我使用python BaseHTTPServer,它可以处理do_GET,do_POST方法,在do_POST方法中,我使用os.system执行linux shell,当我杀死python脚本,但是监听端口仍然被占用,所以我无法运行再次编写脚本,netstat -antp | grep 80显示bash / tail占用端口80
import sys
import os
import traceback
import time
import logging.handlers
import logging
from threading import *
from datetime import datetime
import urllib2
reload(sys)
sys.setdefaultencoding('utf-8')
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
server_version = 'python httpserver'
sys_version = 'b'
backup_dir = None
def do_HEAD(s):
s.send_response(200)
s.send_header("Content-type", "text/html")
s.end_headers()
def do_GET(self):
if self.path == '/foo':
self.send_response(200)
os.system('nohup tail -f a.log &')
else:
self.send_error(404)
if __name__ == "__main__":
try:
server = BaseHTTPServer.HTTPServer(('',80), WebRequestHandler)
server.serve_forever()
except KeyboardInterrupt:
server.socket.close()
答案 0 :(得分:3)
默认情况下,子进程会继承文件描述符,因此使用system()调用启动的命令会继承侦听端口80的套接字。
为避免这种情况,您应该在侦听套接字上设置FD_CLOEXEC标志。这可以通过添加(和使用)特定的HTTPServer类来完成。
class WebServer(BaseHTTPServer.HTTPServer):
def __init__(self, *args, **kwargs):
BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
# Set FD_CLOEXEC flag
flags = fcntl.fcntl(self.socket.fileno(), fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(self.socket.fileno(), fcntl.F_SETFD, flags)
相关: