Mat*_*hew 33 command-line pipe
如果您正在帮助某人在命令行上学习管道的概念,您会使用什么示例?实际出现的例子如下:
cat whatever.txt | less
Run Code Online (Sandbox Code Playgroud)
我觉得这不是最好的例子,因为只有一步。什么是好的但基本的用途|?
理想情况下,我将展示的示例将使用具有输出本身的程序,这些输出可以独立运行,然后通过管道一起显示。
rah*_*hmu 35
我将根据现实生活场景向您介绍一个有点复杂的示例。
问题
假设命令conky在我的桌面上停止响应,我想手动杀死它。我对Unix有点了解,所以我知道我需要做的是执行命令kill <PID>。为了检索 PID,我可以使用ps或者top或者我的 Unix 发行版给我的任何工具。但是我怎么能在一个命令中做到这一点呢?
回答
$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill
Run Code Online (Sandbox Code Playgroud)
免责声明:此命令仅适用于某些情况。不要在终端中复制/粘贴它并开始使用它,它可能会毫无戒心地杀死进程。而是学习如何构建它。
这个怎么运作
1- ps aux
此命令将输出正在运行的进程列表以及有关它们的一些信息。有趣的信息是它会在第二列中输出每个进程的 PID。这是我的盒子上命令输出的摘录:
$ ps aux
rahmu 1925 0.0 0.1 129328 6112 ? S 11:55 0:06 tint2
rahmu 1931 0.0 0.3 154992 12108 ? S 11:55 0:00 volumeicon
rahmu 1933 0.1 0.2 134716 9460 ? S 11:55 0:24 parcellite
rahmu 1940 0.0 0.0 30416 3008 ? S 11:55 0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
rahmu 1941 0.0 0.2 160336 8928 ? Ss 11:55 0:00 xfce4-power-manager
rahmu 1943 0.0 0.0 32792 1964 ? S 11:55 0:00 /usr/lib/xfconf/xfconfd
rahmu 1945 0.0 0.0 17584 1292 ? S 11:55 0:00 /usr/lib/gamin/gam_server
rahmu 1946 0.0 0.5 203016 19552 ? S 11:55 0:00 python /usr/bin/system-config-printer-applet
rahmu 1947 0.0 0.3 171840 12872 ? S 11:55 0:00 nm-applet --sm-disable
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:38 conky -q
Run Code Online (Sandbox Code Playgroud)
2- grep conky
我只对一个进程感兴趣,所以我grep用来查找与我的程序相对应的条目conky。
$ ps aux | grep conky
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:39 conky -q
rahmu 3233 0.0 0.0 7592 840 pts/1 S+ 16:55 0:00 grep conky
Run Code Online (Sandbox Code Playgroud)
3- grep -v grep
正如您在第 2 步中看到的,该命令在其列表中ps输出grep conky进程(毕竟它是一个正在运行的进程)。为了过滤它,我可以运行grep -v grep. 该选项-v告诉grep匹配除包含模式的行之外的所有行。
$ ps aux | grep conky | grep -v grep
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:39 conky -q
Run Code Online (Sandbox Code Playgroud)
注意:我很想知道在一次grep调用中完成第 2 步和第 3 步的方法。
4- awk '{print $2}'
现在我已经隔离了我的目标进程。我想检索它的PID。换句话说,我想检索输出的第二个单词。幸运的是,大多数(全部?)现代 unices 将提供某种版本的awk,一种脚本语言,可以对表格数据产生奇迹。我们的任务变得如此简单print $2。
$ ps aux | grep conky | grep -v grep | awk '{print $2}'
1948
Run Code Online (Sandbox Code Playgroud)
5- xargs kill
我有PID。我所需要的只是将它传递给kill. 为此,我将使用xargs.
xargs kill将从输入中读取(在我们的例子中是从管道中读取),形成一个由(是它从输入中读取的任何内容)组成的命令,然后执行创建的命令。在我们的例子中,它将执行. 任务完成。kill <items><items>kill 1948
最后的话
请注意,根据您使用的 unix 版本,某些程序的行为可能略有不同(例如,ps可能会在 $3 列中输出 PID)。如果出现错误或不同之处,请阅读供应商的文档(或更好的man页面)。还要小心,因为长管道可能很危险。不要做任何假设,尤其是在使用kill或 之类的命令时rm。例如,如果有另一个名为“conky”(或“Aconkyous”)的用户,我的命令也可能会终止他所有正在运行的进程!
我的意思是要小心,尤其是对于长管道。像我们在这里所做的那样以交互方式构建它总是更好,而不是做出假设并在以后感到抱歉。
Baa*_*arn 16
我最喜欢的是这个:
youtube-dl $1 -q -o - | ffmpeg -i - $2
从传递的给定 youtube url 下载视频$1并将其输出为$2. 请注意文件是如何安静地-q输出到 STDOUT -o -,通过管道传输到 ffmpeg 并由-i -.
特别是对于 linux 新手,这可能是一个实用的例子,为什么命令行比使用 GUI 工具有用并且使事情变得更容易。我不确定从 youtube 下载视频并将其声音转换为 mp3 需要多长时间。上面的行可以在几秒钟内完成。
一般用途(阅读:我大部分时间使用它的方式)是出于某种原因,我必须通过多种工具运行一些数据以执行不同的处理任务。
所以我会说管道的使用就像胶水一样将几个构建块(不同的 UNIX 工具)组装在一起。像李晶表示,sort并且uniq是一种常见的节。
根据听众的不同,如果您想突出管道的这种用法,例如,您可以这样开头:“嘿,这个教学大纲有几个有趣的 PDF 的链接,其中包含论文和讲义,但其中一些是重复的。我可以吗?以某种方式自动执行此操作?”
然后你可以展示如何lynx --dump --listonly获取链接列表,如何grep过滤以 结尾的链接.pdf,如何colrm或sed可以摆脱lynx每个 URL的数字写入,如何sort以及如何uniq摆脱重复,最后如何wget -i -可以用来检索文件(--wait当然,在服务器上使用温和)。
恐怕这是一个复杂的例子。另一方面,当您只是通过管道并让 shell 一次运行所有管道时,它可能有助于展示管道的强大功能。