現在のプロセスを補助プロセス/サブプロセスに置き換える

現在のプロセスを補助プロセス/サブプロセスに置き換える

P機能を提供する前に「Hello」を受信して​​「Why?」を出力するプログラムがあります。この機能は、「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.

セクション(例:)に使用されるか、cat不要なバッファリングが発生する可能性があります。私のオプションは何ですか?ddReplace...cat <&p &; exec cat >&p

答え1

あなたが言う問題は、実際に交換に関するものではありません。プロセスしかし、既存のプロセスを置き換える小川。目的は、プロセスとある程度対話し、対応する入力/出力を他の接続されたストリームペアに渡すことです。

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

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

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

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

答え2

バッファリングを避けるために、Perlを使用して次のコードをテストできます。これがうまくいくかどうか試してみてください。

Pの例示的なバージョン

$ cat /tmp/P
#!/bin/bash
read input
if [[ $input = "Hello" ]]
then
    echo "Why?"
else
    exit 1
fi
echo "Got Hello from client, working ..."
sleep 10
echo "Need to read some input"
read x
echo "Got: $x"

包装プログラム

$ cat /tmp/wrapper 
#!/usr/bin/zsh
coproc /tmp/P
print -p Hello  # Send Hello to P
read -pr line   # Read what P has to say
if [[ "$line" = "Why?" ]]; then
    perl -e '$|=1;print $_ while(<>);' <& p &
    perl -e '$|=1;print $_ while(<>);' >& p
else
    echo "Could not get P's attention."
fi

テストの実行

$ /tmp/wrapper 
Got Hello from client, working ...
Need to read some input
hi there P!   <== Typed in at teminal
Got: hi there P!

関連情報