これをPOSIXシェルで実行すると、
$ cmd0 | cmd1
Cmd0のSTDOUTは、cmd1のSTDINにパイプされます。
Q:これに加えて、どうすればまた cmd1のSTDOUTをcmd0のSTDINにパイプできますか?
名前付きパイプ(FIFO)との間のリダイレクトを使用することは必須ですか?名前付きパイプはいくつかのファイルシステムパスを占有し、名前の衝突について心配する必要があるため、私はあまり好きではありません。または、C、Python、またはいくつかの汎用プログラミング言語を介してpipe(2)を呼び出す必要がありますか?
(cmd0とcmd1はどちらもネットワークI/Oを実行するため、相互に永久にブロックされることはありません。)
双方向パイプ(Linuxではない)を備えたシステムでは、次のことができます。
cmd0 <&1 | cmd1 >&0
Linuxでは、次のことができます。
{ cmd0 < /dev/fd/3 | cmd1 3>&-; } 3>&1 | :
Linux(およびLinuxのみ)では/dev/fd/x
ここで、x
は名前付きパイプのfdであり、名前付きパイプのように機能します。つまり、読み取りモードで開くと読み取り終了になり、書き込みモードで開くと書き込み終了になります。
yash
Shell とそのx>>|y
パイプラインリダイレクト演算子 :
{ cmd0 <&4 3<&- 4<&- | cmd1 >&3 3>&- 4>&-; } 3>>|4
zsh:
coproc cmd0
cmd1 <&p >&p
ksh
cmd0 |&
cmd1 <&p >&p
bash4 +
coproc cmd0
cmd1 <&"${COPROC[0]}" >&"${COPROC[1]}"
専用ツールアプローチ( この非常によく似た質問 の回答から恥知らずにコピー):
pipexec
を使用する
pipexec [ A /path/to/cmd0 ] \
[ B /path/to/cmd1 ] \
'{A:1>B:0}' '{A:0>B:1}'
または dpipe
を使用する
dpipe cmd0 = cmd1
または socat
を使用します:
socat EXEC:cmd0 EXEC:cmd1,nofork # using socketpairs
socat EXEC:cmd0,commtype=pipes EXEC:cmd1,nofork # using pipes
python
についてはわかりませんが、Perl
でも比較的簡単に実行できます。
Perl -e 'pipe STDOUT,STDIN; exec "cmd0 | cmd1"'
いずれにせよ、デッドロックに注意してください!