복붙노트

[PYTHON] 여러 가지 Popen 명령을 파이프와 연결

PYTHON

여러 가지 Popen 명령을 파이프와 연결

cmd = subprocess.Popen을 사용하여 명령을 실행 한 다음 subprocess.communicate를 실행하는 방법을 알고 있습니다. 대부분 나는 Popen을위한 'argv'인수로서 shlex.split로 토큰 화 된 문자열을 사용합니다. "ls -l"예제 :

import subprocess
import shlex
print subprocess.Popen(shlex.split(r'ls -l'), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]

그러나 파이프가 작동하지 않는 것처럼 보입니다 ... 예를 들어, 다음 예제는 주목할만한 것을 반환합니다.

import subprocess
import shlex
print subprocess.Popen(shlex.split(r'ls -l | sed "s/a/b/g"'), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]

내가 뭘 잘못하고 있는지 말해 줄 수 있니?

고마워

해결법

  1. ==============================

    1.나는 당신이 여기에서 두 개의 분리 된 Popen 객체를 인스턴스화하고 싶다고 생각합니다. 하나는 'ls'이고 다른 하나는 'sed'입니다. 첫 번째 Popen 객체의 stdout 속성을 두 번째 Popen 객체의 stdin 인수로 전달하려고합니다.

    나는 당신이 여기에서 두 개의 분리 된 Popen 객체를 인스턴스화하고 싶다고 생각합니다. 하나는 'ls'이고 다른 하나는 'sed'입니다. 첫 번째 Popen 객체의 stdout 속성을 두 번째 Popen 객체의 stdin 인수로 전달하려고합니다.

    예:

    p1 = subprocess.Popen('ls ...', stdout=subprocess.PIPE)
    p2 = subprocess.Popen('sed ...', stdin=p1.stdout, stdout=subprocess.PIPE)
    print p2.communicate()
    

    명령이 더 많은 경우이 방법으로 체인을 유지할 수 있습니다.

    p3 = subprocess.Popen('prog', stdin=p2.stdout, ...)
    

    서브 프로세스 작업 방법에 대한 자세한 정보는 서브 프로세스 문서를 참조하십시오.

  2. ==============================

    2.shlex는 셸 규칙에 따라 공백 만 분할하지만 파이프는 처리하지 않습니다.

    shlex는 셸 규칙에 따라 공백 만 분할하지만 파이프는 처리하지 않습니다.

    그러나 다음과 같이 작동해야합니다.

    import subprocess
    import shlex
    
    sp_ls = subprocess.Popen(shlex.split(r'ls -l'), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
    sp_sed = subprocess.Popen(shlex.split(r'sed "s/a/b/g"'), stdin = sp_ls.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
    sp_ls.stdin.close() # makes it similiar to /dev/null
    output = sp_ls.communicate()[0] # which makes you ignore any errors.
    print output
    

    도움 (하위 프로세스)에 따르면

    Replacing shell pipe line
    -------------------------
    output=`dmesg | grep hda`
    ==>
    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    output = p2.communicate()[0]
    

    HTH

  3. ==============================

    3.배관을 돕기 위해 약간의 기능을 만들었습니다. 도움이되기를 바랍니다. 필요에 따라 Popens를 연결합니다.

    배관을 돕기 위해 약간의 기능을 만들었습니다. 도움이되기를 바랍니다. 필요에 따라 Popens를 연결합니다.

    from subprocess import Popen, PIPE
    import shlex
    
    def run(cmd):
      """Runs the given command locally and returns the output, err and exit_code."""
      if "|" in cmd:    
        cmd_parts = cmd.split('|')
      else:
        cmd_parts = []
        cmd_parts.append(cmd)
      i = 0
      p = {}
      for cmd_part in cmd_parts:
        cmd_part = cmd_part.strip()
        if i == 0:
          p[i]=Popen(shlex.split(cmd_part),stdin=None, stdout=PIPE, stderr=PIPE)
        else:
          p[i]=Popen(shlex.split(cmd_part),stdin=p[i-1].stdout, stdout=PIPE, stderr=PIPE)
        i = i +1
      (output, err) = p[i-1].communicate()
      exit_code = p[0].wait()
    
      return str(output), str(err), exit_code
    
    output, err, exit_code = run("ls -lha /var/log | grep syslog | grep gz")
    
    if exit_code != 0:
      print "Output:"
      print output
      print "Error:"
      print err
      # Handle error here
    else:
      # Be happy :D
      print output
    
  4. ==============================

    4."" " 왜 껍질을 사용하지 않는거야?

    "" " 왜 껍질을 사용하지 않는거야?

    """

    def output_shell (줄) :

    try:
        shell_command = Popen(line, stdout=PIPE, stderr=PIPE, shell=True)
    except OSError:
        return None
    except ValueError:
        return None
    
    (output, err) = shell_command.communicate()
    shell_command.wait()
    if shell_command.returncode != 0:
        print "Shell command failed to execute"
        return None
    return str(output)
    
  5. from https://stackoverflow.com/questions/7389662/link-several-popen-commands-with-pipes by cc-by-sa and MIT license