web-dev-qa-db-ja.com

stdin、stdout、およびstderrに対するシェルパイプ演算子への影響

シェルを使用してパイプを作成すると、たとえば次のようになります。

ls | cat

私が確かに知っているのは、stdincatstdoutlsになるということです(つまり、lsstdoutに書き込むすべてのものは、catstdinを介して読み取ります)。

今私は2つの質問があります:

  1. stdinlsstdoutcatになりますか?
  2. stderrlsの両方のcatは、パイプ演算子の影響を受けますか、それともシェルの継承されたstderr値のままですか?
2
user8240761

技術的には、ls | cat

  • ls(そのfd 1)の標準出力は、パイプ(または一部のシステムではksh93とのソケットペア)の書き込み終了になります。
  • cat(そのfd 0)のstdinは、同じパイプの読み取り終了になります
  • 両方のコマンドが同時に実行されます(別々のプロセスで同時に開始されます)
  • lsのstdinは影響を受けません(質問1)
  • catのstdoutは影響を受けません(質問1)
  • lsまたはcatのstderr(fd 2)は影響を受けません(質問2)。

lsのstderrもパイプの書き込み側に移動するようにするには(つまり、catはパイプの反対側のstdinから読み取ることができます)、次のようにします。

ls 2>&1 | cat

つまり、「fd2がfd1と同じリソース(ここではパイプ)を指すようにします」

cshtcshzsh、またはbash 4.0以降では、次のように書くこともできます。

ls |& cat

パイプが双方向であるシステムでは、次のことができます。

ls <&1 | cat >&0

catのstdoutを同じパイプを介して逆方向にlsにフィードバックする必要がありますが、lsがstdinから読み取ることはないため、これは無意味です。

パイプが双方向ではないLinuxでは、そのコマンドはエラーを出します。

6