Home  >  Q&A  >  body text

python - IOError: [Errno 32] Broken pipe

# -*- coding: utf-8 -*-
#!/usr/bin/python26

from SimpleHTTPServer import SimpleHTTPRequestHandler  
from BaseHTTPServer import BaseHTTPRequestHandler  
from BaseHTTPServer import HTTPServer  
import SocketServer
import cgi
import os
import logging
import thread


class 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.1
Traceback (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

这是为什么呢?

高洛峰高洛峰2742 days ago1001

reply all(1)I'll reply

  • 天蓬老师

    天蓬老师2017-04-17 11:44:36

    You need to know what popen does. It pipes the standard output of the child process to the parent process. So you have to read the pipe in the parent process. If you close it directly, the child process will get a "Broken pipe" error when writing to the pipe. If the pipe is not read, the child process will be blocked when writing more content to the pipe than the pipe buffer.

    os.popen The function returns a file-like object. You can directly .read() read all the data in the pipe.

    If you just don’t want the child process to display information, you can redirect its standard output to /dev/null. If using Python 3.3+ and subprocess.Popen, just specify stdout=subprocess.DEVNULL.

    PS: There are extra spaces at the end of some lines of your code.

    reply
    0
  • Cancelreply