Chr*_*phe 29 python subprocess popen wait communicate
非常具体的问题(我希望):以下三个代码之间有什么区别?
(我希望它只是第一个不等待子进程完成,而第二个和第三个进行.但我需要确定这是唯一的区别......)
我也欢迎其他评论/建议(虽然我已经很清楚shell=True危险和跨平台限制)
请注意,我已经阅读过Python子进程交互,为什么我的进程可以使用Popen.communicate,但不能使用Popen.stdout.read()?并且我不希望/之后需要与程序交互.
另请注意,我已经阅读了Python Popen.communicate()内存限制的替代品?但是我没有真正得到它......
最后,请注意我知道当一个缓冲区使用一种方法填充一个输出时存在死锁的风险,但我在互联网上寻找清晰的解释时迷路了......
第一个代码:
from subprocess import Popen, PIPE
def exe_f(command='ls -l', shell=True):
"""Function to execute a command and return stuff"""
process = Popen(command, shell=shell, stdout=PIPE, stderr=PIPE)
stdout = process.stdout.read()
stderr = process.stderr.read()
return process, stderr, stdout
Run Code Online (Sandbox Code Playgroud)
第二个代码:
from subprocess import Popen, PIPE
from subprocess import communicate
def exe_f(command='ls -l', shell=True):
"""Function to execute a command and return stuff"""
process = Popen(command, shell=shell, stdout=PIPE, stderr=PIPE)
(stdout, stderr) = process.communicate()
return process, stderr, stdout
Run Code Online (Sandbox Code Playgroud)
第三个代码:
from subprocess import Popen, PIPE
from subprocess import wait
def exe_f(command='ls -l', shell=True):
"""Function to execute a command and return stuff"""
process = Popen(command, shell=shell, stdout=PIPE, stderr=PIPE)
code = process.wait()
stdout = process.stdout.read()
stderr = process.stderr.read()
return process, stderr, stdout
Run Code Online (Sandbox Code Playgroud)
谢谢.
jdi*_*jdi 38
如果您查看源代码subprocess.communicate(),它会显示差异的完美示例:
def communicate(self, input=None):
...
# Optimization: If we are only using one pipe, or no pipe at
# all, using select() or threads is unnecessary.
if [self.stdin, self.stdout, self.stderr].count(None) >= 2:
stdout = None
stderr = None
if self.stdin:
if input:
self.stdin.write(input)
self.stdin.close()
elif self.stdout:
stdout = self.stdout.read()
self.stdout.close()
elif self.stderr:
stderr = self.stderr.read()
self.stderr.close()
self.wait()
return (stdout, stderr)
return self._communicate(input)
Run Code Online (Sandbox Code Playgroud)
你可以看到,communicate并利用读取调用stdout和stderr,还呼吁wait().这只是一个操作顺序问题.在你的情况下,因为你正在使用PIPEstdout和stderr,它进入_communicate():
def _communicate(self, input):
stdout = None # Return
stderr = None # Return
if self.stdout:
stdout = []
stdout_thread = threading.Thread(target=self._readerthread,
args=(self.stdout, stdout))
stdout_thread.setDaemon(True)
stdout_thread.start()
if self.stderr:
stderr = []
stderr_thread = threading.Thread(target=self._readerthread,
args=(self.stderr, stderr))
stderr_thread.setDaemon(True)
stderr_thread.start()
if self.stdin:
if input is not None:
self.stdin.write(input)
self.stdin.close()
if self.stdout:
stdout_thread.join()
if self.stderr:
stderr_thread.join()
# All data exchanged. Translate lists into strings.
if stdout is not None:
stdout = stdout[0]
if stderr is not None:
stderr = stderr[0]
# Translate newlines, if requested. We cannot let the file
# object do the translation: It is based on stdio, which is
# impossible to combine with select (unless forcing no
# buffering).
if self.universal_newlines and hasattr(file, 'newlines'):
if stdout:
stdout = self._translate_newlines(stdout)
if stderr:
stderr = self._translate_newlines(stderr)
self.wait()
return (stdout, stderr)
Run Code Online (Sandbox Code Playgroud)
这使用线程一次从多个流中读取.然后它wait()在最后调用.
总结一下:
此外,在第2和第3个示例中,您不需要这两个import语句:
from subprocess import communicate
from subprocess import wait
Run Code Online (Sandbox Code Playgroud)
它们都是Popen对象的方法.
| 归档时间: |
|
| 查看次数: |
31607 次 |
| 最近记录: |