无法通过php exec运行shell命令,但可以作为shell上的用户吗?

时间:2014-05-14 19:02:01

标签: linux perl bash shell exiftool

我正在尝试让exiftool在我的专用服务器上运行。问题是PHP exec似乎与命令以用户身份运行时不同。奇怪的是,PHP显示为我登录的用户,但它与系统命令的行为不一样。

奇怪的是,我的本地主机上的一切都运行良好,但不在我的服务器上。

如上所述,运行通过ssh登录的exiftool命令很好。

但是在php测试脚本中运行(注意我已经在每个测试目录上安装了exiftool,并且它通过ssh运行),没有任何东西可以访问,尽管它以用户orangeman运行...

它失败了

这是更新 - 整天都在这里:

在shell上:

-bash-4.1$ which exiftool -a
~/perl5/bin/exiftool
/usr/bin/exiftool
~/perl5/bin/exiftool

在PHP shell_exec('exiftool -a');

/usr/bin/exiftool

以下是该文件链接的内容:

lrwxrwxrwx    1 root root          33 May 15 02:10 exiftool -> /home/orangeman/perl5/bin/exiftool

我也尝试创建各种各样的符号链接,在php中通过putenv();篡改主要的$ PATH变量......我真的在黑暗中。适用于localhost,而不是专用服务器。


我用赏金更新了这个 - 这是一个严重的问题。

我在专用服务器上,问题如上所述。


更新 根据@gcb的建议,我能够打印出php的exec()函数运行系统命令时发生的错误。

PHP

<?php
exec('exiftool 2>&1', $output, $r);
var_dump($output, $r);
?>

输出:

array(2) {
  [0]=>
  string(230) "Can't locate Image/ExifTool.pm in @INC (@INC contains: /bin/lib /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /bin/exiftool line 33."
  [1]=>
  string(59) "BEGIN failed--compilation aborted at /bin/exiftool line 33."
}

更新

@ gcb的解决方案奏效了。非常感谢你。

4 个答案:

答案 0 :(得分:5)

所以你现在没有php问题,而是一个perl问题。你的包含路径很糟糕。

在这里回答http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=2217.0

You either have to install the ExifTool libraries in the
standard location (ie. somewhere in the @INC directories
listed in your post), or add the location to the include path,
something like this:

Code:
#!/usr/bin/perl
BEGIN { unshift @INC, "PATH_TO_DIRECTORY_CONTAINING_LIBRARIES" }
use Image::ExifTool;

You should be able to add "Image/ExifTool.pm" to the path you add
to find the ExifTool module.

- Phil

我仍然认为使用上一个答案中我的建议#3会解决它。如果没有,你真的想知道原因,创建一个新的perl脚本,只输出@INC的内容,并通过shell和php运行它。你会看到差异,然后你需要找到哪些登录脚本没有在php中被尊重,并打开一个针对PHP shell_exec不尊重它的错误...

虽然更容易解决您的问题(因为它看起来对您的解释不太感兴趣)是在调用脚本之前设置PERLLIB var。

所以,就这样做:

  1. find / -name ExifTool.pm这将告诉您lib的安装位置。让我们说这会返回/example/perl/Image/ExifTool.pm
  2. PERL5LIB=/example/perl/附加到您的exec()调用中。
  3. exec(“PERL5LIB = / example / perl / sudo /var/www/myscript/execscript.sh {$ param}”);

答案 1 :(得分:2)

0)你应该查看你的错误日志。通常在/ var / log / apache / error

它会有“拒绝访问”等消息。

1)您显然没有获得该命令的足够输出以查看任何错误。所以尝试使用exiftool 2>&1运行它。这会将stderr重定向到stdout,因此输出上会出现错误。不确定这是否相关或者php已经这样做了。您可能还想使用passthru代替exec

2)安全模式执行dir

您的文件可能超出您的安全模式exec目录。读完这篇文章:

http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-exec-dir

3)所有其他方法都失败了,将命令作为登录shell运行,登录shell应该具有与通过ssh登录时相同的脚本。只需用shell_exec

替换exec即可

...我非常确定查看错误日志可以解决您的错误。

答案 2 :(得分:1)

一种可能性是,在命令行中,您的$PATH已由$HOME/.bashrc$HOME/.bash_profile设置/修改,因为您的命令行是登录shell。当Web服务器调用PHP时,它运行为&#34; orangeman&#34; 仅作为shell而不是登录shell,因此其$PATH可能不一样,这就是您在此处看到的内容。 您是否尝试将export PATH="what:you:want:your:PHP:path:to:be"放入$HOME/.bashrc

答案 3 :(得分:1)

我相信这种情况正在发生,因为您已为您的用户私有安装perl。

基本上@INC是perl用于定位其库的数组,它不包含安装库的路径。

有几种方法可以更改@INC,您可以在以下链接中找到:

http://perlmaven.com/how-to-change-inc-to-find-perl-modules-in-non-standard-locations

我希望这会有所帮助。