我想说这是一个相当简单的问题,但我被困住了:
我需要与运行一些调试选项的外部程序(特别是Exim)进行通信。当我从linux shell运行它时,它是这样的:运行exim -bh 11.22.33.44,然后读取它的输出( STDOUT和STDERR),输入来自SMTP对话框的某一行的类型,然后再次读取Exim输出,输入另一个SMTP行,依此类推。当我在bash shell上时,它工作得很好,但当我从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交换读取-到目前为止还没有成功。
请告诉我做这件事的正确方法!
发布于 2014-06-05 00:14:24
我仔细检查以确保exim没有使用STDIN、STDOUT和STDERR做任何奇怪的事情。此外,我知道您可以使用swaks来连接STDIN和来自STDOUT (STDERR是调试输出,所以您可以忽略它)。在swaks中,通常使用以下命令测试调试构建:
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,它仅在管道关闭时发送。相反,您需要构造一个函数,外部循环检查来自其中一个管道的!eof()。在循环中,检查来自STDERR和STDOUT的输出,如果找到则显示它。当它到达期望输入的点时,然后发送SMTP命令。
然而,仍然存在一个问题。如果您使用来查看它正在做什么,那么不知何故,输出似乎与$txt2 ($pipes...)相同。我不知道为什么,我也不是一个php程序员,不知道为什么它会这样做。
https://stackoverflow.com/questions/24040157
复制相似问题