从 PHP 运行 Python 脚本

Posted

技术标签:

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

我正在尝试使用以下命令:

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 身份运行。 尝试以您的网络服务器用户或具有类似权限的用户身份登录,然后尝试自己运行命令。

【问题讨论】:

首先访问此问题***.com/questions/21659637/… 如果未修复并且您遇到类似的问题,如果您遇到导入或 tty 或没有 askpass 无法正常工作的情况,请查看此链接以获取执行它的详细步骤。 ***.com/a/57978771/9470457谢谢!!! 【参考方案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 运行时。

【讨论】:

以上是关于从 PHP 运行 Python 脚本的主要内容,如果未能解决你的问题,请参考以下文章

从 PHP 运行 Python 脚本

无法从raspberry pi 2 ver B中的php脚本运行sudo killall python

从 php 执行的 python 脚本给出错误

如何从python脚本将数组传递给php?

从php.in windows调用python脚本

Python3 脚本在 shell 中运行良好,但在 PHP 中触发 UnicodeEncodeError