从 PHP 运行 Python 脚本

2024-12-03 08:45:00
admin
原创
146
摘要:问题描述:我正在尝试使用以下命令从 PHP 运行 Python 脚本:exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');但是,PHP 根本没有产生任何输出。错误报告设置为 E_ALL,并且 display_errors 已打开...

问题描述:

我正在尝试使用以下命令从 PHP 运行 Python 脚本:

exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');

但是,PHP 根本没有产生任何输出。错误报告设置为 E_ALL,并且 display_errors 已打开。

这是我尝试过的:

  • 我用python2/usr/bin/python2python2.7不是/usr/bin/python2.7

  • 我还使用了相对路径而不是绝对路径,这也没有改变任何东西。

  • 我尝试使用命令exec, shell_exec, system

但是,如果我跑

if (exec('echo TEST') == 'TEST')
{
    echo 'exec works!';
}

shutdown now尽管它什么也不做,但却运行正常。

PHP 具有访问和执行该文件的权限。

编辑:感谢 Alejandro,我能够修复该问题。如果您遇到同样的问题,请不要忘记您的 Web 服务器可能/希望不是以 root 身份运行。尝试以 Web 服务器的用户或具有类似权限的用户身份登录,然后尝试自己运行命令。


解决方案 1:

在 Ubuntu Server 10.04 上测试。希望它也能在 Arch Linux 上帮到你。

在 PHP 中使用 shell_exec 函数:

通过 shell 执行命令并以字符串形式返回完整的输出。

它返回执行命令的输出,如果发生错误或命令没有产生输出则返回 NULL。

<?php 

$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;

?>

进入 Python 文件test.py,验证第一行中的以下文本:(参见 shebang 解释):

#!/usr/bin/env python

如果您安装了多个版本的 Python,/usr/bin/env 将确保使用的解释器是您环境的 $PATH 中的第一个。另一种方法是硬编码 #!/usr/bin/python 之类的内容;这没问题,但灵活性较差。

在 Unix 中,需要解释的可执行文件可以通过在第一行开头使用 #! 来指示要使用的解释器,后面跟着解释器(以及它可能需要的任何标志)。

当然,如果您谈论的是其他平台,则此规则不适用(但“shebang line”不会造成任何危害,而且如果您将该脚本复制到具有 Unix 基础的平台(例如 Linux、Mac 等),它会有所帮助)。

这适用于在 Unix 中通过使其可执行(chmod +x myscript.py)然后直接运行它:./myscript.py,而不仅仅是 python myscript.py

要使文件在 unix 类型平台上可执行:

chmod +x myscript.py

此外,Python 文件必须具有正确的权限(如果 PHP 脚本在浏览器或 curl 中运行,则用户 www-data / apache 可执行)和/或必须是“可执行的”。此外,.py文件中的所有命令都必须具有正确的权限。

摘自php 手册:

对于那些试图在 unix 类型平台上使用 shell_exec 但似乎无法使其工作的人来说,这只是一个快速提醒。PHP 以系统上的 Web 用户身份执行(对于 Apache 通常是 www),因此您需要确保 Web 用户有权访问您尝试在 shell_exec 命令中使用的任何文件或目录。否则,它似乎不会执行任何操作。

解决方案 2:

我建议passthru直接使用和处理输出缓冲区:

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 

解决方案 3:

如果您想知道命令的返回状态并获取整个stdout输出,您实际上可以使用exec

$command = 'ls';
exec($command, $out, $status);

$out是所有行的数组。$status是返回状态。对于调试非常有用。

如果你还想查看stderr输出,你可以使用proc_open或简单地添加2>&1到你的$command。后者通常足以使事情正常运转,并且“实施”速度更快。

解决方案 4:

根据情况明确使用哪个命令

exec()- 执行外部程序

system()- 执行外部程序并显示输出

passthru()- 执行外部程序并显示原始输出

来源: http: //php.net/manual/en/function.exec.php

解决方案 5:

Alejandro 指出了这一点,并对例外情况(Ubuntu 或 Debian)进行了澄清 - 我没有代表可以添加到答案本身:

sudoers文件:
sudo visudo

添加的例外情况:
www-data ALL=(ALL) NOPASSWD: ALL

解决方案 6:

在我的例子中,我需要在www目录中创建一个名为 的新文件夹scripts。在其中scripts我添加了一个名为 的新文件test.py

然后我使用sudo chown www-data:root scriptssudo chown www-data:root test.py

然后我进入新scripts目录并使用sudo chmod +x test.py

我的 test.py 文件如下所示。请注意不同的 Python 版本:

#!/usr/bin/env python3.5
print("Hello World!")

我现在从 php 执行以下操作:

$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);

您应该看到:Hello World!

解决方案 7:

以上方法看上去比较复杂,可以参考我的方法。

我有这两个文件:

  • 运行.php

  • 创建目录

这里,我创建了一个包含GO按钮的 HTML 页面。每当您按下此按钮时,都会在您指定的路径下创建一个新文件夹。

运行.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
    if(isset($_POST['GO']))
    {
        shell_exec("python /var/www/html/lab/mkdir.py");
        echo"success";
    }
?>

运行代码片段Hide results展开片段

创建目录

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");

解决方案 8:

受到 Alejandro Quiroz 的启发:

<?php 

$command = escapeshellcmd('python test.py');
$output = shell_exec($command);
echo $output;

?>

需要添加Python,不需要路径。

解决方案 9:

上述所有选项都会创建新的系统进程。这是一场性能噩梦。为此,我将 PHP 模块与“透明”的 Python 调用结合在一起。

https://github.com/kirmorozov/runpy

编译起来可能有点棘手,但可以节省系统进程并让您在 PHP 调用之间保持 Python 运行时间。

解决方案 10:

这很简单,但我只是想帮助那些已经遵循 Alejandro 的建议但遇到此错误的人:

sh:blabla.py:未找到命令

如果有人遇到该错误,那么 Alejandro 需要对 php 文件进行一些更改:

$command = escapeshellcmd('python blabla.py');

解决方案 11:

我确实从上面的答案中找到了对我的情况的一些帮助。对我来说,python 文件没有被调用,因为我正在使用一些旧版本的服务器,并且我创建了我正在工作的虚拟环境(包含所有必需的库)。所以我这样调用它:

$command="/home/userName/venv/bin/python /var/www/html/foldername1/foldername2/test.py"." ".$arg1." ".$arg2." ".$arg2; \\pass argument if needed in arg1 etc.

chdir("/var/www/html/folder1/folder2/"); //Changed the directory to where my files were

$output=shell_exec($command); //Execute the command in this directory

chdir("to the original working directory");

希望这对某人有帮助。

附言:由于我们的实验室已授权访问互联网,因此在服务器上单独运行这些文件(python 脚本)时,它们会卡在下载任何模块之间或出现 SSL 错误等,因此只需授予服务器互联网访问权限,它就可以正常工作。然后我从 PHP 调用它。谢谢

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用