2つのプログラム間に一方向パイプを設定する方法(stdout
最初のプログラムとstdin
2番目のプログラムバインディング)は誰でも知っていますfirst | second
。
しかし、双方向パイプライン、つまり2つのプログラムのクロスstdin
バインディングを作成する方法は何ですかstdout
?シェルで簡単にできる方法はありますか?
ベストアンサー1
まあ、名前付きパイプ()を使うのはかなり「簡単」ですmkfifo
。プログラムがこの目的のために設計されていない場合は、デッドロックが発生する可能性が高いため、引用符で囲まれました。
mkfifo fifo0 fifo1
( prog1 > fifo0 < fifo1 ) &
( prog2 > fifo1 < fifo0 ) &
( exec 30<fifo0 31<fifo1 ) # write can't open until there is a reader
# and vice versa if we did it the other way
標準出力に書き込む操作には通常バッファリングが含まれます。たとえば、両方のプログラムが次のような場合:
#!/usr/bin/perl
use 5.010;
say 1;
print while (<>);
無限ループが予想されます。しかし、むしろ両側はデッドロックに陥る。$| = 1
出力バッファリングをオフにするには追加(またはそれに対応するもの)が必要です。デッドロックの原因は両方プログラムが標準入力で何かを待っていますが、他のプログラムの標準出力バッファにあり、まだパイプに書き込まれていないため、これは表示されません。
修正する:Stéphane CharzelasとJoostの提案を組み合わせます。
mkfifo fifo0 fifo1
prog1 > fifo0 < fifo1 &
prog2 < fifo0 > fifo1
同じことを行い、より短くて携帯性に優れています。