了解如何将输入发送到Bash中的管道


17

我不太了解管道如何在bash中工作。

我知道它将一条命令的输出作为另一条命令的输入。

我可以得到什么输出,因为这是命令打印到屏幕上的内容。

但是我怎么知道命令将要输入什么呢?

这是我认为可行的示例:

which gem | rm

不幸的是没有。

哪种宝石可以打印出来,/usr/bin/gem所以必须正确输出?

我以为那是给rm的了,rm /usr/bin/gem但是我错了。

所以我的问题是,我怎么知道命令需要什么输入?


2
除其他外,这rm /usr/bin/gem是一个可怕的想法。离开这个gem(和Ruby解释它去用)单独安装您首选的Ruby解释器(和gem使用)rvmrvm.beginrescueend.com
泰勒马格斯

Answers:


23

“输入”和“命令行参数”是不同的东西。

rm 删除作为参数提供的文件。

管道将左手命令的输出重定向到右手命令的输入。它不会影响右侧程序的命令行参数。

要执行您要执行的操作,请尝试使用xargs将标准输入转换为用于执行程序的命令行参数。那是它的工作。

which gem | xargs rm,例如,将删除gem您的PATH中的。


12

rm不接受输入,接受参数。这些是不同的。参数是您在命令行上赋予程序以影响其行为的开关和文件名等。输入是程序处理的数据。例如,同时grep接受输入和参数:

grep "foo" file.txt

有两个参数有"foo"file.txt。该输入内容file.txt,不是字符串file.txt本身。由于grep接受输入,因此可以将其与管道一起使用:

cat file.txt | grep "foo"

产生相同的输出,因为猫正在file.txt作为参数,并产生内容file.txt作为输出。然后,将该输出通过管道传递到grep,与第一个示例中的效果相同,与grep打开文件本身相同。

如果要将一个程序的输出用作另一个程序的参数,请使用反引号:

rm `which gem`

或以下替代(特定于bash的)语法:

rm $(which gem)

编辑:或xargs作为另一个答复者指出。使用命令行为猫皮化的方法很多。


值得注意的是,它的cat file.txt | grep "foo"速度可能比慢数百倍grep "foo" file.txt
Borealid 2010年

1
这是我不明白的部分。我怎么知道什么是参数,什么是标准输入?
ajsie 2010年

8
@ajsie:如果您在程序名称之后和按Enter键之前键入它,则它是一个参数。如果在程序开始运行后将其键入程序,则为标准输入。
Borealid

1
得到它了!这说明了一切。现在我知道我既可以直接使用命令,也可以查看是否提示我(grep),也可以阅读手册(man grep)来查看它是否使用std输入。
ajsie

@ajsie:如果您不想深入研究联机帮助页,还grep --help可以快速了解接受的参数。
Borealid 2010年

3

请查看man您感兴趣的命令页面。这些程序将指示它们从中读取stdin(尝试man grep使用读取stdin的流行命令)。


我尝试man grep | grep 'standard input'If no file arguments are specified, the standard input is used.最后一场比赛。👍我不得不grep稍微品尝一下自己的药。😎
ma11hew28

2

如果您的PATH中有一个包含空格的目录,或者如果命令名包含空格,那么运行这些命令将很危险:

rm `which gem`       # Dangerous
rm $(which gem)      # Dangerous
which gem | xargs rm # Dangerous

GNU Parallel http:// www.gnu.org/software/parallel/不会出现此问题,因此即使您的PATH目录中包含空格或命令名称包含空格,这也可以解决:

which gem | parallel rm
parallel -a <(which bass) rm

观看GNU Parallel的介绍性视频:http : //www.youtube.com/watch?v=OpaiGYxkSuQ

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.