从 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/python2
和python2.7
而不是/usr/bin/python2.7
我还使用了相对路径而不是绝对路径,它也没有改变任何东西。
我尝试使用命令exec
、shell_exec
、system
。
但是,如果我运行
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>&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 scripts
和sudo 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 脚本的主要内容,如果未能解决你的问题,请参考以下文章