我不明白为什么,但是我无法从PHP页面执行一些二进制文件。
如果我从PHP页面调用它,则不会得到任何输出:
<?php
echo shell_exec('/usr/bin/which ffmpeg');
如果我从CLI执行它,它将起作用:
$ sudo -u apache php -r 'echo shell_exec("/usr/bin/which ffmpeg");'
/usr/bin/ffmpeg
但是,如果我尝试从PHP页面调用whereis
而不是which
,尽管它们位于同一目录中,但我确实得到了输出:
<?php
echo shell_exec('/usr/bin/whereis ffmpeg');
我不明白背后的逻辑...
我已经验证了文件权限,并且一切正常:-rwxr-xr-x. root:root
,并且没有ACL。
我正在使用Fedora 28(SELinux设置为宽松的)。这些命令可在Debian和Ubuntu上使用。
答案 0 :(得分:2)
找到程序后,which
命令将在STDOUT
上生成输出,但是当没有这样的命令时,它将使用STDERR
。
$ strace which php
[...]
access("/usr/bin/php", R_OK) = 0
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0
write(1, "/usr/bin/php\n", 13) = 13
[...]
请注意1
的{{1}},它是write()
的处理程序,但是当找不到该命令时,将使用其他处理程序:
STDOUT
请注意$ strace which something_not_existing
[...]
stat("/usr/games/bin/something_not_existing", 0x7ffc20f046a0) = -1 ENOENT (No such file or directory)
write(2, "which: no something_not_existing"..., 150) = 150
[...]
的{{1}},它是2
的处理程序。
在控制台中,您将同时看到write()
的输出和STDERR
的输出,但是STDOUT
将仅输出/返回STDERR
流。
还要检查http://www.php.net/shell_exec,以了解如何捕获shell_exec()
流。根据您的要求,您甚至可能想要使用STDOUT
之类的其他执行功能来控制STDERR
/ proc_open()
/ STDIN
流。
STDOUT
命令将始终写入STDERR
,这是因为您通过whereis
在php中看到了输出。