为什么在使用subprocess.call()时我的简单Python-CGI总是出现500错误?
我尝试通过一个简单的Python 2.7 CGI脚本来触发系统调用:
import subprocess
print 'Content-Type:text/html'
print
print '<!DOCTYPE html>'
print '<html>'
print '<body>'
print '<pre>'
try:
subprocess.check_call('/bin/ls')
except:
pass
print '</pre>'
print '</body>'
print '</html>'
这个脚本在命令行中运行得很好(即使是用Apache用户来运行),但是当我通过网络服务器运行CGI时,我总是收到一个500错误。我尝试设置shell=True,但这并没有改变什么。我在Apache的错误日志中只看到这条信息:
malformed header from script.
不过,如果我取消注释标签中的子进程调用,Apache就不再抱怨头部信息了,我得到了预期的结果(状态200,但当然没有系统调用)。
我是不是漏掉了什么?我需要配置Apache以允许CGI进行系统调用吗?这样的配置是要在本地(.htaccess)还是全局(/etc/apache2/...)进行?有没有什么建议可以解决这个问题?任何帮助都很感激。
1 个回答
3
这件事发生的原因是,子进程产生了输出,但这个输出没有通过调用者的标准输出(stdout)传递,反而是直接被输出了。因此,ls
的输出就变成了CGI头信息,这就是导致500错误的原因。
os.popen
能够正常工作,因为它会为你处理好标准输出的传递。
不过,你也可以用另一种(更推荐的)方式来做到这一点:
p = subprocess.Popen('/bin/ls')
(注意:现在子进程是异步运行的,这和你最开始用的 subprocess.check_call
不一样。如果你需要同步调用(比如你需要子进程的输出...),你可以这样做:
out, err = p.communicate()
print(out)
等等,以接近最初的同步控制流程。别忘了在 Popen()
调用中加上 stdout=PIPE
。)