不幸的是,我发现执行外部程序的所有解决方案都不合适,所以我使用自己的实现,在pcntl_fork之后是pcntl_exec.
但是现在我需要将执行程序的stderr / stdout重定向到某个文件中.很明显,我应该在pcntl_fork之后使用某种dup2 Linux调用,但我在PHP中看到的唯一的dup2是eio_dup2
,看起来它不是常规流(如stderr / stdout),而是一些异步流.
如何从PHP调用dup2或如何在没有它的情况下重定向std *?
同样的问题(但没有细节)没有答案:How do I invoke a dup2() syscall from PHP ?
解决方法:
这是一种不需要dup2的方法.它基于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";
}