3

Consider this sample script:

<?php

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

When /bin/sh is symlinked to /bin/dash (the Debian default), cat gets executed in a shell:

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

When /bin/sh is linked to /bin/bash however, cat is a direct child of php:

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

This is very annoying inconsistency that makes it impossible to reliably send signals to the spawned process (as the signal is sometimes received by a shell).

Why is proc_open behaving differently depending on where /bin/sh points to? Is there a way to not run a shell, even if /bin/sh is not bash?

4

1 回答 1

4

PHP 在这两种情况下都通过 /bin/sh 运行命令,区别在于 shell,而不是 PHP。dash 分叉进程以运行命令(在本例中为 cat)并等待它完成。bash 执行了一个 execve(),因此它用 cat 替换了自己的进程。

他们似乎在以后的版本中修复了它:https ://bugs.debian.org/cgi-bin/bugreport.cgi?bug=436466

使用 bash 或最新版本的 dash 应该可以解决您的问题,因为执行的命令会获取生成的 shell 的 PID,从而接收信号。</p>

于 2014-03-28T11:13:15.187 回答