【问题标题】:Executing a binary on Linux web server through PHP's exec通过 PHP 的 exec 在 Linux Web 服务器上执行二进制文件
【发布时间】:2013-04-19 07:17:59
【问题描述】:

更新

我的目录结构如下

http://domainname.com/developer/clientName/ppt/phantom/    // inside this phantom folder, all files are present

在与 Bass Jobsen 聊天并查看服务器错误日志后,我发现日志中列出了这一点

[Tue Apr 23 08:31:34 2013] [error] [client xxx.xxx.xx.xxx] sh: line 1: 29443 
Segmentation fault /home/xyz/public_html/developer/clientName/ppt/phantom/phantomjs --version 2>&1

================================================ ====================================

总结

我正在尝试在我的服务器上执行一个二进制文件。二进制文件名为phantomJS,主要用于创建网页截图。

我登录到我的 cPanel 并找到了有关我的服务器的以下信息:

Operating system : Linux
Architecture     : i686

所以我继续从 phantomJS 网站下载了phantomjs-1.9.0-linux-i686.tar.bz2。我上传了位于下载的bin 文件夹内的phantomjs 文件(我刚刚上传了一个名为phantomjs 的文件,大小约为38 MB。我假设我不需要任何文件下载附带的其他文件。有一个examples 文件夹和一些ReadMes 和其他.txt 文件)

我还将另外三个文件上传到存在phantomjs 的同一文件夹中:

  1. test.php(这是将在 浏览器)
  2. test.js(包含启动phantomjs的代码)
  3. createScreenshot.php(包含输出一些 HTML 的代码)

所以所有文件都在同一个文件夹中。因此,不应该因为路径错误而出现问题。

test.php

exec('phantomjs test.js');

test.js

var page = require('webpage').create();
var url = 'createScreenshot.php';
page.open(url, function (status) {
    page.render('test.png');
    phantom.exit();
});

createScreenshot.php

echo '<h1>This should be converted to an image</h1>';

问题

现在,当我浏览到www.mydomain.com/test/test.php 时,我得到的只是一个空白页面,这很好,因为唯一应该发生的事情是在test 文件夹中创建一个图像,但这永远不会发生。没有错误被输出。我也尝试将error_reporting(E_ALL) 放入test.php,但仍然没有显示错误,只是一个空白页。

调试

我决定测试我的服务器上是否完全启用了exec。我这样做是通过使用

echo exec('whoami');

这打印出了我的 cPanel 用户名。所以这意味着exec 正在工作。

接下来我要做的是检查文件夹权限。 test 文件夹拥有 755 权限,phantomjs 也是如此。我尝试将两者都更改为777,但这也无济于事。

这让我相信phantomjs 文件有问题。我不知道下一步该尝试什么。我确信我从 phantomJS 网站 (phantomjs-1.9.0-linux-i686.tar.bz2) 下载了正确的包。

我还能做些什么来调试问题?

更多调试

跑步

echo exec("ls -lh");

打印出来

-rw-r--r-- 1 abc abc 1.8K Apr 6 05:15 third-party.txt

这个third-party.txt 位于包含phantomjs 二进制文件的文件夹中,但我想知道为什么只打印了一个文件名。与third-party.txt 相同的文件夹中也有php 和js 文件。不太确定 1 在上面的输出中代表什么。

【问题讨论】:

  • 您知道phantomjs 是否在您的PHP 可执行路径中吗?如果没有,您可能想尝试找到它并为其使用绝对路径(locate phantomjs 或替代方法)
  • PHP 通常从运行它的用户那里继承路径(通常是/usr/bin, /usr/local/bin)。您需要检查的是 phantomjs 是否确实在其中。如果不是,您需要参考它的绝对路径(即它的确切位置)。 locate phantomjs 可能会返回它的位置。
  • 当您将其上传到与脚本相同的文件夹时,尝试使用以下路径:dirname(__FILE__)."/phantomjs" 很可能证明有效。
  • 抱歉这个菜鸟问题,但您的意思是尝试echo exec(dirname(__FILE__)."/phantomjs") 吗?
  • 是的,如果 phantomjs 与您的 PHP 脚本位于同一文件夹中。或随后的错误/警告/通知。

标签: php linux exec


【解决方案1】:

如果通过 FTP 上传二进制文件,它可能会由于 FTP 客户端更改文件内的行结尾而损坏。

要解决此问题,请将传输模式更改为二进制(在 FileZilla 中:传输 -> 传输类型 -> 二进制)。

[source]

