管道无法使用 echo 命令

当我运行以下 Bash脚本时,我希望它打印 Hello。相反,它打印一个空行并退出。

echo 'Hello' | echo

Why doesn't piping output from echo to echo work?

137298 次浏览

echo打印它的所有参数。它不从 stdin读取。因此,第二个 echo打印它的所有参数(无)并退出,忽略 stdin上的 Hello

对于读取其 stdin并将其打印到 stdout的程序,请使用 cat:

$ echo Hello | cat
Hello

这是因为 echo(内建和 /bin/echo)不从 stdin读取任何东西。

改为使用 cat:

echo 'Hello' | cat
Hello

Or without pipes:

cat <<< 'Hello'

管道只能用于从 stdin 获取输入的命令。但是 Echo 不从 stdin 那里拿钱。它将从参数中获取输入并打印出来。所以这行不通。为了回声,你可以做一些像 echo $(echo 'hello')

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

Pipes are part of the IO system resulting from the C runtime-library. These 溪流 are buffered (there is an exception) by default. Basically a pipe is just connecting the output buffer from one process to the input buffer of another.

使用的前三个流(称为 文件描述符)分别编号为0、1和2。第一个0被称为 standard inputstdin(C 中使用的名称)。默认情况下,这是连接到键盘,但它可以重定向使用的 <符号或程序名称是在一个管道的右侧。

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

所以:

echo 'Hello' | echo

echo获取标准输出,并将其传递给 echo的标准输入。但是 echo不读 stdin!所以什么都没发生。

筛选程序 处理命令行上指定的文件名。如果没有给出文件名,那么它们将读取 stdin。例子包括 catgrepsed,但是 没有 echo。例如:

echo 'Hello' | cat

将显示“ Hello”,而 cat是无用的(通常如此)。

echo 'Hello' | cat file1

忽略echo输出,并只显示 file1的内容。请记住,只有在没有给出文件名的情况下才读取 stdin。

What do you think this displays?

echo 'Hello' | cat < file1 file2

and why?

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

myprog 2>&1 | anotherprog

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

以上是正常行为,然而程序可以覆盖所有这些如果它想要的。例如,它可以从文件描述符2读取。我省略了许多其他细节,包括其他形式的重定向,如 工序替代工序替代这里的文件