【问题标题】:Running a Python script from PHP从 PHP 运行 Python 脚本
【发布时间】:2013-11-13 03:43:03
【问题描述】:

我正在尝试使用以下命令从 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
  • 我还使用了相对路径而不是绝对路径,它也没有改变任何东西。
  • 我尝试使用命令execshell_execsystem

但是,如果我运行

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

shutdown now 什么都不做时,它工作得非常好。

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

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

【问题讨论】:

标签: php python linux exec archlinux


【解决方案1】:

在 Ubuntu Server 10.04 上测试。我希望它对您在 Arch Linux 上也有帮助。

在 PHP 中 use shell_exec function:

通过 shell 执行命令并将完整的输出作为字符串返回。

返回执行命令的输出,如果出错则返回 NULL 发生或该命令不产生输出。

<?php 

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

?>

进入 Python 文件test.py,验证第一行的文本:(see shebang explain)

#!/usr/bin/env python

如果您安装了多个版本的 Python,/usr/bin/env 将 确保使用的解释器是您环境中的第一个解释器 $路径。另一种方法是硬编码类似的东西 #!/usr/bin/python;没关系,但不太灵活。

在 Unix 中,用于解释的可执行文件可以指示 有一个 #! 使用什么解释器在第一行的开头, 其次是解释器(以及它可能需要的任何标志)。

如果你说的是其他平台,当然,这条规则不 申请(但是“shebang line”没有害处,如果你有帮助的话 将该脚本复制到具有 Unix 基础的平台,例如 Linux, Mac 等)。

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

make executable a file on unix-type platforms

chmod +x myscript.py

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

拍摄from php manual

对于那些试图在 unix 类型的平台,似乎无法让它工作。 PHP 执行为 系统上的网络用户(对于 Apache 通常是 www),所以你需要 确保网络用户有权访问任何文件或 您尝试在 shell_exec 命令中使用的目录。 否则,它似乎不会做任何事情。

【讨论】:

  • 谢谢你,成功了!还有一个问题 - Apache 用户无法在 Python 脚本中执行命令,但我能够通过使用 sudo 并将我的脚本的异常添加到 sudoers 文件来解决这个问题。再次感谢! :)
  • 对于 OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); 或:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
  • 有点不同,但帮助我在​​ debian 中进行诊断:echo(exec("/usr/bin/python3 magic.py));
【解决方案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&gt;&amp;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

        【讨论】:

        • 将 www-data 添加到 sudoers 似乎没有效果,并为 apache 提供了它需要的更多权限。授予您正在执行的脚本的 www-data 权限就足够了。
        • 很酷的想法,但肯定会使您的系统易受攻击。我同意@JasonRDalton
        【解决方案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】:

          上述方法似乎很复杂。参考我的方法。

          我有这两个文件:

          • run.php

          • mkdir.py

          在这里,我创建了一个包含 GO 按钮的 HTML 页面。每当您按下此按钮时,将在您提到的路径的目录中创建一个新文件夹。

          run.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";
          	}
          ?>

          mkdir.py

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

          【讨论】:

            【解决方案8】:

            这太琐碎了,但只是想帮助任何已经遵循 Alejandro 的建议但遇到此错误的人:

            sh: blabla.py: 找不到命令

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

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

            【讨论】:

              【解决方案9】:

              受亚历杭德罗·奎罗斯的启发:

              <?php 
              
              $command = escapeshellcmd('python test.py');
              $output = shell_exec($command);
              echo $output;
              
              ?>
              

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

              【讨论】:

                【解决方案10】:

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

                https://github.com/kirmorozov/runpy

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

                【讨论】:

                  猜你喜欢
                  • 2012-06-11
                  • 2019-05-27
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-08-19
                  • 2017-05-22
                  相关资源
                  最近更新 更多