상세 컨텐츠

본문 제목

[파이썬(Python)] #19. subprocess 모듈

python

by 빨간눈동자 2021. 10. 15. 00:00

본문

반응형

subprocess 모듈은 새로운 프로세스를 실행하도록 도와주며, 프로세서의 입/출력 및 에러 결과에 대한 리턴 값을 사용자가 직접 제어할 수 있게 도와준다. 

 

subprocess.run()

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)
# test.py
import subprocess

print(subprocess.run(['ls -al'], shell=True, check=True))

window 실행 화면

위 에러 내용은 window 환경이라 "ls -al" 명령어를 지원하지 않아 출력되는 error 이다. 

ubunt 20.04 실행 화면

 

 

window 환경에서 테스트하려면, window cmd인 "dir" 명령을 수행해보자. 

# test.py
import subprocess

print(subprocess.run(['dir'], shell=True, check=True))

 

subprocess.call()

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
# test.py
import subprocess

print("="*50)
print(subprocess.call(['ls', '-al']))                        # 1
print("="*50)
print(subprocess.call(['ls -al'], shell=True))               # 2
print("="*50)

 

※ run()과 call()은 비슷한 기능을 수행하지만, 인터넷을 찾아보니 다들 run()을 사용하라고 권장하고 있다. 

 

 

subprocess.Popen()

subprocess.Popen(args, bufsize=-1, excutable=None, 
                       stdin=None, stdout=None, stderr=None, 
                       preexec_fn=None, close_fds=None, shell=False, 
                       cwd=None, env=None, universal_newlines=False, 
                       startupinfo=None, creationflags=0, restoreflags=0, 
                       restore_signals=True, start_new_session=False, pass_fds=()
                      )

arg : 문자열 or 입력될 인자를 공백으로 나눈 리스트

stdin, stdout, stderr : 표준 입력, 표준 출력, 표준 에러을 제어한다. 

shell=True : subprocess로 주어진 명령이 바로 실행되는 것이 아니라, 별도의 쉘을 실행하고 해당 쉘에서 명령을 실행하도록 함 

universal_newlines=True : output을 byte arrary가 아닌 string으로 변환해 준다. 

 

Popen 객체의 method

.poll() : 자식 프로세스가 종료되었는지를 확인함.

.wait(timeout=None) : 자식 프로세스가 종료되길 기다린다. 

.communicate(input=None, timeout=None) : 자식 프로세스의 표준 입력으로 데이터를 보낸다음, 표준 출력의 EOF를 만날 때까지 이를 읽어온다.  

이 함수는 튜플을 리턴하고, 이 함수를 사용하려면 stdout=subprocess.PIPE 옵션으로 자식 프로세스를 시작해야 함 

import subprocess
proc = subprocess.Popen(
    ['echo', 'Hello world'],
    stdout=subprocess.PIPE
    )
out, err = proc.communicate()
print(out)                       # 결과가 byte array 형태임
print(out.decode('utf-8'))       # string으로 변환하기 위해 decoding을 해줘야함

 

# communicate()의 output을 string으로 변경하기 위해서는 universal_newline=True option을 사용하면 된다.

import subprocess

proc = subprocess.Popen(
            ['echo', 'Hello world'],
            stdout=subprocess.PIPE, universal_newlines=True
            )
out, err = proc.communicate()
print(out)

 

import subprocess

proc = subprocess.Popen(['sleep', '3'])
while proc.poll() is None:
    print('Working...')
    # 시간이 걸리는 작업을 수행
print('Exit Status', proc.poll())

3초 동안 while문을 돌다가 종료하게 된다. 

 

import subprocess

proc = subprocess.Popen(['sleep', str(10)])
try:
    proc.communicate(timeout=1)
except subprocess.TimeoutExpired:
    proc.terminate()
    proc.wait()

print('Exit status', proc.poll())

sleep 10초를 수행하지만, proc.comunicate(timeout=1)로 인해 exception이 발생하여 except 구문으로 빠지면서 프로그램이 종료된다.  

 

poll()과 wait()(그리고 communicate()에 의해 간접적으로)로 설정된 자식 반환 코드 None 값은 프로세스가 아직 종료되지 않았음을 나타낸다.

음수 값 -N은 자식이 시그널 N에 의해 종료되었음을 나타낸다. (POSIX 전용).

 

 

반응형

관련글 더보기