繁体   English   中英

PHP如何运行.sh脚本从php网页调用python程序

[英]PHP How can a run a .sh script that calls a python program from a php webpage

我有一个unix .sh脚本,下面运行一个python程序,可能需要10分钟才能完成一些数据处理,它工作正常。 我想从php网页运行此脚本。

run_virt_da_py.sh

#! /bin/bash

# activate virtual environment
cd /Users/data/myproject
source bin/activate

# virtualenv is now active 

python iterate_dir_analyse_files_1.py

echo "data analysis completed ok"

当使用命令行从运行osx 10.6的Apple mac上的终端使用以下命令手动运行该脚本时,以上脚本将“完美”运行。 下面显示了提示,后面是输入的命令。

[~]% cd myproject
[myproject]% source bin/activate
(myproject)[myproject]% sh run_virt_da_py.sh

但是,当我尝试从php运行.sh脚本时,它失败了,以下脚本返回了python程序的第一个echo语句,而没有其他返回。

<html lang="en">
    <head>
        <title>Data_analysis</title>
    </head>
    <body>
    <?php 
     echo " data analysis script started ";
     echo shell_exec('sh   /Users/Data/myproject/run_virt_da_py.sh');
     echo "data analysis script may have completed";
     ?>
    </body>
</html>  

研究我一直在使用,系统,中继,EXEC,对了shell_exec不使用的virtualenv和没有问题的脚本尝试。

  1. 欢迎任何帮助,解决方案,方法或指针。 提前致谢。

一些托管(如GoDaddy)(在共享托管上)在PHP的exec函数中有限制。

另一点是,您需要配置php.ini以增加超时max_execution_time = 1200 ,默认情况下, php.ini有60秒的超时时间,脚本将死掉。

我认为您正在达到自己的脚本,但是您没有等待完成。 尝试在您的php顶部添加一些代码,以编写“ Hello world”文件进行测试。

首先,请确保修改php.ini(如果可能)以延长执行时间。 如果脚本花费的时间太长,则脚本可能会终止。

然后,确保您实际上给了脚本足够的时间来进入shell_exec()

第三,确保禁用安全模式。

第四,确保您的托管服务提供商允许shell_exec()或反引号。

可接受的答案是正确的,但应该指出的是,virtualenv附带了一个名为activate_this.py的脚本,该脚本的存在是为了建立类似虚拟环境的环境以用于Web服务器。 请参阅https://pypi.python.org/pypi/virtualenv并在页面上搜索activate_this.py 然后您就可以做到这一点,而不必从网络服务器启动一个子外壳来修改环境以运行virtualenv的Python解释器。

为什么要在10分钟内提出Web请求? PHP根本不是为了这个目的。 我已经看到了一些后台流程,例如,生成要下载的文件,花费很长时间甚至更长的时间才能完成,用户可以等待它,但是确保它不会被信任,该流程可能由于多种原因而终止(硬件限制,配置限制,网络故障等),甚至更多,无论配置如何,在共享服务器中,服务器都会明确杀死您的进程。

当然,在专用或VPS中,您可以修改指令并允许脚本永久运行,但是问题不在于如何执行,而是是否需要这种方法。 可能是的,我没有说那是绝对禁止的方法,但可能不是。 替代方案可以是:

  1. 让cronjob定期运行您的sh。 当有Web请求时,您可以提供预先计算的数据。
  2. 如果您不希望它生成得太频繁,则可以使其经常运行,但是要检查它是否必须实际上继续运行,可以检查数据库或文件,然后在有请求时从php进行更改该数据库字段或该文件的值,因此cron知道它必须运行。
  3. 让php启动sh,但是在异步线程中,因此php执行立即结束,通知用户数据正在处理,并且实际进程在后台运行

这是一种非常普遍的方法,您可以在许多网站中看到它,例如,在服务器中,如果您需要一些繁重的东西,它们会生成它并在准备就绪时通知您。 或在Facebook中,当您想要备份数据时,也可以这样做。 商业智能系统以及那些分析数据的系统还具有后台流程,而不是生成预先计算的数据,因此用户流程可以是轻量级的。

在企业级应用程序中,我用来处理这种繁重过程的过程是拥有一个用于访问最后生成的数据的链接(告知其日期),一个经常运行的过程以及一个强制启动新过程的链接。马上。

这样,您将获得一个更可靠的系统,并且最大程度地减少了两个用户同时在不同计算机上分析相同数据的机会,这意味着两个过程需要10分钟才能获得相同数据。

更新

如果您真的不需要让用户实时看到过程的结果,那么它会变得更加容易。 我不得不说,由于系统的发展,它可以极大地帮助您保持流程有序并在控制之下,因此非常有帮助。 但是,如果您此时不希望这样做,则可以尝试直接从php启动后台进程。 尝试使用此代码(我在很多年前就使用过,但是我想它会起作用)。 对Unix和Windows服务器均适用。

/**
 * execute $cmd in the background without PHP waiting for it to finish
*/
function execInBackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
        pclose(popen("start /B ". $cmd, "r"));  
    } 
    else { 
        exec($cmd . " > /dev/null &");   
    } 
} 

因此,要启动命令,您必须执行以下操作:

<html lang="en">
<head>
    <title>Data_analysis</title>
</head>
<body>
<?php 
 echo " data analysis script started ";
 echo execInBackground('sh   /Users/Data/myproject/run_virt_da_py.sh');
 echo "data analysis script has been started";
 ?>
</body>
</html>  

当然,由于它是在后台线程中运行的,因此您不直接知道该过程何时完成,因此必须在sh脚本的末尾包括一些特殊的操作,例如使用可能需要的通知过程启动另一个php,例如发送电子邮件,更新数据库等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM