2014-03-25 50 views
4

考虑此示例脚本:当/bin/sh链接PHP proc_open庆典VS短跑

30760 pts/0 S+  0:00 |   \_ php f.php 
30761 pts/0 S+  0:00 |    \_ sh -c cat 
30762 pts/0 S+  0:00 |     \_ cat 

<?php 

$pipes = array(); 
$p = proc_open('cat', array(0 => STDIN, 1 => STDOUT, 2 => STDERR), $pipes); 
fgetc(STDIN); 

/bin/sh被链接到/bin/dash(Debian的默认值),cat在shell被执行到/bin/bash然而,catphp的直接子:

30786 pts/0 S+  0:00 |   \_ php f.php 
30787 pts/0 S+  0:00 |    \_ cat 

这是非常烦人的不一致性,这使得不可能可靠地发送信号产生的过程(因为信号有时被外壳接收)。

为什么proc_open的行为有所不同,取决于/bin/sh指向哪里? 有没有办法不运行一个shell,即使/bin/sh不是bash

回答

3

PHP在两种情况下都通过/ bin/sh运行命令,区别在于shell,而不是PHP。破折号分叉进程运行命令(在这种情况下猫),并等待它完成。 bash做了一个execve(),所以它用cat替换了它自己的进程。

他们似乎在以后的版本中,虽然固定它:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=436466

使用bash或破折号的最新版本应该可以解决你的问题,因为执行命令获取催生壳的PID,从而接收信号。

+0

谢谢。我想这是readme.md的“警告”部分。 – Peter

+0

我仍然在用Dash 0.5.8.2看到这个问题,但是我通过在传递给'proc_open()'的命令行前面加上'exec'来解决它。 –