Bashコードから
command1 | tee >(command2) | command3
command2
inの出力とvar2
inの出力をキャプチャしたいと思います。command3
var3
command1
他のコマンドはI / O制約のため高価ですが、command1
完了する前に作業を開始できます。
command2
合計の出力順序command3
は固定されていません。だから私はファイル記述子を使ってみました。
read -r var2 <<< var3=(command1 | tee >(command2 >&3) | command3) 3>&1
または
{read -u 3 -r var2; read -r var3} <<< command1 | tee >(command2 >&3) | command3
しかし、成功しませんでした。
これら3つのコマンドを並列に実行して一時ファイルを作成せずに結果を別の変数に保存する方法はありますか?
ベストアンサー1
それでは、cmd1の出力をcmd2とcmd3にパイプし、cmd2とcmd3の出力を別の変数にインポートしますか?
したがって、シェルには2つのパイプが必要なようです。 1つはcmd2の出力に、もう1つはcmd3の出力に接続され、シェルは両方のパイプでselect()
/を使用します。poll()
bash
そうしません。などのより高いレベルのシェルが必要ですzsh
。zsh
ネイティブインタフェースはありませんが、pipe()
Linuxでは通常のパイプの名前付きパイプとして機能するという事実を活用し、/dev/fd/x
以下のようなものを使用できます。シェルリダイレクトを使用して同じファイル記述子を読み書きする
#! /bin/zsh -
cmd1() seq 20
cmd2() sed 's/1/<&>/g'
cmd3() tr 0-9 A-J
zmodload zsh/zselect
zmodload zsh/system
typeset -A done out
{
cmd1 > >(cmd2 >&3 3>&-) > >(cmd3 >&5 5>&-) 3>&- 5>&- &
exec 4< /dev/fd/3 6< /dev/fd/5 3>&- 5>&-
while ((! (done[4] && done[6]))) && zselect -A ready 4 6; do
for fd (${(k)ready[(R)*r*]}) {
sysread -i $fd && out[$fd]+=$REPLY || done[$fd]=1
}
done
} 3> >(:) 5> >(:)
printf '%s output: <%s>\n' cmd2 "$out[4]" cmd3 "$out[6]"