我在Windows中使用python 3.6,我的目标是运行cmd命令并将输出保存为变量中的字符串。
我正在使用子进程及其对象,如check_output
,Popen and Communicate
和getoutput
。但这是我的问题:
subprocess.check_output
问题是,如果代码返回非零,则引发异常并且我无法读取输出,例如,执行netstat -abcd
。
stdout_value = (subprocess.check_output(command, shell=True, stdin=subprocess.PIPE, stderr=subprocess.DEVNULL, timeout=self.timeout)).decode()
subprocess.Popen
和communicate()
问题是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
答案 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'问题!