什么是将命令组合在一起的好例子?


33

如果您正在帮助某人在命令行上学习管道的概念,那么您将使用哪个示例?实际出现的示例如下:

cat whatever.txt | less

我觉得那不是最好的例子,也就是说,因为只有一步之遥。什么是好的,但基本的使用|

理想情况下,我将展示的示例将使用本身具有输出的程序,这些输出可以独立运行,然后通过管道显示在一起。


3
您的示例确实不是很好-它基本上是猫无用使用奖的提名。
maxschlepzig

@maxschlepzig并不是说您错了,但是您也不是很有帮助。您不需要这样做cat,因为less whatever.txt效果很好。
宝拉·M·阿尔珀

Answers:


34

我将根据实际场景向您介绍一个比较复杂的示例。

问题

假设该命令conky在我的桌面上停止响应,而我想手动将其杀死。我知道一点点Unix,所以我知道我需要做的是执行命令kill <PID>。为了获取PID,我可以使用pstop或任何工具,我的Unix发行给了我。但是,如何在一个命令中执行此操作?

回答

$ 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。换句话说,我想检索输出的第二个单词。对我来说幸运的是,大多数(全部?)现代大学将提供的某种版本的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”)的用户,我的命令也可能杀死所有正在运行的进程!

我要说的是要小心,特别是对于长管道。像我们在这里所做的那样,以交互方式构建它总是比做出假设和以后感到遗憾更好。


注意:我很想知道在单个grep调用中执行步骤2和3的方法。-> grep“
conky

3
实际上,这是一个不好的例子,就像您可以做的那样kill $(pgrep conky)
Patrick

5
我知道这已经很晚了,但是您可以进一步简化它pkill conky
苦恼

2
“”“ NB:我很想知道在单个grep调用中执行步骤2和3的方法。”“”“而不是” aux“,请使用” -o pid,comm“-由于它是POSIX,因此它也更可移植兼容。这样,grep进程将显示为“ grep”而不是“ grep conky”,因此它不会与自身匹配。
2013年

2
注意:我很想知道在一个grep电话中执行第2步和第3步的方法。 grep [c]onky是您要寻找的。
AlexT

15

我最喜欢的是这个:

youtube-dl $1 -q -o - | ffmpeg -i - $2

从传递的给定youtube URL下载视频,$1并将其输出为给出的文件$2。请注意,文件是如何安静地-q输出到STDOUT -o -,通过管道传输到ffmpeg并由用作输入的-i -

特别是对于linux新手,这可能是一个实用的示例,为什么使用命令行比使用GUI工具更加有用并使事情变得更容易。我不确定从youtube下载视频并将其声音转换为mp3需要多长时间。上面的代码行可以在几秒钟内完成。


3
youtube-dl具有仅保存音频的选项。我通常的命令是这样,其中URL出现在stdin:上youtube-dl --extract-audio --audio-format mp3 -a -。仍然是一个很酷的例子,但是有更简单的方法可以做到这一点。(内部调用ffmpeg。)
Brigand

3
@FakeRainBrigand:哈哈,很高兴知道!但是我有一个不应该内置的替代方法:youtube-dl $1 -q -o - | mplayer -直接在mplayer中播放视频。我从笔记本电脑使用该命令告诉服务器(连接到电视)播放视频。我必须附加-display :0.0 -geometry 400x300+1200+200以使mplayer窗口出现在正确的屏幕上。
巴恩2012年

9

一般用途(阅读:我大多数时候的使用方式)是出于某种原因,当我不得不通过几种工具运行一些数据以执行不同的处理任务时。

所以我想说管道使用是将几个构件(不同的UNIX工具)组装在一起的胶水。就像乌尔里希所说,sort并且uniq是一个普通的节。

根据听众的不同,如果要突出显示管道的这种用法,可以例如从以下内容开始:“嘿,本课程提纲包含了一些有趣的PDF的链接,其中包含论文和讲义,但是其中一些是重复的。以某种方式使它自动化?”

然后,您将展示如何lynx --dump --listonly获取链接列表,如何grep过滤以结尾的链接.pdf,如何colrmsed可以消除lynx写入每个URL 的数字,如何sort以及uniq可以消除重复项,最后如何wget -i -用于检索链接。文件(--wait当然,在服务器上使用时比较温和)。

恐怕这是一个复杂的例子。另一方面,当您仅通过管道传输并使外壳一次运行所有管道时,它可能有助于显示管道的功能。


2
您也可以sort -uGNU coreutils中使用。
Teresa e Junior

2

