subprocess check_output,Popen,getoutput python之间的区别

时间:2017-11-04 08:36:27

标签: python subprocess

我在Windows中使用python 3.6,我的目标是运行cmd命令并将输出保存为变量中的字符串。 我正在使用子进程及其对象,如check_outputPopen and Communicategetoutput。但这是我的问题:

subprocess.check_output问题是,如果代码返回非零,则引发异常并且我无法读取输出,例如,执行netstat -abcd

stdout_value = (subprocess.check_output(command, shell=True, stdin=subprocess.PIPE, stderr=subprocess.DEVNULL, timeout=self.timeout)).decode()

subprocess.Popencommunicate()问题是netstat -abcd等命令从communicate()返回空。

self.process = subprocess.Popen(command, shell=True,
                                            stdout=subprocess.PIPE,
                                            stderr=subprocess.DEVNULL,
                                            stdin=subprocess.PIPE)
try:
   self.process.wait(timeout=5)
   stdout_value = self.process.communicate()[0]
except:
   self.process.kill()
   self.process.wait()

subprocess.getoutput(Command)没问题,但是没有超时,所以我的代码会永远阻止执行netstat之类的命令。我也尝试将它作为一个线程运行,但代码是阻塞的,我无法阻止线程本身。

stdout_value = subprocess.getoutput(command)

我想要的是使用超时运行任何cmd命令(像netstat一样阻塞或像dir这样的非阻塞),例如,如果用户执行netstat它只显示超时生成的行然后杀死它。 感谢。

EDIT ------ 根据Jean的回答,我重写了代码,但超时在运行netstat等命令时不起作用。

# command = "netstat"
command = "test.exe"  # running an executable program can't be killed after timeout
self.process = subprocess.run(command, shell=True,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE,
                              stdin=subprocess.PIPE,
                              timeout=3,
                              universal_newlines=True
                              )
stdout_value = self.process.stdout

1 个答案:

答案 0 :(得分:2)

带有超时的

subprocess.run()似乎无法在Windows上正常运行。

您可以尝试在Timer-thread内运行子流程,或者如果您不需要沟通(),您可以执行以下操作:

import time
import subprocess

#cmd = 'cmd /c "dir c:\\ /s"' 
#cmd = ['calc.exe']
cmd = ['ping', '-n', '25', 'www.google.com']

#_stdout = open('C:/temp/stdout.txt', 'w')
#_stderr = open('C:/temp/stderr.txt', 'w')

_stdout = subprocess.PIPE
_stderr = subprocess.PIPE

proc = subprocess.Popen(cmd, bufsize=0, stdout=_stdout, stderr=_stderr)

_startTime = time.time()

while proc.poll() is None and proc.returncode is None:
    if (time.time() - _startTime) >= 5:
        print ("command ran for %.6f seconds" % (time.time() - _startTime))
        print ("timeout - killing process!")
        proc.kill()
        break

print (proc.stdout.read())

它适用于Win7 / py3.6上的所有三个命令,但不适用于' killed-netstat'问题!