OSError:[Errno 1]不允许操作 - Python

时间:2015-12-17 18:04:20

标签: ruby process operating-system multiprocessing signals

我有一个自动化工具,可以使用命令行启动Ruby on Rails服务器:

from subprocess import Popen
devnull = open(os.devnull, 'r+')
self.webserver = Popen(server_cmd, shell=True, stdin=devnull, stdout=devnull,
                       stderr=devnull, close_fds=True, preexec_fn=os.setsid) 

Web服务器是一个包含作为单独进程运行的服务器的进程(它应该是这样的)。所以我有stop_webserver方法来终止进程并停止Rails服务器:

def stop_webserver(self):
    """
    Stop the Rails server, if there is one running or it was created.
    Kill the process and all of its children, in order to avoid having a
    zoombie processes.
    """
    if self.webserver is None:
        self.log.info("Server isn't running. Nothing to do.")
        return

    if self.is_server_running():
        # os.killpg(self.webserver.pid, signal.SIGTERM)
        self.log.info("PID: %s" % self.webserver.pid)
        # self.log.info("PID: %s" % os.getpgid(self.webserver.pid))
        time.sleep(10)
        os.killpg(self.webserver.pid, signal.SIGKILL)
        self.webserver = None
        self.log.info("Server was stopped.")

但是我总是收到以下错误:

Traceback (most recent call last):
  File "unit/front_end_test.py", line 27, in runTest
    frontend.stop_webserver()
  File "front_end.py", line 184, in stop_webserver
    os.killpg(self.webserver.pid, signal.SIGKILL)
OSError: [Errno 1] Operation not permitted

如果我尝试使用os.getpgid终止该过程,我会收到不同的错误:

Traceback (most recent call last):
  File "unit/front_end_test.py", line 27, in runTest
    frontend.stop_webserver()
  File "front_end.py", line 182, in stop_webserver
    self.log.info("PID: %s" % os.getpgid(self.webserver.pid))
OSError: [Errno 3] No such process

但是,服务器仍在端口3001上运行。该进程从未被终止。如何正确终止流程?

1 个答案:

答案 0 :(得分:1)

我通过强制os.system() kill来解决问题:

def stop_webserver(self):
    """
    Stop the Rails server, if there is one running or it was created.
    Kill the process and all of its children, in order to avoid having a
    zoombie processes.
    """
    if self.webserver is None:
        self.log.info("Server isn't running. Nothing to do.")
        return

    if self.is_server_running():
        try:
            # os.killpg(self.webserver.pid, signal.SIGKILL)
            os.killpg(self.webserver.pid, signal.SIGTERM)
            self.webserver = None
            self.log.info("Server was stopped.")
        except OSError, e:
            self.log.exception(e)
            self.log.info("PID: %s" % self.webserver.pid)
            os.system("sudo kill %s" % (self.webserver.pid, ))