Unfortunately, I've found all the solutions for executing external programs not suitable, so I use my own implementation, which is pcntl_exec
after pcntl_fork
.
But now I need to redirect stderr/stdout of the executed program into some file. It's obvious, that I should use some sort of dup2
Linux call after pcntl_fork
, but the only dup2
I can see in PHP is eio_dup2
, which looks like it operates not the regular streams (like stderr/stdout), but some async streams.
How can I call dup2
from PHP or how can I redirect std* without it?
The same question (though, without details) has no answers: How do I invoke a dup2() syscall from PHP ?
Here comes a way without the need of dup2
. It is based on this answer.
$pid = pcntl_fork();
switch($pid) {
case 0:
// Standard streams (stdin, stdout, stderr) are inherited from
// parent to child process. We need to close and re-open stdout
// before calling pcntl_exec()
// Close STDOUT
fclose(STDOUT);
// Open a new file descriptor. It will be stdout since
// stdout has been closed before and 1 is the lowest free
// file descriptor
$new_stdout = fopen("test.out", "w");
// Now exec the child. It's output goes to test.out
pcntl_exec('/bin/ls');
// If `pcntl_exec()` succeeds we should not enter this line. However,
// since we have omitted error checking (see below) it is a good idea
// to keep the break statement
break;
case -1:
echo "error:fork()\n";
exit(1);
default:
echo "Started child $pid\n";
}
Error handling has been omitted for brevity. But keep in mind that in system programming should carefully handle any function return value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With