问题:从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/python2
而python2.7
不是/usr/bin/python2.7
- 我还使用了相对路径而不是绝对路径,它也没有改变任何东西。
- 我试着使用的命令
exec
,shell_exec
,system
。
但是,如果我跑步
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
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
上述方法似乎很复杂。使用我的方法作为参考。
我有两个文件:
在这里,我创建了一个包含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:
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');