如何将命令输出传递给其他命令?


83

例:

ls | echo什么都不打印(实际上是空白行)。我希望它能打印文件列表。

ls | grep 'foo'另一方面,可以按预期工作(打印名称中带有'foo'的文件)。

在这些情况下,我的工作类似于: ls | while read OUT; do echo $OUT; done但这很麻烦。

为什么管道只能与某些命令一起使用,而不能与其他命令一起使用?如何解决这个问题?


2
您期望ls | echo做什么?为什么不简单地运行ls
theomega's

12
我使用了最简单的示例来说明我的观点。当我尝试制作单行代码以在对象存储库中显示git对象及其类型时,我实际上遇到了此问题。因此,我通过管道将对象ID传送到git cat-file,但是它没有用。显然,回声具有相同的行为,因此我以它为例。
Mihai Rotaru 2010年

还可以查看xargs的-n命令,它表示要在子命令上放置多少个参数。`... | xargs -n1 git cat-file
Rich Homolka 2010年

Answers:


118

命令行参数和标准输入之间是有区别的。管道会将一个过程的标准输出连接到另一个过程的标准输入。所以

ls | echo

将ls的标准输出连接到echo的标准输入。好吧 好吧,echo会忽略标准输入,并将其命令行参数(在本例中为否)转储为其自己的stdout。输出:什么都没有。

在这种情况下,有一些解决方案。一种是使用读取stdin并将其转储到stdout的命令,例如cat。

ls | cat

将“工作”,具体取决于您对工作的定义。

但是一般情况如何。您真正想要的是将一个命令的标准输出转换为另一命令的命令行参数。正如其他人所说的,xargs在这种情况下,它是规范的帮助器工具,它从其stdin读取其命令行参数以获取命令,并构造要运行的命令。

ls | xargs echo

您还可以使用替换命令对此进行一些转换 $()

echo $(ls)

也会做你想要的。

这两个工具都是Shell脚本的核心,您应该两者都学习。

为了完整起见,正如您在问题中所指出的,将stdin转换为命令行args的另一种基本方法是Shell的内置read命令。它将“单词”(由IFS变量定义的单词)转换为临时变量,您可以在任何命令运行中使用它。


1
一个非常有用的答案,谢谢!我目前正在学习bash,之前我已经看过xargs和$(*)表示法,但是并没有对它们进行过多的关注。现在我知道它们的重要性,并且一定会研究它们。
Mihai Rotaru 2010年

1
xargs可能是OP寻找的。
Iktys

19

ls | echo仅打印空白行,因为不echo读取任何输入;管道的最后一条命令实际上echo是只打印空白行。

通常:

a | b

确保的输出a成为的输入b。我建议您阅读的Pipelines部分man bash


如果您真的想使用lsecho一起使用,下面是一些(非常没用的)示例:

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done


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.