从PHP运行Python脚本

问题:从PHP运行Python脚本

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

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有权访问和执行文件。

编辑:感谢亚历杭德罗,我能够解决此问题。如果您遇到相同的问题,请不要忘记您的Web服务器可能/希望不是以root用户身份运行。尝试以您的Web服务器用户或具有类似权限的用户身份登录,然后尝试自己运行命令。

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.


回答 0

在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文件必须具有正确的特权(如果PHP脚本在浏览器或curl中运行,则对用户www-data / apache的执行)和/或必须是“可执行的”。此外,所有进入.py文件的命令都必须具有正确的特权:

采取从PHP手册

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

为了使在UNIX型平台上的可执行文件

chmod +x myscript.py

Tested on Ubuntu Server 10.04. I hope it helps you also on Arch Linux.

In PHP use shell_exec function:

Execute command via shell and return the complete output as a string.

It returns the output from the executed command or NULL if an error occurred or the command produces no output.

<?php 

$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;

?>

In Python file test.py, verify this text in first line: (see shebang explain):

#!/usr/bin/env python

Also Python file must have correct privileges (execution for user www-data / apache if PHP script runs in browser or curl) and/or must be “executable”. Also all commands into .py file must have correct privileges:

Taken from php manual:

Just a quick reminder for those trying to use shell_exec on a unix-type platform and can’t seem to get it to work. PHP executes as the web user on the system (generally www for Apache), so you need to make sure that the web user has rights to whatever files or directories that you are trying to use in the shell_exec command. Other wise, it won’t appear to be doing anything.

To make executable a file on unix-type platforms:

chmod +x myscript.py

回答 1

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

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

I recommend using passthru and handling the output buffer directly:

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

回答 2

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

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

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

如果您还想查看stderr输出,则可以使用proc_open或直接将其添加2>&1到中$command。后者通常足以使事情正常运行,并更快地实现。

If you want to know the return status of the command and get the entire stdout output you can actually use exec:

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

$out is an array of all lines. $status is the return status. Very useful for debugging.

If you also want to see the stderr output you can either play with proc_open or simply add 2>&1 to your $command. The latter is often sufficient to get things working and way faster to “implement”.


回答 3

亚历杭德罗(Alejandro)钉上了钉子,为异常(Ubuntu或Debian)添加了说明-我没有代表要添加到答案本身:

sudoers文件: sudo visudo

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

Alejandro nailed it, adding clarification to the exception (Ubuntu or Debian) – I don’t have the rep to add to the answer itself:

sudoers file: sudo visudo

exception added: www-data ALL=(ALL) NOPASSWD: ALL


回答 4

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

exec() -执行外部程序

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

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

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

To clarify which command to use based on the situation

exec() – Execute an external program

system() – Execute an external program and display the output

passthru() – Execute an external program and display raw output

Source: http://php.net/manual/en/function.exec.php


回答 5

就我而言,我需要在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!

In my case I needed to create a new folder in the www directory called scripts. Within scripts I added a new file called test.py.

I then used sudo chown www-data:root scripts and sudo chown www-data:root test.py.

Then I went to the new scripts directory and used sudo chmod +x test.py.

My test.py file it looks like this. Note the different Python version:

#!/usr/bin/env python3.5
print("Hello World!")

From php I now do this:

$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);

And you should see: Hello World!


回答 6

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

我有两个文件:

  • 运行.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");

The above methods seem to be complex. Use my method as a reference.

I have these two files:

  • run.php

  • mkdir.py

Here, I’ve created an HTML page which contains a GO button. Whenever you press this button a new folder will be created in directory whose path you have mentioned.

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

回答 7

这很琐碎,但只是想帮助已经遵循亚历杭德罗建议但遇到此错误的任何人:

sh:blabla.py:找不到命令

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

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

This is so trivial, but just wanted to help anyone who already followed along Alejandro’s suggestion but encountered this error:

sh: blabla.py: command not found

If anyone encountered that error, then a little change needs to be made to the php file by Alejandro:

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