【问题标题】:Piping not working with echo command [duplicate]管道不适用于 echo 命令 [重复]
【发布时间】:2016-05-09 02:06:13
【问题描述】:

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

echo 'Hello' | echo

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

【问题讨论】:

  • 你似乎期待第二个 echo 表现得像 cat
  • echo $(echo 'Hello')

标签: bash echo


【解决方案1】:

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

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

$ echo Hello | cat
Hello

【讨论】:

  • $ echo Hello | xargs echo,默认等价于echo Hello | xargs
  • 编辑没有意义或不适用于主题。
【解决方案2】:

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

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

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

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

所以:

echo 'Hello' | echo

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

过滤程序处理命令行中指定的文件名。如果没有给出文件名,那么它们读取标准输入。示例包括 catgrepsed,但不是 echo。例如:

echo 'Hello' | cat

会显示“Hello”,cat 没用(通常是这样)。

echo 'Hello' | cat file1

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

你认为这显示了什么?

echo 'Hello' | cat < file1 file2

为什么?

最后,第三个流 2 被称为标准错误,或stderr,而这个是无缓冲。它被管道忽略,因为它们只在标准输入和标准输出之间运行。但是,您可以重定向 stderr 以使用 stdout(请参阅 man dup2):

myprog 2>&1 | anotherprog

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

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

【讨论】:

    【解决方案3】:

    管道只能用于从标准输入获取输入的命令。但 echo 不取自标准输入。它将从参数中获取输入并打印它。所以这行不通。为了回应你可以做类似echo $(echo 'hello')

    【讨论】:

      【解决方案4】:

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

      改用cat

      echo 'Hello' | cat
      Hello
      

      或者没有管道:

      cat <<< 'Hello'
      

      【讨论】:

        猜你喜欢
        • 2018-07-03
        • 2023-03-22
        • 1970-01-01
        • 2016-01-31
        • 2019-09-10
        • 1970-01-01
        • 1970-01-01
        • 2021-09-08
        • 2023-03-15
        相关资源
        最近更新 更多