subprocess.Popen() 必须加上close_fds=True(

时间:2022-11-03 15:46:19

今天在做一个web页面控制memcached重启的功能,本以为非常简单,不就获取pid,然后kill,在重新启动memcached就这么简单。

没想到使用subprocess.Popen() 来调用命令时竟然发现response确实是返回到客户端了,但是服务器端和客户端的http连接竟然还连接着,一直不断。

查看了一下python的文档,发现:http://docs.python.org/library/subprocess.html

popen2 closes all file descriptors by default, but you have to specify close_fds=True withPopen

我的代码如下:

def _restart(port, start_cmd):
     cmd
= ' ps aux | grep "memcached .* %s" ' % port
     p
= subprocess.Popen(cmd, shell = True, close_fds = True, # 必须加上close_fds=True,否则子进程会一直存在
                          stdout = subprocess.PIPE, stderr = subprocess.PIPE)
     stdoutdata, stderrdata
= p.communicate()
    
if p.returncode != 0:
        
return False, error_response(cmd, stderrdata)
    
for r in stdoutdata.split( ' \n ' ):
        
if cmd in r:
            
continue
        
break
    
if r:
         pid
= r.split()[ 1 ]
        
         cmd
= ' kill %s ' % pid
         p
= subprocess.Popen(cmd, shell = True, close_fds = True,
                              stdout
= subprocess.PIPE, stderr = subprocess.PIPE)
         p.communicate()
     p
= subprocess.Popen(start_cmd, shell = True, close_fds = True,
                          stdout
= subprocess.PIPE, stderr = subprocess.PIPE)
     stdoutdata, stderrdata
= p.communicate()
    
if p.returncode != 0:
        
return False, error_response(cmd, stderrdata)
    
return True, None
 

subprocess - Subprocesses with accessible I/O streams
 
This module allows you to spawn processes, connect to their
input/output/error pipes, and obtain their return codes.  This module
intends to replace several other, older modules and functions, like:
 
os.system
os.spawn*
os.popen*
popen2.*
commands.*
 
Information about how the subprocess module can be used to replace these
modules and functions can be found below.
 
 
 
Using the subprocess module
===========================
This module defines one class called Popen:
 
class Popen(args, bufsize=0, executable=None,
            stdin=None, stdout=None, stderr=None,
            preexec_fn=None, close_fds=False, shell=False,
            cwd=None, env=None, universal_newlines=False,
            startupinfo=None, creationflags=0):
 
 
Arguments are:
 
args should be a string, or a sequence of program arguments.  The
program to execute is normally the first item in the args sequence or
string, but can be explicitly set by using the executable argument.
 
On UNIX, with shell=False (default): In this case, the Popen class
uses os.execvp() to execute the child program.  args should normally
be a sequence.  A string will be treated as a sequence with the string
as the only item (the program to execute).
 
On UNIX, with shell=True: If args is a string, it specifies the
command string to execute through the shell.  If args is a sequence,
the first item specifies the command string, and any additional items
will be treated as additional shell arguments.
 
On Windows: the