2016-01-31 57 views
16

工作当我运行以下Bash剧本,我希望它打印Hello。相反,它会打印一个空白行并退出。管道无法与echo命令

echo 'Hello' | echo 

为什么不piping输出echoecho工作?

+2

您似乎期待第二个'echo'的行为像'猫'。 –

回答

25

echo打印它的所有参数。它不从stdin读取。因此,第二个echo打印它的所有参数(无),然后退出,无视stdinHello

一个程序,读取其stdin,并打印到stdout,使用cat

$ echo Hello | cat 
Hello 
+1

或'$回声你好| xargs echo'相当于'echo Hello | xargs'默认。 – daGo

2

这是因为echo(包括内置和/bin/echo)不读stdin什么。

使用cat代替:

echo 'Hello' | cat 
Hello 

或者没有管:

cat <<< 'Hello' 
3

管道只能做采取输入从标准输入命令。但回声不会从标准输入。它会从参数中得到输入并打印出来。所以这不会工作。序呼应,你可以这样做echo $(echo 'hello')

8

你似乎并不明白管道。在这种情况下,它们更准确地称为匿名管道,因为他们没有名字(也有命名管道)。匿名管道只能在相关进程之间运行,例如具有相同父进程的进程。

管道是由C运行时库产生的IO系统的一部分。这些被默认缓冲(有一个例外)。基本上,管道只是将一个进程的输出缓冲区连接到另一个进程的输入缓冲区。

使用的第一三个流(称为文件描述符)编号为0,1和2。第一,0,被称为标准输入,或stdin(在C中使用的名称)。默认情况下,它连接到键盘,但可以使用<符号或位于管道右侧的程序名重定向。

第二个1被称为标准输出stdout。默认情况下,它连接到终端屏幕,但可以使用>符号或位于管道左侧的程序名称重定向。

所以:

echo 'Hello' | echo 

需要从echo标准输出并将其传递到的echo标准输入。但echo不读取标准输入!所以没有任何反应

过滤程序过程在命令行中指定的文件名。如果没有给出文件名,那么他们读取标准输入。例子包括catgrep,并sed,但echo。例如:

echo 'Hello' | cat 

将显示 '你好',并且cat是无用的(它经常是)。

echo 'Hello' | cat file1 

echo忽略输出和只显示文件1的内容。请记住,如果没有文件名是因为标准输入是只读的。

你怎么看这个显示器?

echo 'Hello' | cat < file1 file2 

为什么?

最后,第三个流,如图2所示,被称为标准误差,或stderr,而这一次是无缓冲。它是由管道忽略,因为它们只stdin和stdout之间操作。但是,您可以重定向错误输出到标准输出使用(见man dup2):

myprog 2>&1 | anotherprog 

2>&1意味着“重定向文件描述符2到同一个地方FIE描述1”。

上面是正常的行为,但是如果程序可以覆盖所有需要的行为,例如,它可以从文件描述符2中读取。我省略了很多其他的细节,包括其他形式的重定向,如进程替换这里的文件