对标准输入、标准输出和标准错误的 shell 管道操作符的影响

use*_*761 2 shell pipe file-descriptors

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

ls | cat
Run Code Online (Sandbox Code Playgroud)

我可以肯定的是,stdinforcat将是stdoutfor ls(即所有ls写入它的内容stdoutcat都会通过它的 读取它stdin)。

现在我有两个问题:

  1. 请问stdinlsstdoutcat
  2. stderrforls和for是否cat受管道运算符的影响,还是仍然是stderrshell的继承值?

Sté*_*las 6

从技术上讲,在 ls | cat

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

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

ls 2>&1 | cat
Run Code Online (Sandbox Code Playgroud)

其中说:“使 fd 2 指向与 fd 1 上的资源相同的资源(这里是管道)”

随着cshtcshzshbash4.0或以上,你也可以写:

ls |& cat
Run Code Online (Sandbox Code Playgroud)

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

ls <&1 | cat >&0
Run Code Online (Sandbox Code Playgroud)

以具有cat的标准输出被反馈到ls经由相同的管道,但在相反的方向,但是这将是没有意义的作为ls从未从其标准输入读取。

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