2017-09-04 4 views
1

私の現在のプロジェクトでは、実行中に後で必要となる変数を定義するループを実行します。私は 以降のファイルでもログを検査することができるように、ティーとログを追加したいまで すべてがうまくいきました。私は、stdoutとstderrの両方を記録したかったよう 、私は|&2>&1 |のショートカット)を適用します。 しかし、不思議なことに、変数の値が失われてしまいます。バッシュ:影響範囲変数スコープをロギングできますか?

for i in 1 2 3 ; do 
    # ... do something meaningful ... 
    myVar=test1 
done |& tee test1 
echo "myVar=$myVar" 

出力:私はファイルリダイレクトプロセス置換、変数定義作品の組み合わせに切り替えるとき:

myVar= 

はその間私はより良い動作方法を見つけました。

for i in 1 2 3 ; do 
    # ... do something meaningful ... 
    myVar=test2 
done > >(tee test2 ) \ 
    2> >(tee test2 >&2) 
echo "myVar=$myVar" 

出力::-)

  1. がなぜ値が最初の例で迷子ない理由私は理解したい

    myVar=foo 
    

    しかし、?

  2. は、なぜそれが第二で迷子にしないのですか?あなたは

を伝えることはできますか?

+1

パイプを使用するとパイプの両側にサブシェルが作成され、両方のパイプが終了すると、内部で環境が失われます。それは、ティーとは何の関係もなく、どんなコマンドでも試してみてください。二番目の方法は、 '>()'のためのサブシェルを作成するだけなので、そこにないものは失われません。 – 123

答えて

1

As 123 saidパイプサブシェル(新規スコープ)とサブシェルを作成するには、親シェルの変数へのアクセスを有していません。

次のヘルパー関数は、シェルのPIDと可変aの値を示しています。のみリダイレクションを使用するため

show_a() { echo $BASHPID: a=$a >&2; } 

次の例では、何のサブシェルを作成しません。 1つの変数aのみが使用されます。

$ a=1; show_a; { a=2; show_a; } > /dev/null ; show_a 
31072: a=1 
31072: a=2 
31072: a=2 

しかし、この例ではパイプのためにサブシェルを作成しています。また、各プロセスには独自の変数aがあります。

$ a=1; show_a; { a=2; show_a; } | tee ; show_a 
31072: a=1 
6375: a=2 
31072: a=1 
+0

あなたがた両方に感謝します。実行中に$ BASHPIDを出力するのに便利です。 – Hardy

関連する問題