如果您帮助某人在命令行上学习管道的概念,您会使用什么示例?实际出现的例子如下:
cat whatever.txt | less
我觉得这不是最好的例子,因为只有一步。什么是好的但基本的用途|
?
理想情况下,我将展示的示例将使用具有输出本身的程序,这些输出可以独立运行,然后通过管道显示在一起。
答案1
我将向您介绍一个基于现实生活场景的稍微复杂的示例。
问题
假设该命令conky
在我的桌面上停止响应,我想手动终止它。我对Unix有一点了解,所以我知道我需要做的是执行命令kill <PID>
。为了检索 PID,我可以使用Unix 发行版提供的任何工具ps
。top
但我怎样才能用一个命令来做到这一点呢?
回答
$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill
免责声明:此命令仅在某些情况下有效。不要将其复制/粘贴到终端中并开始使用它,它可能会毫无戒心地终止进程。而是学习如何构建它。
怎么运行的
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
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
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
注意:我很想知道如何在一次grep
调用中执行步骤 2 和 3。
4-awk '{print $2}'
现在我已经隔离了我的目标进程。我想检索它的 PID。换句话说,我想检索输出的第二个单词。对我来说幸运的是,大多数(全部?)现代 unice 都会提供某种版本的awk
,这是一种可以对表格数据产生奇迹的脚本语言。我们的任务变得如此简单print $2
。
$ ps aux | grep conky | grep -v grep | awk '{print $2}'
1948
5-xargs kill
我有PID。我所需要的只是将它传递给kill
.为此,我将使用xargs
.
xargs kill
将从输入中读取(在我们的例子中是从管道),形成一个命令组成kill <items>
(<items>
是从输入中读取的任何内容),然后执行创建的命令。在我们的例子中它将执行kill 1948
。任务完成。
最后的话
请注意,根据您使用的 UNIX 版本,某些程序的行为可能略有不同(例如,ps
可能在 $3 列中输出 PID)。如果出现错误或不同,请阅读供应商的文档(或者更好的是页面man
)。还要小心,因为长管道可能很危险。不要做出任何假设,尤其是在使用kill
或 之类的命令时rm
。例如,如果有另一个名为“conky”(或“Aconkyous”)的用户,我的命令也可能会杀死他所有正在运行的进程!
我的意思是要小心,尤其是长管道。像我们在这里所做的那样以交互方式构建它总是比做出假设并事后感到遗憾要好。
答案2
我最喜欢的是这个:
youtube-dl $1 -q -o - | ffmpeg -i - $2
从传递的给定 youtube url 下载视频$1
并将其输出为 给定的文件$2
。请注意该文件如何悄悄-q
输出到 STDOUT -o -
、通过管道传输到 ffmpeg 并用作其中的输入-i -
。
特别是对于 Linux 新手来说,这可能是一个实用的例子,说明为什么命令行比使用 GUI 工具有用并且使事情变得更容易。我不确定从 youtube 下载视频并将其声音转换为 mp3 需要多长时间。上面的行可以在几秒钟内完成此操作。
答案3
一般用途(阅读:我大多数时候使用它的方式)是当由于某种原因,我必须通过几种工具运行一些数据以执行不同的处理任务时。
所以我想说这使用管道就像胶水一样将多个构建块(不同的 UNIX 工具)组装在一起。正如乌尔里希所说,sort
anduniq
是一个常见的诗节。
根据受众的不同,如果你想强调管道的这种用法,你可以这样开始:“嘿,这个教学大纲有几个有趣的 PDF 的链接,其中包含论文和讲义,但其中一些是重复的。我可以吗?”以某种方式自动化这个?”
然后,您可以展示如何lynx --dump --listonly
获取链接列表,如何grep
过滤以 结尾的链接.pdf
,如何colrm
或sed
可以删除lynx
写入每个 URL 的数字,如何sort
或uniq
可以删除重复项,以及最后如何wget -i -
用于检索文件(--wait
当然,在服务器上要温和)。
恐怕这是一个复杂的例子。另一方面,当您只需通过管道传输并让 shell 立即运行所有管道时,它可能有助于显示管道的强大功能。
答案4
这是我第一个想到的……
mysqldump
是一个控制台应用程序,它将数据、模式以及可选的过程和函数发送到标准输出。通常它会被重定向到一个文件进行备份。
mysqldump <options> > mydb.dump
这会给你一个未压缩的sql脚本。为了节省空间,您可以使用 bzip2 对其进行压缩。
bzip2 mydb.dump
或者,您可以一步完成这两项操作:
mysqldump <options> | bzip2 > mydb.dump.bz2
在上面的示例中,stdout frommysqldump
通过管道传输到 bzip2,然后 bzip2 的输出重定向到文件。