리셋 되지 말자

[python] subprocess 자동 종료하기 (shell=True 옵션) 본문

카테고리 없음

[python] subprocess 자동 종료하기 (shell=True 옵션)

kyeongjun-dev 2021. 6. 16. 14:25

subprocess를 이용한 프로그램 실행

두 개의 방법이 있다. 첫 번째는 그냥 사용. 두 번째는 shell=True 옵션으로 사용하는 방법.

 

첫 번째 방법 : 그냥 사용

소스코드를 먼저 보면,

 

- 소스코드

import subprocess
import time
sp = subprocess.Popen(['python', 'manage.py', 'runserver'], stdout=subprocess.PIPE)

print(sp.pid)
time.sleep(20)
sp.terminate()

Django 웹서버를 시작하는 명령어를 위와같이 subprocess로 실행한다.
실행한 subprocess의 pid를 출력하고, 20초를 대기한 뒤에 subprocess를 종료한다.

 

- 실행결과

$ python sptest.py 
7042

print()로 출력한 pid가 출력된다.

 

 

- 20초 지나기 전에 웹페이지 접속

20초 후에는 접속이 안되는걸 확인

 

- 20초 지나기 전에 process 확인

$ ps -ef | grep python
ubuntu    7041  6408  0 13:59 pts/1    00:00:00 python sptest.py
ubuntu    7042  7041  1 13:59 pts/1    00:00:00 python manage.py runserver
ubuntu    7044  7042  3 13:59 pts/1    00:00:00 /home/ubuntu/바탕화면/python_wait_test/formtest/bin/python manage.py runserver
ubuntu    7051  6607  0 13:59 pts/2    00:00:00 grep --color=auto python

subprocess 는 자식 프로세스를 생성하여 작업을 실행한다. 'python sptest.py' -> 'python manage.py runserver' -> '/home/ubuntu/바탕화면/python_wait_test/formtest/bin/python manage.py runserver' 순으로 subprocess가 생성되어 실행되는걸 확인할 수 있다.

 

- 20초 지나서 process 확인

$ ps -ef | grep python
ubuntu    7051  6607  0 13:59 pts/2    00:00:00 grep --color=auto python

종료된걸 확인

 

 

두 번째 방법 : shell=True 옵션으로 실행

- 소스코드

import subprocess
import time
cmd = 'python manage.py runserver'
sp = subprocess.Popen(cmd , stdout=subprocess.PIPE, shell=True)

print(sp.pid)
time.sleep(20)
sp.terminate()


# os 모듈 사용
import subprocess
import time
import os
cmd = 'python manage.py runserver'
sp = subprocess.Popen(cmd , stdout=subprocess.PIPE, shell=True)

print(sp.pid)
time.sleep(20)
os.kill(sp.pid)

shell=True 옵션을 활용하면, 실제 shell에서 명령어를 그대로 사용할 수 있어서 간편하다. ['python', 'manage.py', 'runserver'] 처럼 일일히 구분하지 않아도 된다. 별도로 shell을 추가로 지정하지 않으면 default 설정인 '/bin/sh' 이다.

POSIX에서 shell=True일 때, 셸의 기본값은 /bin/sh입니다. args가 문자열이면, 문자열은 셸을 통해 실행할 명령을 지정합니다. 이것은 문자열이 프롬프트에서 입력할 때와 똑같이 포맷되어야 한다는 것을 의미합니다. 예를 들어, 스페이스가 포함된 파일명을 인용하거나 역 슬래시 이스케이핑 하는 것을 포함합니다. args가 시퀀스이면, 첫 번째 항목이 명령 문자열을 지정하고, 추가 항목은 셸 자체에 대한 추가 인자로 처리됩니다. 즉, Popen은 다음과 동등한 것을 수행합니다
https://docs.python.org/ko/3/library/subprocess.html

 

- 실행결과

$ python sptest.py 
7394

20초 동안 접속이 되고, 20초 후에는 접속이 끝나는 것도 똑같다.

 

주의사항

shell=True 를 사용할 때, 중간에 subprocess가 /bin/sh 를 통해서 실행된다.
그래서 실제 cmd 명령어를 사용한 pid에서 한번 더 subprocess가 생성되어 pid가 달라지게 되는 경우가 있다.

ex) python manage.py runserver를 실행한 pid는 3030인데, /bin/sh python mana.py runserver가 3030이 되고, 실제 runserver를 실행한 pid는 3031이 되는경우

주의하여 사용할 필요가 있을 것 같다.

Comments