当我运行以下Hello
脚本时,我希望它能打印echo 'Hello' | echo
。相反,它会打印一个空行并退出。
piping
echo
echo
的{{1}}输出为何不起作用?
答案 0 :(得分:48)
echo
打印其所有参数。它不会从stdin
读取。所以第二个echo
打印所有参数(无)并退出,忽略Hello
上的stdin
。
对于读取其stdin
并将其打印到stdout
的程序,请使用cat
:
$ echo Hello | cat
Hello
答案 1 :(得分:16)
你似乎不懂管道。在这种情况下,它们更准确地称为匿名管道,因为它们没有名称(还有命名管道)。匿名管道仅在相关进程之间工作,例如具有相同父进程的进程。
管道是由C运行时库产生的IO系统的一部分。默认情况下,这些流是缓冲的(有一个例外)。基本上,管道只是将输出缓冲区从一个进程连接到另一个进程的输入缓冲区。
使用的前三个流(称为文件描述符)编号为0,1和2.第一个,0,称为标准输入,或{{ 1}}(C中使用的名称)。默认情况下,它连接到键盘,但可以使用stdin
符号或管道右侧的程序名称重定向。
第二个1称为标准输出或<
。默认情况下,它连接到终端屏幕,但可以使用stdout
符号或管道左侧的程序名称重定向。
所以:
>
从echo 'Hello' | echo
获取标准输出并将其传递给echo
的标准输入。但echo
没有读取标准输入!没有任何反应。
过滤程序处理命令行中指定的文件名。如果没有给出文件名,那么他们会读取标准输入。示例包括echo
,cat
和grep
,但不 sed
。例如:
echo
将显示“Hello”,echo 'Hello' | cat
无效(通常是)。
cat
忽略 echo 'Hello' | cat file1
的输出,只显示file1的内容。请记住,只有在没有给出文件名的情况下才会读取stdin。
您认为这会显示什么?
echo
为什么?
最后,第三个流2称为标准错误或echo 'Hello' | cat < file1 file2
,而且这个 unbuffered 。它被管道忽略,因为它们只在stdin和stdout之间运行。但是,您可以重定向stderr以使用stdout(请参阅stderr
):
man dup2
myprog 2>&1 | anotherprog
表示“将文件描述符2重定向到与fie描述符1相同的位置”。
以上是正常行为,但程序可以覆盖所有这些,如果它想要的话。例如,它可以从文件描述符2中读取。我省略了很多其他细节,包括其他形式的重定向,例如进程替换和 here documents 。
答案 2 :(得分:5)
管道只能用于从stdin获取输入的命令。但回声不是来自stdin。它将从参数中获取输入并打印出来。所以这不会奏效。为了回应你可以做echo $(echo 'hello')
答案 3 :(得分:2)
这是因为echo
(内置和/bin/echo
)都没有从stdin
读取任何内容。
改为使用cat
:
echo 'Hello' | cat
Hello
或没有管道:
cat <<< 'Hello'