管道无法与echo命令配合使用

133
当我运行以下的 Bash 脚本时,我期望它会输出 Hello。但事实上,它只会输出空白行并退出。
echo 'Hello' | echo

为什么从echo输出到echopiping不起作用?


4
你似乎期望第二个“echo”的行为像“cat”一样。 - Keith Thompson
1
回显 $(回显'你好') - pr-pal
4个回答

148

echo命令打印其所有参数,不会从stdin读取信息。因此,第二个echo会打印其所有参数(没有),然后退出,忽略stdin上的Hello

如果要编写一个程序来读取stdin并将其输出到stdout,请使用cat命令:

$ echo Hello | cat
Hello

22
或者 $ echo Hello | xargs echo 默认情况下等同于 echo Hello | xargs - daGo
编辑不合理或与主题无关。 - konsolebox

37

在这种情况下,您使用的管道更正确地被称为匿名管道,因为它们没有名称(还有命名管道)。匿名管道只能在相关进程之间工作,例如具有相同父级的进程。

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

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

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

因此:

echo 'Hello' | echo

echo的标准输出传递给echo的标准输入。但是echo不会读取stdin!所以什么都不会发生。

筛选程序处理在命令行上指定的文件名。如果没有指定文件名,则它们会读取stdin。示例包括catgrepsed,但不包括echo。例如:

echo 'Hello' | cat

将显示“Hello”,而cat是无用的(通常情况下是这样)。

echo 'Hello' | cat file1

echo的输出忽略,仅显示file1文件的内容。请记住,只有在没有给出文件名时才会读取标准输入。

你认为这会显示什么?

echo 'Hello' | cat < file1 file2

为什么?

最后,第三个流2称为标准错误,或者stderr,它是未缓冲的。 它被管道忽略,因为它们只在stdin和stdout之间操作。 但是,您可以重定向stderr以使用stdout(请参见 man dup2 ):

myprog 2>&1 | anotherprog

2>&1的意思是“将文件描述符 2 重定向到与文件描述符 1 相同的位置”。

尽管如此,程序可以覆盖所有这些行为。例如,它可以从文件描述符 2 中读取。我省略了很多其他详细信息,包括其他形式的重定向,如进程替换Here 文档


11

管道只能用于以stdin作为输入的命令。但是echo不从stdin中获取输入。它将从参数获取输入并输出。因此,这种方法行不通。要使用echo,可以尝试如下方法:echo $(echo 'hello')


5

这是因为echo(包括内置的和/bin/echo)不从stdin读取任何内容。

可以使用cat代替:

echo 'Hello' | cat
Hello

或者不使用管道符:

cat <<< 'Hello'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接