最近,我一直在尝试该ps
命令,有时很长的路径会换行到下一行(或两行)并使其难以阅读。我想将ps
输出通过管道传输到另一个程序中,以将输出限制为x
字符数。
这是我到目前为止所做的,但效果不太好:
ps aux | cut -c1-$(stty size | cut -d' ' -f2)
$(stty size | cut -d' ' -f2)
计算结果为 167,但似乎不是 的有效输入cut
。
有没有办法让这种类型的语法在 bash 中工作?
答案1
有些 shellzsh
会bash
自动将变量mksh
设置$COLUMNS
为终端的宽度,因此您无需stty
在此处调用。
我尝试的所有实现ps
都支持非标准(BSD 类型)语法自行查询终端宽度。我很惊讶你的没有。我希望它会看看的内容COLUMNS
环境虽然有变数。
所以你可以这样做:
export COLUMNS; ps aux
如果不,
ps aux | cut -c"1-$COLUMNS"
您还可以告诉您的终端不要换行:
tput rmam
ps aux
答案2
以下作品:
ps aux | cut -c1-$(stty size </dev/tty | cut -d' ' -f2)
这也有效:
v=$(stty size | cut -d' ' -f2) ; ps aux | cut -c1-$v
问题似乎是stty
需要在其标准输入上有 tty 才能正常工作。以上两种方法就可以解决这个问题。
还有另一种选择。虽然stty
的 stdin 和 stdout 在上述命令中都被重定向,但它的 stderr 却没有:它仍然指向终端。奇怪的是,stty
如果将 stderr 作为输入,它也会起作用:
ps aux | cut -c1-$(stty size <&2 | cut -d' ' -f2)
答案3
您还可以ps
更好地处理输出。
ps --width ${n:-$COLUMNS} ${opts} #set ps terminal width
ps -ww ${opts} #no word wrap
ps -o ${only_interesting_output} ${opts} #trim output
这将告诉您ps
根据需要将其输出解析为您的规范。
当然,如果您不自动换行,那么您就会遇到丢失信息的问题。您真的需要所有流程都使用它吗?如果是这样,请在寻呼机中打开它:
ps ww ${opts} | $PAGER
如果没有,请指定您希望看到的内容:
ps -o args= -p $pid
或者,您可以明确告知ps
您的终端--width
:
man ps
...
w
宽输出。使用此选项两次可获得无限宽度。
-w
宽输出。使用此选项两次可获得无限宽度。
--width n
设置屏幕宽度。
该--width
产品完全符合您要求的规格,无需涉及任何额外的过滤器或辅助流程(这可能只会让你的-aux
输出更加混乱)。正如$COLUMNS
上面所示和 Stephane 指出的那样,它甚至可以动态工作。
不过,可能值得注意的是,我发现人们经常尝试添加这些不必要的过滤器,以便他们可以|pipe
适应其他过滤器来解析输出,这也很可能是不必要的。当然,通过人们我主要是指我。
我上面提到的输出操作数-o
允许您过滤ps
显示哪些列,当您添加分配时,=
您甚至可以根据需要命名该列。我将分配留空并交给它一个目标-p
进程$pid
,因此唯一的输出ps
是$pid
命令名称及其args
调用时的名称。并且仅仅触及了如何定义将显示或不显示的-o
内容的表面。ps
这是我建议您采取的方向,特别是通过:
man ps
...
使用 BSD 语法查看系统上的每个进程:
ps ax
ps axu
打印进程树:
ps -ejH
ps axjf
要获取有关线程的信息:
ps -eLf
ps axms
要获取安全信息:
ps -eo euser,ruser,suser,fuser,f,comm,label
ps axZ
ps -eM
要以用户格式查看以 root 身份运行的每个进程(真实有效 ID):
ps -U root -u root u
要使用用户定义的格式查看每个进程:
ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
ps -Ao pid,tt,user,fname,tmout,f,wchan
仅打印 syslogd 的进程 ID:
ps -C syslogd -o pid=
仅打印 PID 42 的名称:
ps -p 42 -o comm=