私はbash coproc
を使用しようとしていますが、おそらくバッファリングで問題が発生しています。標準入力からの行指向の入力を受け入れ、入力行ごとに標準出力に行を出力する複雑なコマンドがあります。コマンドラインでは、このコマンドは行ごとに正常に機能しますが、コプロシージャに入れて${COPROC[0]}
FD から読み取ると、読み取りがブロックされます。
この動作は で再現できますが、 では再現できpaste
ませんcat
。パラメータが渡されなかった場合、私はほとんど同じことを期待paste
しています。cat
これは、コマンド プロンプトで直接実行する場合です。
$ cat
Hello World!<RETURN>
Hello World!^D
$ paste
Hello World!<RETURN>
Hello World!^D
$
(説明のためRETURN
に^D
追加)
しかし、これらをcoprocに入れると、動作が異なります-cat
厳密に行バッファリングされpaste
ていますが、はるかに大きなバッファで動作しているようです:
$ coproc cat
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
Hello world!
$ kill $COPROC_PID
[3]+ Terminated coproc COPROC cat
$
$ coproc paste
[3] 42657
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
#### read blocks here until ^C ####
paste
この理由は、接続先に応じてバッファリングモードを調整するためだと思いますが、cat
常にラインバッファリングモードになっています。
coproc で強制的にpaste
(または他の一般的なコマンドを) ライン バッファリングする方法はありますか?
もう少し実験を重ねた結果、 coproccat
を使用せずに と の間をパイプするだけで、同様の動作を再現できることがわかりましたpaste
。
$ cat | cat
Hello World!<RETURN>
Hello World!^D
$ cat | paste
Hello World!<RETURN>
Hello World!^D
$ paste | cat
Hello World!<RETURN>
#### command blocks here until ^C ####
(説明のためRETURN
に^D
追加)
- 最初に、パイプ
cat
しcat
て行バッファリングを取得しますが、 - 次に、パイプ
cat
してpaste
行バッファリングを取得します - 最後に、パイプ
paste
してcat
行バッファリングを取得しません
これは、 がインタラクティブ モードの場合は stdout をライン バッファリングすることを示しているように見えpaste
ますが、それ以外の場合は、はるかに大きなバッファを使用します。