使用subprocess.call()时,为什么我会在这个简单的Python-CGI上继续获得Error 500?

时间:2014-07-24 11:18:32

标签: python apache cgi subprocess

我尝试使用这个简单的脚本通过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>'

脚本在shell中运行良好(即使使用Apache用户运行它),但是当通过Web服务器运行CGI时,始终会收到错误500。我尝试设置 shell = True ,但这没有什么区别。我在Apache错误日志中收到的唯一消息是:

malformed header from script.

然而,如果我取消注释 标记内的子进程调用,Apache不再抱怨标题,我收到了预期的结果(状态200,但当然没有系统调用)。

我错过了什么吗?我是否配置Apache以允许来自CGI的系统调用?是否必须在本地(.htaccess)或全局(/ etc / apache2 / ...)进行此类配置?关于如何解决这个问题的任何建议?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

这显然是因为子进程产生输出,它是通过调用者的标准输出管道,应该是,但是将直接刷新到输出。因此,实际上,ls的输出最终成为CGI标题,因此出现500错误。

os.popen工作,因为它为你做了预期的stdout管道。

但你也可以这样做(首选):

p = subprocess.Popen('/bin/ls')

(注意:子进程现在异步运行,与原始subprocess.check_call不同。如果需要同步调用(例如,您需要子进程的输出...),您可以执行类似

out, err = p.communicate()
print(out)

等。近似原始的同步控制流程。不要忘记在stdout=PIPE电话中添加Popen()。)