例:
ls | echo
什么都不打印(实际上是空白行)。我希望它能打印文件列表。
ls | grep 'foo'
另一方面,可以按预期工作(打印名称中带有'foo'的文件)。
在这些情况下,我的工作类似于:
ls | while read OUT; do echo $OUT; done
但这很麻烦。
为什么管道只能与某些命令一起使用,而不能与其他命令一起使用?如何解决这个问题?
git cat-file
,但是它没有用。显然,回声具有相同的行为,因此我以它为例。
例:
ls | echo
什么都不打印(实际上是空白行)。我希望它能打印文件列表。
ls | grep 'foo'
另一方面,可以按预期工作(打印名称中带有'foo'的文件)。
在这些情况下,我的工作类似于:
ls | while read OUT; do echo $OUT; done
但这很麻烦。
为什么管道只能与某些命令一起使用,而不能与其他命令一起使用?如何解决这个问题?
git cat-file
,但是它没有用。显然,回声具有相同的行为,因此我以它为例。
Answers:
命令行参数和标准输入之间是有区别的。管道会将一个过程的标准输出连接到另一个过程的标准输入。所以
ls | echo
将ls的标准输出连接到echo的标准输入。好吧 好吧,echo会忽略标准输入,并将其命令行参数(在本例中为否)转储为其自己的stdout。输出:什么都没有。
在这种情况下,有一些解决方案。一种是使用读取stdin并将其转储到stdout的命令,例如cat。
ls | cat
将“工作”,具体取决于您对工作的定义。
但是一般情况如何。您真正想要的是将一个命令的标准输出转换为另一命令的命令行参数。正如其他人所说的,xargs
在这种情况下,它是规范的帮助器工具,它从其stdin读取其命令行参数以获取命令,并构造要运行的命令。
ls | xargs echo
您还可以使用替换命令对此进行一些转换 $()
echo $(ls)
也会做你想要的。
这两个工具都是Shell脚本的核心,您应该两者都学习。
为了完整起见,正如您在问题中所指出的,将stdin转换为命令行args的另一种基本方法是Shell的内置read
命令。它将“单词”(由IFS
变量定义的单词)转换为临时变量,您可以在任何命令运行中使用它。
如果要执行echo
该ls
命令,请尝试:
ls | xargs echo
这将调用echo
的输出ls
。
ls | xargs -I {} echo {}
如果您希望每个行分别调用它
ls | echo
做什么?为什么不简单地运行ls
?