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
?
PHP runs the command via /bin/sh in both cases, the difference is in the shells, not PHP. dash forks the process to run the command (cat in this case) and waits for it to finish. bash does an execve(), so it replaces its own process with cat.
They seem to have fixed it in later versions though: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=436466
Using bash or the latest version of dash should fix your problem, since the executed command gets the PID of the spawned shell and thus receives the signals.