Python CGI os.system 导致标头格式错误 [英] Python CGI os.system causing malformed header

查看:34
本文介绍了Python CGI os.system 导致标头格式错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am running Apache/2.4.10 (Raspbian) and I am using python for CGI. But when I try to use os.system in simple code I get this malformed header error:

[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 中的代码:

Here is the code from 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,这些都没有奏效.

The strange thing is that if I remove the os.system line it mysteriously starts working again. I have tried using popen instead, same problem. I have tried to obscure it in some code,change file name, different encodings and even time.sleep, none of those worked.

最奇怪的是它在更复杂的代码中运行得非常好.

The strangest thing is that it works perfectly fine in a more complicated code.

推荐答案

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

To see why the problem happened, try launching your script

python webls.py > output

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

And than open output with some text editor. You will notice that your Content-type: text/html ended up being in the bottom of the file, which, of course, is wrong.

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

That happens because incorporating outout of your os.system in output of Python code screws thing up (because think about it: your print(...) is accumulated and flushed in blocks when appropriate, while os.system() abruptively prints data and because it is os.system transacton, flushes only its result (which is also why you do not see the problem if outout is to console)). The solution is to flush output after printing headers. You should change your code to

#!/usr/bin/python

import cgi
import os
import sys

print 'Content-type: text/html'
print ''

sys.stdout.flush()

os.system('ls')

<小时>

虽然这是一个修复,但如果您需要将控制台命令的输出合并到网页内容中并使用 os.system 来实现,那么您就知道自己在做一些非常错误的事情.您应该考虑做几件事.这些解决方案按推荐程度排序(从糟糕到好):


Although that is a fix, you know you are doing something terribly wrong if you need to incorporate output of your console command to the content of the web page and use os.system for that. There are several things you should consider doing. These solutions are sorted by how recommended they are (from crappy to good):

-使用输入/输出重定向.将 ls 的输出保存到文件并在您的 Python 代码中读取它:

-Use redirection of input/output. Save output of ls to file and read it in your Python code:

os.system('ls > /tmp/lsoutput')
print open('/tmp/lsoutput', 'r').read()

-使用子进程.它允许您捕获控制台程序的输出并在您的 Python 代码中使用它(示例来自 python getoutput() 等价于子进程)

-Use subprocess. It allows you to capture output of console program and use it in your python code (example from python getoutput() equivalent in subprocess)

import subprocess
process = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE)
out, err = process.communicate()
print(out)

-根本不要调用外部程序,这是一件坏事.如果需要文件列表,请改用 Python 函数

-Do not call external programs at all, this is a bad thing to do. If you need a list of files, use Python functions instead

import os

for filename in os.listdir('.'):
    print filename

这篇关于Python CGI os.system 导致标头格式错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