(BASHの場合)サブシェルが非STDOUT非STDERRファイル記述子を使用して、データを親シェルに返すようにします。どうやってやるの?最終的には、親シェルの変数にデータを保存したいと思います。
(
# The following two lines show the behavior of the subshell.
# We cannot change them.
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent Shell" >&3
)
#...
data_from_subshell=... # Somehow assign the value of &3 of the
# subshell to this variable
編集:サブシェルは、STDOUTおよび&3に書き込むブラックボックスプログラムを実行します。
BEWARE、BASHISM AHEAD(プロセス置換のないashやdashなど、bashよりも大幅に高速なposixシェルがあります)。
ハンドルダンスを実行して、元の標準出力を新しい記述子に移動し、標準出力をパイピングに使用できるようにします(頭の上から)。
_exec 3>&1 # creates 3 as alias for 1
run_in_subshell() { # just shortcut for the two cases below
echo "This goes to STDOUT" >&3
echo "And this goes to THE OTHER FUNCTION"
}
_
今、あなたは書くことができるはずです:
_while read line; do
process $line
done < <(run_in_subshell)
_
しかし、<()
コンストラクトはバシズムです。パイプラインに置き換えることができます
_run_in_subshell | while read line; do
process $line
done
_
2番目のコマンドalso以外はsubshellで実行されます。パイプラインを行います。
もちろん、最も簡単な方法は、出力を親で直接キャプチャすることです
data_from_subshell=$(echo "This is the data I want to pass to the parent Shell")
子からデータを読み取る代替方法として名前付きパイプを使用できます
mkfifo /tmp/fifo
これで、子を/tmp/fifo
にリダイレクトできます
(
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent Shell" >/tmp/fifo
) &
親はそこから読むことができます
read data_from_subshell </tmp/fifo
別の方法は、 coproc
を使用して子プロセスを開始することです。これにより、双方向パイプを持つ子が作成され、子のstdinとstdoutがパイプ記述子にリダイレクトされます。子でパイプと標準出力の両方を使用するには、最初に親で標準出力を複製する必要があります
exec 4>&1 # duplicate stdout for usage in client
coproc SUBSHELL (
exec 3>&1 1>&4- # redirect fd 3 to pipe, redirect fd 1 to stdout
(
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent Shell" >&3
)
)
exec 4>&- # close fd 4 in parent
read data <&${SUBSHELL[0]}
echo "Parent: $data"
コプロセスはBash 4.0で導入されました。