136

I'm trying to run a Python script from PHP using the following command:

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

However, PHP simply doesn't produce any output. Error reporting is set to E_ALL and display_errors is on.

Here's what I've tried:

  • I used python2, /usr/bin/python2 and python2.7 instead of /usr/bin/python2.7
  • I also used a relative path instead of an absolute path which didn't change anything either.
  • I tried using the commands exec, shell_exec, system.

However, if I run

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

it works perfectly fine while shutdown now doesn't do anything.

PHP has the permissions to access and execute the file.

EDIT: Thanks to Alejandro, I was able to fix the problem. If you have the same problem, don't forget that your webserver probably/hopefully doesn't run as root. Try logging in as your webserver's user or a user with similar permissions and try to run the commands yourself.

4

10 回答 10

193

在 Ubuntu 服务器 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 中,要解释的可执行文件可以通过 #! 来指示要使用的解释器。在第一行的开头,然后是解释器(以及它可能需要的任何标志)。

当然,如果您在谈论其他平台,则此规则不适用(但“shebang 行”没有害处,如果您将该脚本复制到具有 Unix 基础的平台(例如 Linux、Mac)会有所帮助, ETC)。

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

在 unix 类型平台上生成可执行文件

chmod +x myscript.py

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

取自php 手册

只是对那些试图在 unix 类型平台上使用 shell_exec 并且似乎无法使其工作的人的快速提醒。PHP 在系统上以 Web 用户身份执行(对于 Apache 通常为 www),因此您需要确保 Web 用户有权访问您尝试在 shell_exec 命令中使用的任何文件或目录。否则,它似乎不会做任何事情。

于 2013-11-01T22:34:58.963 回答
28

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

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 
于 2013-11-01T22:38:27.893 回答
16

如果您想知道命令的返回状态并获取整个stdout输出,您可以实际使用exec

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

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

如果您还想查看stderr输出,您可以使用proc_open或简单地添加2>&1到您的$command. 后者通常足以让事情正常工作并更快地“实施”。

于 2015-09-18T18:19:01.317 回答
9

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

exec()- 执行外部程序

system()- 执行外部程序并显示输出

passthru()- 执行外部程序并显示原始输出

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

于 2018-10-07T15:59:18.227 回答
8

亚历杭德罗(Alejandro)确定了这一点,对异常(Ubuntu或Debian)进行了澄清-我没有代表可以添加到答案本身:

sudoers 文件: sudo visudo

添加了异常: www-data ALL=(ALL) NOPASSWD: ALL

于 2014-07-27T22:19:04.393 回答
8

在我的情况下,我需要在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!

于 2018-03-02T17:43:47.907 回答
5

上述方法似乎很复杂。使用我的方法作为参考。

我有这两个文件:

  • 运行.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");
于 2018-06-20T11:08:19.590 回答
2

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

sh:blabla.py:找不到命令

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

$command = escapeshellcmd('python blabla.py');
于 2018-05-29T17:37:41.613 回答
1

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

https://github.com/kirmorozov/runpy

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

于 2020-11-30T21:52:42.353 回答
1

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

<?php 

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

?>

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

于 2020-08-16T20:55:40.783 回答