少量のデータのためのリーンソリューション

少量のデータのためのリーンソリューション

Bashコードから

command1 | tee >(command2) | command3

command2inの出力とvar2inの出力をキャプチャしたいと思います。command3var3

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そうしません。などのより高いレベルのシェルが必要ですzshzshネイティブインタフェースはありませんが、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]"

おすすめ記事