我已经使用了以下命令一段时间来保持标题ps
输出。
ps aux | { head -1; grep root; }
输出结果如下所示。
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 142 0.0 0.0 1234567 2520 ?? Ss 3:14AM 0:08.03 /usr/sbin/notifyd
root 55 0.0 0.0 7890123 2460 ?? Ss 3:14AM 0:01.94 /usr/sbin/syslogd
...
但是,当与其他命令行程序一起使用时,输出不是预期的。
采用以下df
示例。
df -h
输出以下内容。
Filesystem Size Used Avail Use% Mounted on
/dev/disk1s1 466G 103G 362G 22% /
/dev/disk1s4 466G 1.1G 362G 1% /blah/blah/blah
使用与上述示例类似的语法df
ps
。
df -h | { head -1; grep disk1; }
输出以下内容。
Filesystem Size Used Avail Use% Mounted on
期望输出看起来与直接df -h
命令基本相同。
为什么这与ps
不同?
我觉得了解这些差异将有助于我更完整地理解BASH处理。
谢谢!
答案 0 :(得分:5)
这是因为head
正在缓冲其输入。它从管道读入一个大缓冲区,然后开始从该缓冲区中提取行。在读取并打印了前N行之后,它就会退出。然后grep
开始从管道读取。但是head
已经读入其缓冲区的任何内容都不可用。
它似乎与ps
一起使用的原因是因为它产生了大量输出,这不适合这个缓冲区。然后grep
能够处理输出的其余部分。但我认为如果仔细检查,你会发现结果不完整。
df
的输出要小得多,它都适合head
使用的缓冲区,因此grep
无需处理任何内容。
缓冲区大小可能类似于4K字符。
您可以使用awk
执行所需操作:
df -h | awk 'NR == 1 || /disk1/'
ps aux | awk 'NR == 1 || /root/'
NR
是行号,因此如果它是第一行或与正则表达式匹配,则打印该行。
答案 1 :(得分:-1)
在这种情况下,Sed(1)也可用于过滤输出:
ps aux | sed -n '1p; /root/p'
-n
:在对所有命令应用之后,不要将输入行回显到标准输出。
1p
; "地址" line1,with' p'打印图案空间
/root/p;
"地址" of / regexp / matching" root",with' p'打印图案空间
替代:
ps aux | sed '1p; /root/p; d;'
某些系统可能需要ps -aux
i.t.短划线( - )到前缀选项。 Linux和* BSD系统没有(不能确定macOS的行为方式,我没有这样的系统可以检查)。