コマンドは{ echo err >&2; echo out >&1; } | :
「err」を印刷できますが、2番目のコマンドは印刷できないのはなぜですか?
コンテナのいくつかのテスト:
- ダーバン:11.5(バッシュ/5.1.4)
- ロッキーLinux:9.0(バッシュ/5.1.8)、
- 中央オペレーティングシステム:1908年7月7日(bash/4.2.46)、
- CentOS: 8.4.2105(bash/4.4.19)。
これはホストCentOS 8.0.1905、Debian 11.4でも発生します。
~# { echo err >&2; echo out >&1; } | :
err
~# { echo out >&1; echo err >&2; } | :
~#
以下を使用しない:
ことが正しいようです。
~# { echo out >&1; echo err >&2; } | sed 's/.*/-&-/'
err
-out-
~#
ただし、他のホストCentOS 7.7.1908(bash / 4.2.46)では、次のように印刷されます。
~# { echo out >&1; echo err >&2; } | :
err
~#
ベストアンサー1
間の違い
{ echo err >&2; echo out >&1; } | :
...そして
{ echo out >&1; echo err >&2; } | :
echo
...2つの呼び出しが行われた順序です。順序は進行方法によって重要です。早く最初のecho
実行が可能です。
パイプの両側は同時に開始され、{ ...; }
標準入力ストリームから読み込まれません。これは、パイプラインが終了するとすぐにすぐに削除されることを意味します。:
:
:
echo out >&1
パイプが解体されると、書き込むパイプバッファはありません。存在しないパイプに書き込もうとすると、echo
パイプの左側がPIPE信号を受けて死にます。
実行前に終了するとecho err >&2
出力はありません。
だから:
パイプの状態は考慮されていないため、常に
err
出力が得られます。{ echo err >&2; echo out >&1; } | :
echo err >&2
err
時には次のような結果が出力されます。{ echo out >&1; echo err >&2; } | :
~によると:
以前に終了した場合でもecho out >&1
実行する機会があります。最初に終了すると、:
左が早期に終了するため、出力はありません。
私の考えでは、ほとんどの人はほとんどのシステムで2番目のパイプの非晶質の動作を経験しません。それにもかかわらず、これを示すオペレーティングシステムとシェルバージョンの組み合わせを見つけることができます。また、単一のシェルセッション内でもFreeBSDの非決定的な動作を複製しましたzsh
(シェルが他の動作よりも1つの動作を好むように見えましたが、最終的に移行を確認するまで10回以上試みる必要がありました)。