본문 바로가기

Python

subprocess

subprocess

subprocess모듈은 자식 프로세스를 생성하고, 필요하다면 입출력을 주고받을 수 있게 해준다.
난 주로 자동화 스크립트를 짤 때 많이 사용한다.
딱히 길게 말할 것도 없으니 바로 본론으로.

단순 호출 - subprocess.call()

import subprocess

retval = subprocess.call('pwd')
print(retval)  # 문제 없을 시 보통 0

간단히 호출만으로 충분할 때 사용하자. 문제 없이 자식 프로세스가 종료되었다면 보통 0을 리턴값으로 줄 것이다.

호출 and 출력확인 - subprocess.check_output()

import subprocess

output = subprocess.check_output(['pwd'], universal_newlines=True)
print(output)  # /home/makerj/PycharmProjects/pg

call()과는 달리 출력을 받아볼 수 있다.
매개변수로 universal_newlines을 사용하는데,

  • True일 경우 outputstr타입으로 돌아온다. 출력이 여러 줄이라면 ‘\n’을 포함하는 str형태로 돌아온다.
  • (기본값) False일 경우 bytes타입으로 돌아온다.

일회용 통신 - subprocess.communicate()

import subprocess

child = subprocess.Popen(['sudo', '-p', '', '-S', 'ls'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

output = child.communicate('Your Input\n')  # parent --(child.stdin)--> child
child_stdout, child_stderr = output[0], output[1]

print(child_stdout)

이제부터 상호작용에 관련된 예제다.
상호작용을 위해서는 subprocess.Popen()으로 자식 프로세스를 시작하고, 필요한 스트림마다 subprocess.PIPE를 넣어주자. 위 예시에서는 모든 스트림(stdin, stdout, stderr)을 사용하므로 전부 PIPE를 넣어줬다.

핵심은 communicate()로, 원하는 입력값을 넣어주면 된다. sudo같이 1번 입력을 요구하는 프로그램과 궁합이 좋다.
일회용 통신이라고 한 이유는, communicate()가 불리고 나면 스트림이 닫혀 더이상 자식 프로세스와 통신을 할 수 없기 때문이다. 자세한 내용은 communicate()의 구현 코드를 보면 알 수 있다.

1회 이상의 통신이 필요할 경우

import subprocess

proc = subprocess.Popen(['sudo', '-p', '', '-S', 'ls'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

proc.stdin.write('Some Input\n')
proc.stdin.flush()

print(proc.stdout.read())

자식 프로세스가 여러번 입력을 요구하는 녀석이라면 위 예시와 같이 각 stream을 직접적으로 다루면 된다.
자식 프로세스에 입력을 보낼 때 write()후 꼭 flush()를 불러주자. 우리가 열심히 쓴 입력이 버퍼에 남아 자식으로 가지 않은 경우가 발생하기 때문.

'Python' 카테고리의 다른 글

Django 1.11 릴리즈 노트  (0) 2017.01.24
gevent with pycharm  (0) 2016.08.25
DRF ModelViewSet method  (0) 2016.02.25
Python update all package  (0) 2016.02.13
Python urllib.parse  (0) 2016.02.12