別の処理のために、teeを使用してコマンドの標準出力を2つの「分岐」にリダイレクトしようとしています。最後に、貼り付けを使用して2つの「分岐」の結果をマージする必要があります。私は生産者のために次のコードを思いつきました。
mkfifo a.fifo b.fifo
python -c 'print(("0\t"+"1"*100+"\n")*10000)' > sample.txt
cat sample.txt | tee >(cut -f 1 > a.fifo) >(cut -f 2 > b.fifo) | awk '{printf "\r%lu", NR}'
# outputs ~200 lines instantly
# and then ~200 more once I read from pipes
その後、別の端末で消費者を起動します。
paste a.fifo b.fifo | awk '{printf "\r%lu", NR}'
# outputs ~200 once producer is stopped with ctrl-C
問題はそれが停止することです。この動作は入力の長さによって異なります。
- 入力行が小さい場合(つまり、2番目の列に100文字ではなく30文字が含まれている場合)、これはうまく機能します。
- 同じ(または同様の長さ)入力が入力
a.fifo
として与えられると、うまく動作するようです。b.fifo
a.fifo
問題はsayから短いチャンクを供給しb.fifo
。この動作はパイプを指定する順序には依存しませんpaste
。
私はLinuxとそのパイプロジックについてはよくわかりませんが、何とか詰まっているようです。私の質問は、これが何とか安定して達成できるかどうかです。それでは、どうすればいいですか?おそらくtee
andを使用せずに他の方法がありますかpaste
?
答え1
問題を詳しく理解できませんでした。明らかに、これはいくつかのバッファを満たす各ラインのサイズの違いに関連しています。
この問題は、バッファを拡大することで「解決」することができます。
paste a.fifo <(buffer <b.fifo) | awk '{printf "\r%lu", NR}'
面白い事実:buffer
ビルドコマンドにaを追加するとawk
完了できますが、コマンドを使用するとまだブロックされます(私の場合はほぼ終わり)。
$ cat sample.txt | tee >(cut -f 1 > a.fifo) >(cut -f 2 | buffer > b.fifo) | awk '{printf "\r%lu", NR}; END { print; print NR; }'
10001
$ paste a.fifo b.fifo | awk '{printf "\r%lu", NR}'
8152
IMHO、言うことはできません。バグが関係していても驚かないでしょう。