環境を変更するコマンドの出力を変数として保存します。

環境を変更するコマンドの出力を変数として保存します。

環境を変更するコマンドの出力を変数として保存するにはどうすればよいですか?

私はbashシェルを使用しています。

私が持っているとしましょう:

function f () { a=3; b=4 ; echo "`date`: $a $b"; }

これで、次のコマンドを使用して実行できますf

$ a=0; b=0; f; echo $a; echo $b; echo $c
Sat Jun 28 21:27:08 CEST 2014: 3 4
3
4

fしかし、出力を変数に保存したいcので、次のようにします。

a=0; b=0; c=""; c=$(f); echo $a; echo $b; echo $c

しかし、残念ながら私は次のことをしました。

0
0
Sat Jun 28 21:28:03 CEST 2014: 3 4

したがって、ここに環境の変化はありません。

関数だけでなく、コマンドの出力を変数に保存し、環境の変更を保存するにはどうすればよいですか?

これは新しいサブシェルを開くこととそれが問題であることを知っていますが、$(...)回避策はありますか?

ベストアンサー1

Bash 4以降を使用している場合は、次のものを使用できます。共同プロセス:

function f () { a=3; b=4 ; echo "`date`: $a $b"; }
coproc cat
f >&${COPROC[1]}
exec {COPROC[1]}>&-
read c <&${COPROC[0]}
echo a $a
echo b $b
echo c $c

出力されます

a 3
b 4
c Sun Jun 29 10:08:15 NZST 2014: 3 4

coproccat与えられたコマンドを実行する新しいプロセス(ここ)を作成します。 PIDを配列に保存し、COPROC_PIDstdout / inputファイル記述子を配列に保存しますCOPROC(例:pipe(2)、または参照ここまたはここ)。

ここでは、実行中のcoprocessを指す標準出力で関数を実行しcatreadから。cat単に入力をエクスポートするだけなので、関数の出力を変数に入れます。永遠に待たないように exec {COPROC[1]}>&-ファイル記述子を閉じてください。cat


read一度に1行しか必要ありません。これを使用mapfileして行配列を取得したり、ファイル記述子を使用したりできますが、別の方法で使用したいと思います。

exec {COPROC[1]}>&-現在のバージョンのBashで動作しますが、以前のSeries 4バージョンでは、まずファイル記述子を単純な変数に保存する必要があります。fd=${COPROC[1]}; exec {fd}>&-変数が設定されていない場合、標準出力は閉じます。


Series 3 バージョンの Bash を使用している場合は、次のコマンドを使用して同じ効果を得ることができますmkfifoしかし、この時点では実際のファイルを使用するよりもあまり良くありません。

おすすめ記事