web-dev-qa-db-ja.com

現在のプロセスをそのコプロセス/子に置き換えます

「Hello」を受信して​​「Why?」を出力することを期待するプログラムPがあります。機能を提供する前に。この機能は、「Hello」との会話を開始することが一般的な礼儀であることを認識していない他のプログラムによって使用されます。したがって、次のように機能するPのラッパーを作成します(zsh構文)。

coproc P
print -p Hello  # Send Hello to P
read -pr line   # Read what P has to say
[[ "$line" = "Why?" ]] && Replace current process with the coprocess.
echo Could not get P's attention.

Replace...部分(cat <&p &; exec cat >&pなど)でcatまたはddを使用すると、不要なバッファリングが発生します。私のオプションは何ですか?

10
Michaël

あなたが述べた問題は、実際にはprocessを置き換えることではなく、既存のプロセスのstreamsを置き換えることです。目標は、プロセスと少し対話してから、その入力/出力を接続されたストリームの別のペアに渡すことです。

これを直接行う方法はありません(少なくとも、シェルでは、プロセス内では、dup2呼び出しはおそらく機能する可能性があります)。ストリームをスプライスする必要があります。つまり:

( echo Hello ; cat ) | P | ( read ; cat )

あなたの例のようにcoprocを使用することもOKです。このコマンドはファイル記述子を配列に保存し、後でリダイレクトに使用できることに注意してください。

Pが接続されている入力/出力ストリームを検査し、それに基づいてバッファリングすることを決定しない限り、これによって追加のバッファリングが発生することはありません(少なくともGNU cat))。たとえば、C標準ライブラリは、ファイルに接続されている場合はstdout/stderrでのバッファリングを有効にしますが、端末に接続されている場合にのみラインバッファリングを実行します。

1