シェル: STDIN/STDOUT 2 つのコマンドを相互にパイプする

シェル: STDIN/STDOUT 2 つのコマンドを相互にパイプする

POSIXシェルを使用して実行すると、

$ cmd0 | cmd1

cmd0のSTDOUTはcmd1のSTDINにパイプされます。

Q:それにどうすればいいですか?返品cmd1のSTDOUTをcmd0のSTDINにパイプしますか?

名前付きパイプ(FIFO)から強制的にリダイレクトしますか?私は名前付きパイプがいくつかのファイルシステムパスを占有し、名前の競合を心配する必要があるため、あまり好きではありません。それとも、C、Python、またはいくつかの一般的なプログラミング言語でパイプライン(2)を呼び出す必要がありますか?

(cmd0とcmd1はどちらもいくつかのネットワークI / Oを実行するため、お互いを永遠にブロックしません。)

ベストアンサー1

双方向パイプを持つシステム(Linuxではない)では、次のことができます。

cmd0 <&1 | cmd1 >&0

Linuxでは、次のことができます。

: | { cmd1 | cmd2; } > /dev/fd/0

これは、Linux(およびCygwinですが、通常は他のシステムではありません)では、/dev/fd/xパイプx(名前が指定または指定されていない)のfdが名前付きパイプのように機能するために機能します。つまり、読み出しモードでパイプを開くと読み出し側が得られ、書き込みモードに入ると書き込み終了です。

とともにyashシェルそしてそのx>>|y パイプリダイレクトオペレーター:

{ cmd0 | cmd1; } >>|0

そしてcoprocをサポートするシェル:

  • ジシュ語:

       coproc cmd0
       cmd1 <&p >&p
    
  • ケシ

       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"'

いつでも名前付きパイプに頼ることができますが、一意の名前とそれを生成するためのいくつかのセキュリティディレクトリを見つけ、それへのアクセスを制限し(他のプロセスがパイプを開いたり妨げたりすることがないように)、後でクリーンアップすることは追加の問題になります。克服するのは難しいです。信頼性と携帯性に優れています。

とにかくデッドロックに注意してください!

おすすめ記事