4

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

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

如前所述,运行通过 ssh 登录的 exiftool 命令是可以的。

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

它失败了

这是一个更新- 一整天都在做这个:

在外壳上:

-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

我也尝试过创建各种符号链接,通过putenv();在 php 中篡改主要的 $PATH 变量......我在这里真的很黑暗。在本地主机上工作,而不是在专用服务器上。


我已经用赏金更新了这个 - 这是开发中的一个严重问题。

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


更新 根据@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

4 回答 4

5

因此,您现在没有 php 问题,而是 perl 问题。你的包含路径不好。

在这里回答。

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/ /var/www/myscript/execscript.sh {$param}"); #和
于 2014-05-18T08:06:14.340 回答
2

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

它将包含诸如“拒绝访问”之类的消息或其他消息。

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

2)安全模式执行目录

您的文件可能超出了您的安全模式执行目录。读这个:

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

3) 一切都失败了,将命令作为登录 shell 运行,它应该加载与通过 ssh 登录时相同的脚本。只需将 exec 替换为shell_exec

...我很确定查看错误日志将解决您的困惑。

于 2014-05-18T03:54:32.927 回答
1

一种可能性是,在命令行上,由于您的命令行是登录 shell ,因此您的和您$PATH的都已设置/修改了您。当 Web 服务器调用 PHP 时,它作为“橙子”运行,仅作为 shell,而不是登录 shell,因此它可能不一样,这就是您在此处看到的。你试过放你的吗?$HOME/.bashrc$HOME/.bash_profile$PATHexport PATH="what:you:want:your:PHP:path:to:be"$HOME/.bashrc

于 2014-05-15T02:47:51.493 回答
1

我相信这是因为您为您的用户私人安装了 perl。

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

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

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

我希望这有帮助。

于 2014-05-18T08:44:51.177 回答