对 stdin、stdout 和 stderr 上 shell 管道运算符的影响

对 stdin、stdout 和 stderr 上 shell 管道运算符的影响

当我使用 shell 创建管道时,例如:

ls | cat

我确信的是,stdinforcat将是stdoutfor ls(即所有内容都ls写入它stdoutcat将通过它读取它stdin)。

现在我有两个问题:

  1. for 会stdinlsforstdoutcat
  2. stderrfor Bothls和是否cat受到管道运算符的影响,或者仍然是stderrshell 的继承值?

答案1

从技术上来说,在ls | cat

  • (其 fd 1)的标准输出ls将是管道(或某些系统上带有 ksh93 的套接字对)的写入端。
  • (其 fd 0)的 stdincat将是同一管道的读取端
  • 两个命令将同时运行(在单独的进程中同时启动)
  • stdinls不受影响(问题1)
  • stdoutcat不受影响(问题 1)
  • stderr (fd 2)lscat不受影响(问题 2)。

要让ls的 stderr 也转到管道的写入端(因此cat可以从管道另一端的 stdin 读取它),您可以执行以下操作:

ls 2>&1 | cat

其中表示:“使 fd 2 指向与 fd 1 相同的资源(此处为管道)”

cshtcshzshbash4.0以上版本,还可以这样写:

ls |& cat

在管道是双向的系统上,您可以执行以下操作:

ls <&1 | cat >&0

通过同一管道但以相反的方向将 的标准输出反馈到,但这毫无意义,因为永远cat不会从其标准输入中读取。lsls

在 Linux 上,管道不是双向的,该命令会给出错误。

相关内容