【问题标题】:Unexpected behavior when calling a Ruby script via PHP's shell_exec()通过 PHP 的 shell_exec() 调用 Ruby 脚本时出现意外行为
【发布时间】:2010-11-26 08:35:22
【问题描述】:

我有一个 Ruby 脚本,用于执行一些 API 调用/屏幕抓取,但我们的主要应用程序是 PHP。我们的 PHP 应用程序使用 shell_exec() 来调用 Ruby 脚本。

ruby 脚本在从命令行调用时效果很好——但是当通过 PHP 的 shell exec 调用时,它会随机提前退出。

这是一个 Ruby 脚本的示例:

#!/usr/bin/env ruby
require 'rubygems'
require 'mysql'
require 'net/http'
require 'open-uri'
require 'uri'
require 'cgi'
require 'fileutils'

# Bunch of code here ... works fine 
somePath = 'http://foo.com/bar.php'
# Seems to always exit when I do a Net::HTTP or open-uri call 
post = Net::HTTP.post_form(URI.parse(somePath),{'id'=>ID,'q'=>'some query'})
data = post.body
# OR 
data = open(somePath).read
# More code here ... 

所以,到目前为止,我所能推断的是,当我尝试通过 net/http 或 open-uri 调用获取/读取外部 URL 时,它总是退出。我正在抓取的页面可以接受 POST 或 GET 请求,但它似乎正在以任何一种方式退出。

我在调用 shell_exec 后使用 PHP 输出结果,但没有错误消息或退出。我的 Ruby 脚本确实输出了带有“puts ....”的消息。这可能是个问题吗(我在想“不”,因为它不会在之前的 puts 消息中退出)?

同样,当从 shell 调用时它工作正常。这几乎就像 shell_exec 调用没有等待 net/http 调用完成一样。

有什么想法吗?

【问题讨论】:

    标签: php ruby shell


    【解决方案1】:

    对此我不确定,但鉴于您的解释,这听起来很合理,您是否看过 proc_open:

    http://us3.php.net/proc_open

    【讨论】:

    • proc_open 与 shell_exec 有何不同?
    【解决方案2】:

    Ruby 的open-uri 需要tempfile,所以我猜您运行ruby 脚本和运行它的Web 服务器之间存在文件所有权冲突。 Web服务器可以使用tempfile创建临时文件吗?

    【讨论】:

    • 我将如何测试它?看看我能不能在 Ruby 中 shell_exec() 一个 tempfile 命令?
    • 好的,我用一个创建临时文件的 ruby​​ 脚本进行了测试,休眠 60 秒,然后关闭。我用 PHP 的 shell_exec() 运行它,它运行良好。该文件在运行时显示在 /tmp 中。这似乎不是问题,但我很欣赏这个想法。谢谢。
    【解决方案3】:

    仅供参考,我从未真正发现为什么会发生这种情况。我能推断出的最好的结果是某种类型的权限问题正在阻止 Ruby 的 open-uri 命令正常工作。

    我选择在 db 表中对这些作业进行排队,并定期通过 cron 运行我的 ruby​​ 脚本。当 ruby​​ 脚本以 root/sudo 权限运行时,一切似乎都运行良好。

    【讨论】:

    • 永远不要使用 root。考虑一个替代方案。
    【解决方案4】:

    在 Linux 终端上运行: sudo -H -u <user> bash -c <your code> 其中<user> 是 Apache 的用户。

    要查找 Apache 的用户,您可以在代码中echo("shell_exec(\"whoami\")"); 并在浏览器上运行它。 whoami 适用于 Linux 和 Windows,但如果您在 Windows 下,则 Apache 默认用户是您的用户。无论如何你都可以测试它以防万一,但我不知道如何在 Windows 上运行代码,就像运行它的 Apache 一样。

    之后,您可以了解正在发生的事情。在大多数情况下,问题是 Apache 的根文件夹与操作系统的文件夹不同。因此,当您使用绝对路径运行命令时,操作系统会考虑/,Apache 会考虑 Linux 上的/var/www/html,Xampp(Linux) 上的/opt/lampp/htdocs 和 Xampp(Windows) 上的C:/xampp/htdocs。你明白我的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2020-10-09
      • 2018-08-13
      相关资源
      最近更新 更多