【问题标题】:Python CGI os.system causing malformed headerPython CGI os.system 导致格式错误的标头
【发布时间】:2017-01-08 09:24:08
【问题描述】:

我正在运行 Apache/2.4.10 (Raspbian),并且正在使用 python 进行 CGI。 但是当我尝试在简单代码中使用 os.system 时,我得到了这个格式错误的标头错误:

[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,这些都不起作用。

最奇怪的是它在更复杂的代码中也能正常工作。

【问题讨论】:

  • 通常最好使用subprocess 而不是 os.system,这样您就可以更好地控制输入/输出。此外,您可能希望使用 WSGI 而不是 CGI,因为它不占用标准输入和标准输出。

标签: python apache cgi


【解决方案1】:

要查看问题发生的原因,请尝试启动您的脚本

python webls.py > output

然后用一些文本编辑器打开output。您会注意到您的 Content-type: text/html 最终位于文件的底部,这当然是错误的。

发生这种情况是因为将您的os.system 输出合并到 Python 代码的输出中会搞砸(因为考虑一下:您的 print(...) 在适当的时候以块的形式累积和刷新,而 os.system() 会突然打印数据,因为它是 os.system 事务,只刷新它的结果(这也是为什么如果 outout 是控制台,你看不到问题的原因)。解决方案是在打印标题后刷新输出。您应该将代码更改为

#!/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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2014-01-08
    • 1970-01-01
    相关资源
    最近更新 更多