所以我在我的apache服务器上托管了一个网页,当用户通过PHP和AJAX按下按钮时,我试图运行一些python和bash脚本。
现在,我的php文件在python脚本(位于/var/www/html
)上执行,该脚本又执行bash文件(位于root/files
)。
在终端中手动执行此操作时,一切都非常正常。
但当我通过网页尝试这样做时,bash脚本并没有执行。
(我不能将bash脚本放在/var/www/html
中,因为它有将git存储库克隆到服务器的命令,并且它给出了私钥。放在那里时不应该是公共错误)
我已经尝试了在这个答案中添加www-data
到sudoers
的建议,但它仍然没有按预期工作。
如有任何帮助,我们将不胜感激。感谢
PHP文件:
if(isset($_POST['timestamp']))
{
$uid = $_POST['timestamp'];
echo "Please wait while the app is being generated".$uid;
exec("python /var/www/html/appgenserver.py $uid");
appgenserver.py
#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess
arg = sys.argv[1]
# Path to be created
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
os.makedirs(path) #Gets executed
subprocess.call(['/root/Final/clone.sh', path) #Not getting executed
最有可能的是,因为bash脚本本身是不可执行的,它只是一个纯文本文件
您的bash(甚至可能是appgenserver.py
?)可能位于/root
下,并且apache可能以非特权用户(如www-data
)的身份运行,该用户将无法访问您的python脚本,进而无法访问python将运行的bash。
请考虑使用脚本作为参数来调用bash。
#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess
arg = sys.argv[1]
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
os.makedirs(path)
subprocess.call(['/bin/bash', '/root/Final/clone.sh', path)
现在,这不是最漂亮的解决方案
但您之前得到的可能是后台出现的一般性"拒绝权限"错误(请检查您的/var/log/apache/error.log
)。
这样做的目的是将/bin/bash
作为一个子流程启动,第一个参数是要执行的脚本。
但是你在这里没有错误处理,你不能太多地干扰这个过程。
考虑这样做:
import subprocess
handle = subprocess.Popen(['/bin/bash', '/root/Final/clone.sh', 'parameter'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
while handle.poll() is None:
print(handle.stdout.read()) # There's some optimizations here to be done as well so it's not a blocking call etc.
handle.stdout.close()
handle.stdin.close()
最后一个提示是,如果要将内容集成到web前端/后端类型的内容中,则根本不要将其放置在/root/
中
你在找麻烦:)
另一种方法是使用sudo
如果您在PHP中修改exec()
以运行exec("sudo ...")
,并允许web用户在没有密码提示的情况下运行脚本,那么它可能会起作用。
请记住,不建议给www-data
sudo访问权限,而是这样做:
# useradd -m -G www-data -s /bin/bash wwwexec
# echo "myuser ALL=NOPASSWD: /usr/bin/python" >> /etc/sudoers
并将您的PHP脚本更改为具有以下内容:
exec("sudo -u wwwexec python /var/www/html/appgenserver.py $uid");
这样,至少您的整个web服务不会通过默认用户名获得root访问权限。
方法
将您的appgenserver.py
放在/var/www/cgi-bin/
下,并在apache配置中为.py
创建一个CGI挂钩,然后将用户移交给URL,使您有权访问CGI脚本。
这样,一切都应该按照最佳实践,即使在理论上,你可以让你的原始解决方案发挥作用。
例如,本指南应该让您开始学习。