PIPESTATUSがコマンド置換時にパイプで機能しない理由

PIPESTATUSがコマンド置換時にパイプで機能しない理由

証明は次のとおりです。Bash 4

Prompt> $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/')
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0

Prompt> echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/'
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0
Output> 0
Output> 123
Output> 0

コマンド置換がフォアグラウンドシェルで実行されるとは見なされませんか?これは私の推測です。

ベストアンサー1

PIPESTATUSコマンド置換はサブシェルで実行されるため、親シェルの変数は変更されません。 ~からコマンド実行環境文書:

コマンドの置換、括弧で囲まれたコマンド、および非同期コマンドは、シェル環境と重複するサブシェル環境で呼び出されます。ただし、シェルによって捕捉されたトラップは、シェルが親シェルから継承した値にリセットされます。祈り。パイプラインの一部として呼び出される組み込みコマンドは、サブシェル環境でも実行されます。サブシェル環境への変更は、シェルの実行環境には影響しません。

PIPESTATUSサブシェルで変数を確認すると、期待される結果が得られます。

$ printf '%s\n' $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/';
for i in ${PIPESTATUS[@]}; do echo $i;done)
0
0
123
0

おすすめ記事