内部服务器错误 - Python CGI
我现在正在写一个CGI脚本,最终目的是运行一个Java程序,然后跳转到另一个页面。不过,当我尝试运行这个Java程序时,CGI就出现了500内部服务器错误。我试过用os.system("[command]")、call(["command"])和subprocess.Popen("command"),这三种方法都出现了同样的问题。任何建议都非常感谢。
编辑 此外,apache的日志几乎没有给我提供任何信息,只说有一个无效的头部。
编辑
#!/usr/bin/python
# Import the CGI module
import cgi
import random
import os
import sys
import re
import subprocess
# Required header that tells the browser how to render the HTML.
print "Content-Type: text/html\n\n"
form = cgi.FieldStorage()
userID = random.random()
print "<html>"
print "<title>Results</title>"
print "<body>"
command = "java [classname] "
user_id = random.randint(0, sys.maxint)
command += str(user_id) + " "
command += re.sub(r'\s', '', form['key0'].value) + " "
command += form['key1'].value + " "
command += form['key2'].value + " "
command += form['key3'].value + " " if form.has_key('key3') else "0 "
## This is where the problem exists
#os.system("ls -l")
#call(["ls", "-l"])
#p = subprocess.Popen(command)
## End of Problem
print command
print "<br>"
print "Redirecting..."
print "<meta http-equiv='refresh' content='0;url=",
print "http://192.168.1.41/Path/",
print user_id,
print ".html' />"
print "</body>"
print "</html>"
整个命令没有显示出来,但我相信它构建得没问题,因为我可以把打印出来的命令复制到终端中运行,结果运行得很好。这个命令就是java [classname] [9 args]
这个Java代码在Python代码之外运行得很顺利,它只生成一个.png文件和一个包含这个.png的.html文件。文件的名字是[user_id].html,所以才会有跳转。
如果只注释掉进程命令,内部服务器错误就不会出现。
编辑 最后我放弃了,转而使用PHP来执行这个脚本。感谢大家的帮助!
2 个回答
你有没有试过:
import cgitb
cgitb.enable()
在浏览器中查看更有意义的错误信息,也就是 Python 的错误提示。
或者
在你的服务器上通过命令行运行你的脚本,看看 Python 是否返回了错误,如果有的话,这样做能否帮助你找出问题所在?
或者
把你在 Python 脚本中调用 Java 的结果以 HTML 格式打印出来?
## This is where the problem exists #os.system("ls -l") #call(["ls", "-l"]) #p = subprocess.Popen(command) ## End of Problem
重点关注
subprocess.Popen
。其他的都可以扔掉,永远不要用。它们都是坏主意。如果
subprocess.Popen(command)
在一个独立的短 Python 脚本中确实能正常工作,那么你需要检查一下 Apache 的 CGI-bin 用户名是否有权限去执行这个命令。记住,Apache 不是以你的身份运行的,它是以一个独立的“人”的身份运行,权限也不同。你的 Java 命令可能会把数据输出到 sys.stdout 或者 sys.stderr。如果是这样,这些输出会被 Apache 接收到。理想情况下,应该有一些内容已经通过 sys.stdout 发送给 Apache,包含了正确的头信息,这样一切就正常了。
不过,由于数据的缓冲方式,Apache 可能没有看到可用的响应,这样 Java 的输出就会让人困惑。
我建议你使用 mod_wsgi
而不是 CGI,因为它更容易控制。
我还建议你把子进程的输出保存到一个文件中,然后再把这个文件的内容复制到 sys.stdout,这样 Apache 就不会被 Java 子进程搞混了。