2

それは非常に単純な質問だと思いますが、私はそれにこだわっています:

いくつかのデバッグ オプションを使用して実行される外部プログラム (具体的には Exim) と通信する必要があります。Linux シェルから実行すると、次のようになります: run を実行しexim -bh 11.22.33.44、その出力 (STDOUT と STDERR の両方) を読み取り、SMTP ダイアログからいくつかの行を入力し、Exim の出力を再度読み取り、別の SMTP 行を入力します。また、bash シェルを使用している間は問題なく動作しますが、PHP スクリプトから実行すると、STDIN 読み取りループでスタックします。

私は使用しますproc-open

$descriptorspec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", 'w'), 
    2 => array("pipe", 'w')
);
$process=proc_open('/usr/sbin/exim -bh 11.22.33.44', $descriptorspec, $pipes, NULL, NULL);
if (is_resource($process)) {
    stream_set_blocking($pipes[1], 1);
    stream_set_blocking($pipes[2], 1);
    while(!feof($pipes[2])) {
        $txt2 = fgets($pipes[2]);
    }
    while(!feof($pipes[1])) {
        $txt2 = fgets($pipes[1]);
    }
    fwrite($pipes[0], 'HELO testhost');
...
}

シンプルに見えますが、最初の STDERR の最後に行くとスタックしました。

ブロッキング モードとブロック解除モードの両方を試し、STDERR と STDIN からの読み取りを交換しようとしましたが、これまでのところうまくいきませんでした。

それを行う正しい方法を教えてください!

4

1 に答える 1

0

私は、exim が STDIN、STDOUT、および STDERR で異常なことをしていないことを再確認します。さらに、swaks を使用して STDIN および STDOUT にパイプできることも知っています (STDERR はデバッグ出力なので、無視してかまいません)。swak では、次のようなコマンドを使用してデバッグ ビルドをテストするのが一般的です。

swaks --pipe './build-Linux-i386/exim -bh 205.201.128.129 
              -C/work/home/exim-build/tmp/etc/exim/exim.conf'
  --ehlo twitter4.us4.mcsv.net 
  --from bounce-mc.us3_23284199.312009-user=example.com@twitter4.us4.mcsv.net
  --to localuser@example.net --data $HOME/12.eml

スクリプトは、パイプが閉じられたときにのみ送信される EOF をチェックしています。代わりに、外側のループが for() をチェックし、パイプの 1 つから !eof() をチェックする関数を構築する必要があります。ループ内で、STDERR および STDOUT からの出力をチェックし、見つかった場合は表示します。入力を期待するポイントに到達したら、SMTP コマンドを送信します。

ただし、まだ問題があります。print $txt2 を使用して動作を確認すると、どういうわけかその出力は fprintf($pipes[0]...) と同じように見えます。理由はわかりませんが、なぜこれを行うのかを知るPHPプログラマーではありません。

于 2014-06-04T16:14:23.807 に答える