我正在运行 Apache/2.4.10 (Raspbian),并且我正在使用 python 作为 CGI。 但是当我尝试在简单代码中使用 os.system 时,我收到此格式错误的 header 错误:
[Wed Aug 31 17:10:05.715740 2016] [cgid:error] [pid 3103:tid 1929376816] [client 192.168.0.106:59277] malformed header from script'play.cgi': Bad header: code.cgi
这是来自 play.cgi 的代码:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import cgi
import os
print('Content-type: text/html')
print('')
os.system('ls')
奇怪的是,如果我删除 os.system 行,它会神秘地再次开始工作。我尝试使用 popen 代替,同样的问题。我试图在一些代码中掩盖它,更改文件名,不同的编码,甚至 time.sleep,但这些都不起作用。
最奇怪的是,它在更复杂的代码中工作得很好。
最佳答案
要了解问题发生的原因,请尝试启动脚本
python webls.py > output
然后用一些文本编辑器打开输出
。您会注意到您的 Content-type: text/html
最终位于文件的底部,这当然是错误的。
发生这种情况是因为在 Python 代码的输出中合并了 os.system
的内容,从而搞砸了(因为想一想:你的 print(...)
是累积的并在适当的时候分块刷新,而 os.system() 突然打印数据,并且因为它是 os.system 事务,所以仅刷新其结果(这也是您这样做的原因)如果输出是控制台,则看不到问题))。解决方案是在打印标题后刷新输出。您应该将代码更改为
#!/usr/bin/python
import cgi
import os
import sys
print 'Content-type: text/html'
print ''
sys.stdout.flush()
os.system('ls')
虽然这是一个修复,但如果您需要将控制台命令的输出合并到网页内容中并使用 os.system 来实现这一点,您就知道自己正在做一些非常错误的事情。您应该考虑做几件事。这些解决方案按推荐程度排序(从糟糕到良好):
-使用输入/输出重定向。将 ls
的输出保存到文件并在 Python 代码中读取它:
os.system('ls > /tmp/lsoutput')
print open('/tmp/lsoutput', 'r').read()
-使用子进程。它允许您捕获控制台程序的输出并在 python 代码中使用它(示例来自 python getoutput() equivalent in subprocess )
import subprocess
process = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE)
out, err = process.communicate()
print(out)
-根本不要调用外部程序,这是一件坏事。如果您需要文件列表,请使用 Python 函数
import os
for filename in os.listdir('.'):
print filename
关于Python CGI os.system 导致 header 格式错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39255498/