Python文件存储服务器IOError: [Errno 32] Broken pipe错误,,# -*- coding


# -*- coding: utf-8 -*-#!/usr/bin/python26from SimpleHTTPServer import SimpleHTTPRequestHandler  from BaseHTTPServer import BaseHTTPRequestHandler  from BaseHTTPServer import HTTPServer  import SocketServerimport cgiimport osimport loggingimport threadclass MyHTTPRequestHandler( BaseHTTPRequestHandler ):      def do_GET( self ):          pass    def do_POST(self):        # 创建线程执行命令            thread.start_new_thread(self.callscript, ('cd /home/www/man-sphinx/docs.500.com/html && /usr/bin/sphinx-build -c ./  ./  /home/www/html/docs.500.com/html/',))        form = cgi.FieldStorage(  # cgi.FieldStorage实例效果类似一个字典,包含键-值和len等内置函数            fp=self.rfile,            headers=self.headers,            environ={'REQUEST_METHOD':'POST',                     'CONTENT_TYPE':self.headers['Content-Type'],                     })        self.send_response(200)        self.end_headers()        self.wfile.write('Client: %s\n' % str(self.client_address))        # self.wfile.write('User-agent: %s\n' % str(self.headers['user-agent']))        # self.wfile.write('Path: %s\n' % self.path)        params = {}        for field in form.keys():            params[field] = form[field].value        filepath = params.get('f')        data = params.get('d')        code = params.get('c')        user = params.get('u')        try:            result = self.filesave(filepath, data, code, user)        except Exception, e:            result = 'Error in filesave:%s' % e        finally:            self.wfile.write(result)        # self.callscript('cd /home/www/man-sphinx/docs.500.com/html && /usr/bin/sphinx-build -c ./  ./  /home/www/html/docs.500.com/html/')    def filesave(self, filepath, data, code, user):        if (filepath and data and code and user) is None:            return 'Params uncomplete!\n'        path = '/'.join(filepath.split('/')[:-1])        name = filepath.split('/')[-1]        if not os.path.exists(path):            os.makedirs(path)        f = open(filepath, 'w')        f.write(data.decode(code).encode('utf-8'))        f.close()        self.log(filepath, user)        return 'Filesaved in %s' % filepath    def callscript(self, command):        try:            os.popen(command)  # 报错        except Exception,e:            print 'Error in CallScript:%s' % e    def log(self, filepath, user):        pass    def do_HEAD( self ):          pass  if __name__ == '__main__':      port = 28080      handler = SimpleHTTPRequestHandler      #httpd = SocketServer.TCPServer(("", port ), handler )      httpd = HTTPServer(('', port ), MyHTTPRequestHandler)      print "Server is running at port", port      httpd.serve_forever() 

这是一个简单的文件存储服务器,文件存储工作正常,但是我希望接受post请求的时候开启一个线程去刷新文件目录,问题是在callscript函数里使用os.popen()会报题示的错误,如果改成os.system()就不会. 详细错误:

# Sphinx version: 1.1.3# Python version: 2.6.5# Docutils version: 0.11 release# Jinja2 version: 2.7.1Traceback (most recent call last):  File "/usr/lib/python2.6/site-packages/Sphinx-1.1.3-py2.6.egg/sphinx/cmdline.py", line 188, in main    warningiserror, tags)  File "/usr/lib/python2.6/site-packages/Sphinx-1.1.3-py2.6.egg/sphinx/application.py", line 94, in __init__    self.info(bold('Running Sphinx v%s' % sphinx.__version__))  File "/usr/lib/python2.6/site-packages/Sphinx-1.1.3-py2.6.egg/sphinx/application.py", line 238, in info    self._status.flush()IOError: [Errno 32] Broken pipe

这是为什么呢?

你要知道 popen 是干什么的。它会把子进程的标准输出通过管道连接到父进程。所以你要在父进程里读取该管道,而如果直接关闭的话,子进程写管道的时候就会得到「Broken pipe」的错误了。如果不读取管道的话,子进程向管道中写入超过管道缓冲区的内容的时候会被阻塞。

os.popen 函数返回一个 file-like 对象。你直接 .read() 可以读取管道中所有的数据。

如果你只是不想子进程显示信息的话,可以把它的标准输出重定向到 /dev/null。使用 Python 3.3+ 以及 subprocess.Popen 的话,指定 stdout=subprocess.DEVNULL 即可。

PS: 你的部分代码行末尾有多余的空格。

编橙之家文章,

评论关闭