【讨论】:

  • 完美。这确实是问题所在。通过 Filezilla 传输时,二进制文件已损坏。你是一个救生员。过去一周我一直在为这个问题苦苦挣扎。
  • @uınbɐɥs 他哥们.. 你在做什么?您可以在chat.*.com/rooms/29074/html-css-webdesign 聊天室加入我们...它的 NullPointer :)
【解决方案2】:

我已经尝试过你所做的。

test.php:

<?
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo exec('./phantomjs-1.9.0-linux-i686/bin/phantomjs ./test.js 2>&1');
exit;

除了./,我还可以使用$_SERVER['DOCUMENT_ROOT']

我的 test.js:

var page = require('webpage').create();
page.open('http://github.com/', function () {
page.render('github.png');
phantom.exit();
});

所有文件都在我的文档根目录 (/var/www/) 中。 Test.php 从网络服务器运行,phantomjs 在通过exec() 调用时也是如此。运行网络服务器的用户(www-data 需要权限)来编写“github.png”。为此,我使用 chmod 0777 /var/www/。现在一切正常。

没有 chmod test.php 给我一个空白页。 phantomjs 不会打印错误。

注意不要在生产环境中更改根目录的权限。为您的屏幕截图创建新目录并对其进行 chmod 并在 test.js 中更改保存路径

【讨论】:

  • 感谢您的回复。我为图像创建了一个新文件夹,将权限设为777 并更新了.js 文件中的路径。它仍然没有工作。也许运行网络服务器的用户没有权限。有没有办法找出这是否正是问题所在?或者可以通过 cPanel 为用户添加权限的任何操作?
  • 您可以将带有php.net/manual/en/function.fwrite.php 的新文件写入您的图像目录并检查它获得的用户/组
  • 我不确定您所说的 check the user/group it get 是什么意思。我在应该保存屏幕截图的文件夹中创建了一个新的文本文件。然后我运行了一个简单的fwrite 没有那个新创建的文本文件。它是成功的。文件确实被写入了。
  • 如果fwrite可以写,phantomjs也可以echo exec('./phantomjs --version 2&gt;&amp;1');的输出是什么
  • 我得到了sh: phantomjs: command not found 我还必须从./phantomjs --version 2&gt;&amp;1 中删除./ 才能显示该消息
【解决方案3】:

exec 运行 IMAGEMAGICK 库时,我遇到了类似的问题。奇怪的是 exec 似乎无法正确找到某些可执行文件的路径。因此,我不得不使用完整的应用程序路径/usr/bin/convert,而不是只使用convert。 要查找完整的应用程序路径,请在终端中键入以下内容:

type -a YOUR_COMMAND

还有一个建议:使用 PHP 的 exec 命令的可选参数,这里是手册中的定义:

string exec ( string $command [, array &$output [, int &$return_var ]] )

我能够在第三个参数的帮助下跟踪我的问题,它返回执行语句的状态。如果您获得 127 作为状态,您肯定必须使用应用程序的完整路径!

【讨论】:

  • 感谢您的回复。让我检查一下,我会用输出回复你
  • 我做了$abc = exec('phantomjs table1.js', $op, $err);$abc 的输出是 11。知道这意味着什么吗?
  • 输出取决于执行的命令,到目前为止我还没有使用 phantomjs 并且无法帮助您。你有 ssh 访问你的服务器吗?如果是,请直接在终端中尝试要从 php 执行的命令。如果它有效,那么您可能从 php 传递了一些错误的选项(文件路径等...),如果没有,那么执行的应用程序有问题,而 php 与它无关
  • +1 向我介绍了exec 的可选参数,这最终帮助我找到了解决方案。
【解决方案4】:

当您使用 exec 或其任何姊妹函数时,请尝试在我的服务器上使用 absolute 路径 -> exec、shell_exec 等 DO NOT WORK 指定文件相对路径。

如果您使用的是共享主机,那当然会有所不同,但类似于:

exec('/var/www/html/script')
//or if youre on a shared server it would be something more like
exec('/user2342jh/www-docs/html')

几年前,我在使用这种类型的东西时经历了一些令人毛骨悚然的情况。

【讨论】:

  • 好的,我听到了,但如果我是你,我会编写一个简单的 PHP 脚本来写入文件以进行测试并检查绝对和相对路径,因为 IK 几乎是 100%可以肯定的是,除非您的主机已将其配置为这样,否则您将需要一个绝对路径。两天前我又做了一次,从 exec 调用了一个 python 脚本。
  • 没关系。我想通了。罪魁祸首是 Filezilla :) 感谢您花时间回答。 +1
最近更新 更多