为什么有些二进制文件不能与shell_exec一起使用?

时间:2018-09-05 12:16:18

标签: php fedora

我不明白为什么,但是我无法从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上使用。

1 个答案:

答案 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中看到了输出。