我正在尝试使用以下命令从PHP运行Python脚本:
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 具有访问和执行该文件的权限。
编辑:感谢亚历杭德罗,我能够解决问题。如果您有同样的问题,请不要忘记您的网络服务器可能/希望不会以 root 身份运行。尝试以 Web 服务器的用户或具有类似权限的用户身份登录,并尝试自己运行命令。
在 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中,要解释的可执行文件可以指示使用什么解释器来使用#!在第一行的开头,后跟解释器(以及可能需要的任何标志)。
当然,如果您谈论的是其他平台,则此规则不会申请(但"社邦线"没有坏处,如果你有的话会有所帮助将该脚本复制到具有 Unix 基础的平台,例如 Linux,苹果等)。
这适用于在 Unix 中通过使其可执行来运行它的情况(chmod +x myscript.py),然后直接运行它:./myscript.py,而不仅仅是蟒蛇 myscript.py
要在 unix 类型的平台上使文件可执行,请执行以下操作:
chmod +x myscript.py
此外,Python文件必须具有正确的权限(如果PHP脚本在浏览器或curl中运行,则为用户www-data/apache执行)和/或必须是"可执行的"。此外,.py
文件中的所有命令都必须具有正确的权限。
摘自 php 手册:
对于那些试图shell_exec在Unix类型的平台,似乎无法使其工作。PHP 执行方式为系统上的Web用户(通常是Apache的www),所以你需要确保 Web 用户有权访问任何文件或您尝试在 shell_exec 命令中使用的目录。其他明智的是,它似乎不会做任何事情。
我建议使用passthru
并直接处理输出缓冲区:
ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean();
如果你想知道命令的返回状态并获取整个stdout
输出,你可以实际使用exec
:
$command = 'ls';
exec($command, $out, $status);
$out
是所有行的数组。 $status
是返回状态。对于调试非常有用。
如果您还想查看stderr
输出,您可以使用proc_open播放,也可以简单地将2>&1
添加到您的$command
中。后者通常足以使事情正常工作,并且更快地"实施"。
根据情况阐明使用哪个命令
exec()
- 执行外部程序
system()
- 执行外部程序并显示输出
passthru()
- 执行外部程序并显示原始输出
来源: http://php.net/manual/en/function.exec.php
亚历杭德罗钉住了它,为例外(Ubuntu 或 Debian)添加了澄清 - 我没有代表添加到答案本身:
苏多尔文件: sudo visudo
添加了异常: www-data ALL=(ALL) NOPASSWD: ALL
就我而言,我需要在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);
你应该看到:你好世界!
上述方法似乎很复杂。使用我的方法作为参考。
我有两个文件:
-
跑.php
-
mkdir.py
在这里,我创建了一个包含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";
}
?>
mkdir.py
#!/usr/bin/env python
import os
os.makedirs("thisfolder");
灵感来自亚历杭德罗·奎罗兹:
<?php
$command = escapeshellcmd('python test.py');
$output = shell_exec($command);
echo $output;
?>
需要添加 Python,并且不需要路径。
这太微不足道了,但只是想帮助任何已经遵循亚历杭德罗的建议但遇到此错误的人:
sh:blabla.py:找不到命令
如果有人遇到该错误,则需要对 Alejandro 的 php 文件进行一些更改:
$command = escapeshellcmd('python blabla.py');
上述所有选项都会创建新的系统进程。这是一场表演噩梦。为此,我将PHP模块与对Python的"透明"调用拼接在一起。
https://github.com/kirmorozov/runpy
编译起来可能很棘手,但可以节省系统进程,并允许您在PHP调用之间保持Python运行时。
我确实从上面的答案中找到了一些帮助。对我来说,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");
希望这对某人有所帮助。
PS:由于我们在实验室中授权访问互联网,因此在服务器上单独运行这些文件(python脚本)时,它们被困在下载任何模块或给出SSL错误等之间,所以只需向服务器提供互联网访问权限,它就可以工作了。然后我从PHP调用它。谢谢