sirve que para examples example ejemplos python subprocess wait popen communicate

que - Python subprocess Popen.communicate() equivalente a Popen.stdout.read()?



subprocess.popen python example (1)

Si miras la fuente de subprocess.communicate() , muestra un ejemplo perfecto de la diferencia:

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)

Puede ver que la communicate hace uso de las llamadas de lectura a stdout y stderr , y también llama a wait() . Es sólo una cuestión de orden de operaciones. En su caso, porque está utilizando PIPE para stdout y stderr, entra en _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)

Esto utiliza hilos para leer de varias secuencias a la vez. Luego llama wait() al final.

Así que para resumir:

  1. Este ejemplo se lee de una secuencia a la vez y no espera a que finalice el proceso.
  2. Este ejemplo lee de ambas secuencias al mismo tiempo a través de subprocesos internos, y espera a que termine el proceso.
  3. Este ejemplo espera a que finalice el proceso, y luego lee una secuencia a la vez. Y, como usted mencionó, tiene el potencial de interbloqueo si hay demasiado escrito en los flujos.

Además, no necesita estas dos declaraciones de importación en sus ejemplos 2 y 3:

from subprocess import communicate from subprocess import wait

Ambos son métodos del objeto Popen .

Pregunta muy específica (espero): ¿Cuáles son las diferencias entre los siguientes tres códigos?

(Espero que solo sea que el primero no espere a que finalice el proceso hijo, mientras que el segundo y el tercero sí. Pero debo estar seguro de que esta es la única diferencia ...

También doy la bienvenida a otros comentarios / sugerencias (aunque ya conozco bien el shell=True Peligros shell=True y limitaciones multiplataforma)

Tenga en cuenta que ya leí la interacción de subproceso de Python, ¿por qué mi proceso funciona con Popen.communicate, pero no con Popen.stdout.read ()? y que no quiero / necesito interactuar con el programa después.

También tenga en cuenta que ya leí Alternativas a las limitaciones de memoria de Popth.com () de Python (). pero que realmente no lo entendí ...

Finalmente, tenga en cuenta que estoy consciente de que en algún lugar existe un riesgo de interbloqueo cuando un búfer se llena con una salida utilizando un método, pero me perdí mientras buscaba explicaciones claras en Internet ...

Primer codigo

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

Segundo código:

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

Tercer código:

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

Gracias.