将两个命令合并为一个命令

将两个命令合并为一个命令

我怎样才能结合这两个命令ps aux | head -n1 ; ps aux | grep vlc合并成一个命令?我尝试使用tee命令 ( ps aux | tee >(head -n1) >(grep vlc)),但是没有用!

答案1

因此,您尝试保留 PS 命令的头部(以便您可以看到标题)但只显示vlc命令。

我个人会awk根据两个条件(行号和 VLC)使用和过滤。如果其中一个条件为真,我们将输出以下行:

$ ps aux | awk 'NR==1 || $11~/vlc/'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
oli       4833  0.6  0.2 795220 62952 ?        Sl   15:37   0:00 /usr/bin/vlc

它还有一个额外的优势,就是您只需运行ps一次。而且由于字段 11 是主命令(而不是其任何参数),我们也不会捕获awk正在运行的命令。我们只会获得 VLC 和列标题。


在侧边栏上,类似这样的应该工作...但是不...

ps aux | tee >(head -1 >&2) | grep vlc

你已经接近了,你需要通过管道传输到最后一个命令,否则tee会溢出到 STDOUT,如果你先输出到 STDOUT,然后再通过管道传输,很有可能它会被后者捕获grep。在上面我将标题输出到 STDERR (2) 以停止grep干扰它。有点不合时宜,但没关系。

但是,是的,这仍然不起作用. 原因是head关闭 STDOUT,它会过滤tee并阻止grep。这是设计使然,因此head不会处理超出需要的输入。您可以使用 模拟它正在做的事情awk

$ ps aux | tee >(awk 'NR==1 {print;exit}' >&2) | grep "grep"
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

这相当于head -1。它找到第一行然后退出。这会关闭输入缓冲区并tee退出。

这是一个在找到第一行后不会退出的版本awk。它会继续运行(不管是好事还是坏事)每一行:

$ ps aux | tee >(awk 'NR==1' >&2) | grep "grep"
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
oli      15103  0.0  0.0  11752  2236 pts/18   S+   11:32   0:00 grep --color=auto grep

另一种方法是将输入发送到sponge。 Sponge 会吸收整个输入流,然后再将其写入文件(或重定向)。 这样可以阻止 head 终止父流,但这确实意味着输入将被反转(将grep首先输出),因此我们也将其推送到sponge实例中:

$ ps aux | tee >(sponge >(head -1 >&2)) | sponge >(grep "grep")
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
oli      14875  0.0  0.0  11752  2192 pts/18   S    11:19   0:00 grep --color=auto grep

但是虽然后两个方法都有效,而且你只生成ps aux一次输出,他们仍然面临严重问题awk|grep正在处理所有事情两次,而spongeorgy 正在缓冲所有事情两次。

总结:如果您可以像使用一样用一个命令处理所有内容awk,那为什么不呢?

答案2

您可以告诉仅使用ps打印进程 ID 。vlc-C

man ps

   -C cmdlist
          Select by command name.  This selects the processes whose
          executable name is given in cmdlist.

例子:

$ ps u -C vlc
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
sylvain  12586  0.1  0.3 1076848 60908 ?       Sl   20:10   0:00 /usr/bin/vlc

答案3

使用bash过程替换和cat

cat <(ps aux | head -1) <(ps aux | grep '[v]lc')

进程替换模式<()将其内部命令的输出替换为文件。cat将像往常一样简单地连接文件。

例子 :

$ cat <(ps aux | head -1) <(ps aux | grep '[v]lc')
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
chayan   26031  2.3  0.4 1098532 38556 pts/31  Sl   20:45   0:00 vlc

答案4

只需告诉ps仅显示输出vlc

$ ps -P $(pgrep vlc)
PID PSR TTY      STAT   TIME COMMAND
6728   2 pts/0    Sl     0:00 vlc

pgrep列出名称与给定模式匹配的任何进程的 PID。ps 的-P开关允许您仅列出特定 PID 的信息。将两者结合起来,您将获得标题ps和您关心的行。

相关内容