エクスポートが他のコマンドにパイプするときに変数を設定しない

エクスポートが他のコマンドにパイプするときに変数を設定しない

エクスポートを別のコマンドにパイプすると (bash 3.2 を使用)、変数は変更されません。

export USER=new | cat ; env | grep USER

出力:USER=old

User 変数は変更されず、同じままです。ただし、エクスポートは正常に終了しました: export USER=new | echo $?0 を出力します。

答え1

通常、パイプラインの各部分 (一部のシェルの最後の部分を除く) はサブシェルで実行されます。つまり、シェルは各部分に対して自身のコピーをフォークし、各コピーがその部分のコマンドを処理して、外部コマンド (catその部分など) を実行します。次のコマンド (他のパイプライン) を続行するメイン シェルは、変更された値を認識しません。

var(そして、いずれにしても、のようなコマンドを実行した後の の値はどうなると予想されますかvar=foo | var=bar?)

これは通常、パイプラインの最後の部分に変数の割り当てがある場合に発生します。

n=0
some command | while read line; do n=$((n+1)); done

nこれは多くのシェルでは に設定されています0が、すべてのシェルでそうではありません。kshとzshはメインシェルで最後の部分を実行し、Bashにはそのためのオプションがあります。これについては、変数が 1 つの 'while read' ループではローカルであるのに、他の類似したループではローカルではないのはなぜですか?

答え2

コードを次のように書き直します。

export USER=new
env | grep $USER

変数の内容を取得するには、事前にUSER必要です。コマンドはSTDOUTに出力しないので$、パイプオンはexport意味がありません。export

関連情報