2012-10-18 20 views
28

Çok özel bir soru (umarım): Aşağıdaki üç kod arasındaki farklar nelerdir?Python alt işlemi Popen.communicate() ile Popen.stdout.read() öğesine eşdeğerdir?

(Ben ikinci ve üçüncü olanlar yaparken alt sürecin beklemez ilk bitirilmesi sadece olmasını bekliyoruz. Ama bu sadece fark olduğundan emin olmak gerekir ... zaten ben zaten Python subprocess interaction, why does my process work with Popen.communicate, but not Popen.stdout.read()? okumanızı ve ben istemiyorum shell=True tehlikeler ve platformlar arası sınırlamalar)

not iyi biliyorum gerçi)

Ben de/etkileşim diğer açıklamalar/öneriler (ihtiyaç hoş geldiniz sonra program ile.

Ayrıca zaten Alternatives to Python Popen.communicate() memory limitations? okumak ama unutmayın ben gerçekten ... alamadım o

Nihayet

, bir yerlerde bir tampon bir çıkış ile doldurulur çıkmaz riski vardır farkındayım notu ... bir yöntemi kullanarak fakat internette net açıklamalar için seyir sırasında kayboldu

İlk kod:

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 

İkinci kod:

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 

Üçüncü kodu:

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 

teşekkürler. Eğer subprocess.communicate() için kaynak bakarsak

cevap

37

, bu farkın mükemmel bir örnek gösterilmektedir:

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) 

Sen communicatestdout ve stderr okuma aramaların faydalanmak olmadığını görmek ve aynı zamanda wait() aramaları yapabilirsiniz . Sadece operasyon sırası meselesi. Durumda da stdout için PIPE kullanıyor çünkü ve stderr, bu _communicate() girer:

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) 

Bu defada birden çok akışları okuma konuları kullanır. Sonra sonunda wait() çağırır.

Yani o Özetle:

  1. Bu örnek bir seferde bir akışından okur ve sürecin bitmesini beklemez.
  2. Bu örnek, her iki akıştan da aynı anda iç iş parçacıkları aracılığıyla okur ve işlemi bitirmesini bekler.
  3. Bu örnek, işlemin bitmesini bekler ve bir seferde bir akış okur. Ve bahsettiğiniz gibi, akıntılara çok fazla yazılırsa, çıkma potansiyeli vardır.

Ayrıca, sizin 2. ve 3. örneklerde bu iki içe aktarma ifadelerini gerekmez:

from subprocess import communicate 
from subprocess import wait 

Onlar Popen nesnenin iki yöntem vardır.

İlgili konular