콘텐츠로 건너뛰기
Home » Subprocess 모듈 사용법 (2021 업데이트)

Subprocess 모듈 사용법 (2021 업데이트)

subprocess 모듈을 사용하는 방법에 대해 정리한 이전 글이 있는데, 이 글도 2021년 기준으로 벌써 6년전 글이고, 실제로 글이 발행됐을 때쯤에 파이썬 3.5가 나오면서 subprocess 모듈이 다시 업데이트 됐었다. 지금은 그 글에서 설명하고 있는 여러 API들은 레거시로 분류되어 있다. 그래서 좀 늦은 감은 있지만 subprocess 모듈의 사용법을 새롭게 정리해 보고자 한다.

급한 사람들을 위한 요약

딱 두 가지이다.

  1. 이제 subprocess.run() 함수만 쓰면 된다.
  2. run() 의 리턴값인 객체에서 리턴코드, 출력 내용 등을 확인할 수 있다.

물론 함수에 전달하는 추가적인 파라미터에 따라 여러가지 옵션이 나뉘기는 하지만, 이러한 것들은 기존의 api에서 크게 달라지지 않는다.

subprocess.run

subprocess 모듈을 사용해서 하위 프로세스를 실행하는 api는 subprocess.run() 함수로 대동단결하게 되었다. subprocess.run() 함수는 기존의 api 와 비슷하게 내부적으로는 Popen()을 사용하며, subprocess.call() 에 익숙하다면 큰 어려움 없이 사용할 수 있다.

이전 api와 달리, 완료된 프로세스의 정보를 담은 객체를 리턴하며, 여기서 실행한 명령과 종료 코드를 볼 수 있다. 자식 프로세스가 화면에 출력하는 글자들은 똑같이 화면으로 출력된다. 단 여기서 capture_output 옵션을 사용하면, 리턴되는 객체가 출력된 내용을 캡쳐해 두게 된다.

아래는 run() 함수를 호출할 때 사용할 파라미터들이다.

  • 실행할 명령 : 문자열 혹은 문자열의 연속열
  • stdin= : 표준 입력으로 데이터를 넣어줄 IO 객체. 입출력과 관련된 IO 객체는 기본적으로 바이너리 모드이지만, encoding= 인자가 넘겨진 경우에는 텍스트 모드로 취급하게 된다.
  • input= : 표준 입력으로 전달해 줄 데이터. 기본적으로 바이트스트림이지만, encodig= 옵션이나 text=True 로 전달했다면 문자열을 전달할 수 있다.
  • stdout= : 표준출력의 내용을 전달할 IO 객체. subprocess.PIPE를 전달하여 캡쳐할 수 있다.
  • stderr= : 표준 오류의 내용을 전달할 객체. 역시 subprocess.PIPE를 전달하여 캡쳐하거나, subprocess.STDOUT을 전달하여 표준 출력과 하나로 병합하는 방법도 있다.
  • capture_output= : True 를 전달하는 경우, 표준출력과 표준에러를 각각 stdout, stderr 으로 캡쳐한다.
  • shell= : True를 전달하면 별도의 쉘을 실행하고 그 위에서 명령을 실행한다.
  • timeout= : 만료시간을 제한한다. 만료시간이 지나면 자식 프로세스를 죽이며, 자식 프로세스가 죽고 나면 TimeoutExpired 예외를 일으킨다.
  • check= : True 로 전달하면 자식 프로세스의 리턴 코드가 0이 아니면 CalledProcessError 예외를 일으킨다.
  • encoding= : 표준출력 및 표준오류의 인코딩. 이 값이 있으면 출력 내용은 문자열로 열린다.
  • errors= , text= : 표준 오류 및 표준 출력을 텍스트 모드로 열 것인지를 결정하는 bool 값이다.
  • env= : 새 프로세스의 환경 변수를 정의하는 맵핑
  • universal_newlines= :
  • 그 외 키워드 인자 : 그외의 키워드 인자는 popen() 함수의 키워드 인자로 전달된다.

호출 결과

자식 프로세스의 리턴 코드를 확인하거나, 출력 내용을 리턴받기 위해서 이전에는 check_call() 이나 check_output() 을 사용했다. 이제 subprocess.run()CompletedProcess 클래스의 인스턴스를 리턴한다. 이 객체의 속성으로부터 프로세스의 결과를 확인할 수 있다.

  • args : 프로세스를 시작하는데 사용된 인자
  • returncode : 자식 프로세스가 리턴한 코드
  • stdout : 자식 프로세스의 표준 출력을 캡쳐한 그 내용
  • stderr : 자식 프로세스의 표준 오류를 캡쳐한 내용
  • check_returncode() : returncode 속성이 0 이 아니면 CalledProcessError 예외를 일으킨다.

부록 : Shell=True 옵션을 사용할 때의 보안 고려 사항

기본적으로 이 함수의 구현은 시스템 쉘을 암묵적으로 호출하지 않는다. 이 말은 즉 쉘 메타문자를 비롯한 모든 문자를 안전하게 자식 프로세스로 전달할 수 있다는 것을 의미한다. 하지만 shell=True 옵션을 사용하면 공백이나 메타문자를 적절하게 처리해서 쉘 인젝션 취약점을 회피하는 처리를 애플리케이션이 책임져야 한다는 의미이다.