【发布时间】:2018-01-27 13:06:56
【问题描述】:
我试图从 PHP 网页运行 npm,但它永远不会运行。我总是得到 127 的退出代码并且没有输出。在做了一些测试后,我将问题缩小到npm 中的shebang,如下所示:
#!/usr/bin/env node
相当标准,但我做了一些测试代码:
<?php
$result = exec("/usr/bin/env node --version", $output, $exit);
var_dump($result);
var_dump($exit);
$result = exec("node --version", $output, $exit);
var_dump($result);
var_dump($exit);
$result = exec("/usr/bin/env gzip --version", $output, $exit);
var_dump($result);
var_dump($exit);
在我的浏览器中得到了这个输出:
string(0) ""
int(127)
string(6) "v8.4.0"
int(0)
string(28) "Written by Jean-loup Gailly."
int(0)
我在 PHP-FPM 配置中启用了catch_workers_output,并在 PHP 日志中看到了这一点:
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: "/usr/bin/env: "
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: "node"
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: ": No such file or directory"
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: ""
我还尝试从 Web 服务器运行 exec("which node"),并在 PHP 日志中看到了这一点:
[18-Aug-2017 15:31:12] WARNING: [pool web] child 27873 said into stderr: "which: no node in ((null))"
我尝试运行 var_dump(exec('echo $PATH')) 并得到以下输出:
string(28) "/usr/local/bin:/bin:/usr/bin"
这似乎与env 命令如何处理路径有关。我尝试使用nginx.conf 中的fastcgi_param PATH 指令手动设置它,但对上述输出没有任何改变。
单独运行 env 并打印输出如下所示,没有 PATH 条目:
Array
(
[0] => USER=nginx
[1] => PWD=/var/www/html
[2] => SHLVL=1
[3] => HOME=/var/cache/nginx
[4] => _=/bin/env
)
我在一个基于 RHEL 的发行版上,禁用了 SELinux,通过 Nginx 1.12.1 的 UNIX 套接字运行 PHP-FPM 5.6.31。 /usr/local/bin/node 是一个指向/usr/local/nodejs/bin/node 的符号链接,它有 775 个权限。出于测试目的,nginx 用户拥有/usr/local/nodejs 目录及其所有后代。有什么建议吗?
请注意,如果我从 CLI(作为 nginx 用户)运行 PHP 代码,它会按预期工作,所以这肯定与 CGI/FPM 环境有关。
$ su -s "/bin/sh" -c "/var/www/html/test.php" nginx
string(6) "v8.4.0"
int(0)
string(6) "v8.4.0"
int(0)
string(28) "Written by Jean-loup Gailly."
int(0)
【问题讨论】:
-
在浏览器中运行
exec("which node", $output, $exit);会发生什么? -
@chiliNUT 没有输出,退出代码 1。这又没有意义,因为我可以只使用
node运行它,所以它必须在$PATH中。在 CLI 中工作正常($_SERVER["PATH"]在 FPM 中返回null,在 CLI 上似乎很好) -
很奇怪。如果 which 返回代码 1 我认为这意味着它没有找到它。但如果你可以只用
node运行它,它必须在$path...但我很确定which只是查看路径中的所有内容,直到找到它或放弃它,所以这很奇怪 -
根据
_变量,用/bin/env调用shell。当你运行exec("/bin/env node --version", $output, $exit);时会发生什么? -
@piarston 是一样的,
/usr/bin/env是一个符号链接。