我并不完全了解良好,但是管道传递grep必须是最常见的用途之一,可能紧随其后wc -l。(是的,grep具有鲜为人知的-c开关。)

另一个常见的节是| sort | uniq,如果仅仅是因为uniq要求对其输入进行排序。


大多数人都喜欢(... | sort -u如果有)!

2

在此示例中,并不是您需要它,而是:

$ ps aux | grep -v grep | grep conky

...颠倒毛刺的顺序可以保留着色,但效率要低得多。大概在大名单上,颜色并不重要。

另外,该网页还建议:

https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep

> Johnsyweb在2012年2月21日晚上10:31回答
>通常的技巧是这样的:
> ps aux | grep'[t] erminal'
>这将匹配包含终端的行,而grep'[t] erminal'则不行!
>它也可以在许多Unix版本上使用。

...但是如果您要寻找一个字母(例如流程“ X”),则无法使用。


2

我终于可以分享我大约一年半前制作的oneliner的烂摊子了...

while read in; do host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'

它...

  1. 读取sites.txt
  2. 在每个主机上运行“主机”(事后看来,“ dig + short”操作会使此操作变得更容易)
  3. 删除包含“ GOOGLE”的行-这些是mx记录
  4. 获取具有两个IP之一的行
  5. 从列表中的每个站点获取http状态代码
  6. 删除返回4xx或5xx的网站
  7. 从返回该值的网站中删除“ 200”
  8. 用“ http”替换“ HTTP”-纯粹是美观的,没有真正的理由。

我敢打赌,用一个Python脚本可以做到更好。


呃...我不确定这是否是向新手解释管道的最干净,最简单的示例;)
Erathiel 2015年

2
我的问题是,它的目的是什么?
ADTC

我有一个充满域的文件,我需要查看它们是否在我的两台服务器之一(不幸的是,我“继承”了)。这将读取文件,执行“主机”并清除该输出,然后仅执行一个请求以查看其是否返回4xx或5xx错误。如果这样做,它将丢弃该域;如果没有,它将输出它们,然后将其放在另一个文件中。
鞣工

1

这是我想到的第一件事...

mysqldump是一个控制台应用程序,用于将数据,架构以及可选的过程和功能发送到stdout。通常,它会重定向到文件进行备份。

mysqldump <options> > mydb.dump

那会给你一个未压缩的SQL脚本。为了节省空间,您可以使用bzip2对其进行压缩。

bzip2 mydb.dump

另外,您也可以一步一步完成两项操作:

mysqldump <options> | bzip2 > mydb.dump.bz2

在上面的示例中,来自的标准输出通过mysqldump管道传递到bzip2,然后将其输出重定向到文件。


1
也添加相反的操作:bzcat mydb.dump.bz2 | mysql <options>
manatwork'2

1

这是我在一个命令中使用多个管道的示例。这使用gawk搜索MySQL通用查询日志($ OFILE)并查找所有拒绝的登录信息。然后,它按名称对列表进行排序,将该列表通过管道传递给uniq,该uniq对出现的次数进行计数,然后通过管道对其进行最后一次排序,以对所计数的列表进行数字排序...

gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n

1

管道与过滤器和翻译器配合使用效果最佳

find /usr/bin/ |                #produce 
sed 's:.*/::'  |                #translate: strip directory part
grep -i '^z'   |                #filter   : select items starting with z
xargs -d '\n' aFinalConsumer    #consume  

这样,数据可以从一个程序流到下一个缓冲区,并且所有数据都不必立即存储在内存中。


0

cat filename | less 管道的使用非常糟糕,因为您只能 less filename

这是我每天使用的点子的示例(但也可能是一个不好的示例): ls -la | more -c

斯科特·霍夫曼和njsg的答案是更好的例子。



0

在想要对文件夹大小进行排序分析的任何目录中执行此命令(然后使用END键向下滚动):

du -m| sort -n| less

Sortiert nachOrdnergrösse


0

这是当xauth不是选项时我用来设置DISPLAY变量的示例...

export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"

第一个命令获取所需的数据,即主机名或IP。第二个命令仅获取该数据(最后一个字段)。最后,最后一条命令从数据中删除括号。


0

您可以在任何可以将第一个命令的输出作为下一个输入的地方使用命令管道。

例子。

  1. 使用文本文件,您可以将文本文件传递给grep以查找特定的文本行。然后,您可以将输出传递给sed或awk来修改或打印行的某些部分。

猫示例txt | grep {some_line} | awk {some_command}

  1. 使用流程,您可以使用管道发送命令以终止流程。

它只是一个简单的概念,即如果您感觉到您运行的命令输出可以被另一个命令输入,则可以通过管道传递它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.