从 PHP 运行 Python 脚本

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

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

然而,PHP 根本不会产生任何输出。错误报告设置为 E _ ALL,display _ Error 处于打开状态。

以下是我试过的方法:

  • 我用 python2/usr/bin/python2python2.7代替了 /usr/bin/python2.7
  • 我还使用了相对路径而不是绝对路径,这也不会改变任何东西。
  • 我尝试使用命令 execshell_execsystem

但是,如果我逃跑呢

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

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

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

编辑: 多亏了亚历杭德罗,我才能解决这个问题。如果您有同样的问题,不要忘记您的 webserver 可能/希望不以 root 用户身份运行。尝试作为您的网络服务器的用户或具有类似权限的用户登录,并尝试自己运行命令。

438681 次浏览

在 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中,验证第一行中的文本: (见解释):

#!/usr/bin/env python

如果安装了多个版本的 Python,/usr/bin/env 将 确保所使用的解释程序是环境中的第一个解释程序 $PATH. 另一种方法是硬编码 /usr/bin/python; 这没问题,但不够灵活。

在 Unix 中,一个需要解释的可执行文件可以表明 通过在第一行的开头使用 # ! 来使用什么解释器, 然后是解释器(以及它可能需要的任何标志)。

如果你在谈论其他平台,当然,这个规则不是 适用(但是“ Shebang line”没有坏处,而且如果你曾经 将该脚本复制到基于 Unix 的平台,例如 Linux, 麦克等等)。

如果在 Unix 中运行它,使其成为可执行文件,那么就会出现这种情况 (chmod + x myscript.py) ,然后直接运行它: ./myscript.py, 而不仅仅是 python myscript.py

在 unix 类型的平台上创建可执行文件:

chmod +x myscript.py

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

拍摄 来自 php 手册:

对于那些试图在 Unix 类型的平台,似乎不能让它工作。 PHP 执行为 系统上的 web 用户(通常是 Apache 的 www) ,因此您需要 确保网络用户有权使用任何文件或 您试图在 shell _ exec 命令中使用的目录。 否则,它看起来什么也做不了。

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

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

Alejandro 搞定了这个问题,为这个异常(Ubuntu 或 Debian)添加了说明——我没有代表来给这个问题添加答案:

Sudoers 文件: sudo visudo

补充例外情况: www-data ALL=(ALL) NOPASSWD: ALL

如果你想知道命令的返回状态并得到整个 stdout输出,可以实际上使用的是 exec:

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

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

如果你也想看到 stderr的输出,你可以使用 Proc _ open或者简单地将 2>&1添加到你的 $command。后者通常足以让事情运转起来,并且更快地“实现”。

在我的例子中,我需要在 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!

这是如此微不足道,但只是想帮助那些已经遵循亚历杭德罗的建议,但遇到这个错误的人:

Sh: blabla.py: 命令未找到

如果有人遇到这个错误,那么 Alejandro 需要对 php 文件做一点小小的修改:

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

上面的方法看起来很复杂,请参考我的方法。

我有两个文件:

  • 快跑

  • Mkdir.py

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

快跑

<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");

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

执行一个外部程序

执行外部程序并显示输出

执行外部程序并显示原始输出

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

灵感来自 Alejandro Quiroz:

<?php


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


?>

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

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

Https://github.com/kirmorozov/runpy

它可能难以编译,但是可以节省系统进程,并且允许在 PHP 调用之间保持 Python 运行时。