"기다렸다가 다음 일을 한다."
A 작업이 끝날 때까지 기다린 후 B 작업을 시작함
코드 예 (파이썬):
import subprocess
subprocess.run(['sleep', '5']) # A, 5초 동안 기다림
print("끝났습니다!") # B, 이건 5초 뒤에 출력됨
"기다리지 않고 다음 일을 동시에 한다."
A 작업을 백그라운드에서 실행하면서, 동시에 B 작업을 진행
코드 예:
import subprocess
p = subprocess.Popen(['sleep', '5']) # 5초 자는 명령 실행
print("끝났습니다!") # 이건 바로 출력됨!
"프로그램을 실행하긴 하는데, 뒤에서 돌리고 나는 다른 일 함"
python my_script.py & 이렇게 쓰면 백그라운드 실행import subprocess
p = subprocess.Popen(['ping', 'google.com']) # ping: 네트워크 연결 확인 명령어
# 브라우저처럼 띄우지 않고, 뒤에서 실행만 함
여러 명령을 파이프로 연결해서, 앞의 출력을 뒤에 전달하는 것
ls -l | grep py
ls -l = 모든 파일 목록 출력grep py = 그중 .py만 걸러냄| = 파이프, 즉 "앞 출력 → 뒤 입력"import subprocess
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE)
output = p2.communicate()[0]
print(output.decode())
| 개념 | 쉬운 설명 | 현실 비유 |
|---|---|---|
| 동기 | 끝날 때까지 기다림 | 🍜 라면 끓이고 → 먹음 |
| 비동기 | 동시에 처리 | 🍜 라면 끓이면서 → 드라마 |
| 백그라운드 실행 | 눈에 안 보이게 뒤에서 돌림 | 🚶♂️ 타이머 켜놓고 다른 일 함 |
| 파이프 연결 | 앞 명령 출력 → 뒤 명령 입력 | 🍽 채소 자르고 → 국에 넣음 |
subprocess.run()과 subprocess.Popen()subprocess 모듈에 포함되어 있음ls, ping, python script.py) 실행 가능| 항목 | subprocess.run() | subprocess.Popen() |
|---|---|---|
| 파이썬 버전 | Python 3.5+ | Python 2.x ~ 최신 |
| 실행 방식 | 동기적 (완료까지 기다림) | 비동기적 (실시간 실행) |
| 사용 난이도 | 간단함 (고수준 API) | 복잡하지만 유연함 (저수준 API) |
| 결과 처리 | CompletedProcess 객체 반환 | 표준 스트림 직접 관리 필요 |
| 백그라운드 실행 | ❌ 어려움 | ✅ 가능 |
| 리눅스 파이프 연결 | 기본적으로 안 됨 | 자유롭게 가능 (stdin, stdout 조합) |
subprocess.run() 예제import subprocess
# ls -l 실행
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
print("리턴코드:", result.returncode)
run()은 프로세스를 기다렸다가, 끝난 뒤 결과를CompletedProcess객체로 돌려줘요.
> CompletedProcess 객체의 자세한 사용법 <
subprocess.Popen() 예제import subprocess
# 실시간 출력 받기
process = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE, text=True)
for line in process.stdout:
print(line.strip())
process.wait()
Popen()은 명령 실행 후 바로 제어권을 반환하므로, 출력도 실시간으로 받을 수 있어요.
| 상황 | 추천 함수 |
|---|---|
| 명령 한 번 실행하고 결과만 필요 | subprocess.run() |
| 실시간 출력 확인이 필요 | subprocess.Popen() |
| 입력/출력 파이프 연결 | Popen() (예: stdout=PIPE) |
| 명령이 오래 걸릴 수 있고 병렬로 처리하고 싶을 때 | Popen() |
| Python 3.5 이상이고 단순 작업이면 | run() 사용 권장 |
Popen에서 communicate()out, err = process.communicate()
communicate()subprocess.Popen().communicate() 함수는 외부 프로세스와 데이터를 주고받을 때 사용하는 중요한 함수인데요, **전달할 수 있는 인자(arguments)**는 몇 개 안 되지만 아주 유용합니다. 아래에 인자별 설명과 예제를 정리해드릴게요.
communicate() 함수 기본 형태stdout_data, stderr_data = process.communicate(input=None, timeout=None)
inputbytes (기본)str (단, text=True 또는 universal_newlines=True일 때만)import subprocess
p = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, _ = p.communicate(input=b'hello\n') # 문자열을 bytes형으로 변환
print(out.decode()) # 출력: hello
timeoutTimeoutExpired 예외 발생float 또는 int)import subprocess
try:
p = subprocess.Popen(['sleep', '5'], stdout=subprocess.PIPE)
p.communicate(timeout=2)
except subprocess.TimeoutExpired:
print("타임아웃 발생!") # 2초 뒤 출력
input을 쓰려면 stdin=PIPE가 필요함# 잘못된 사용 – stdin 설정 안 하면 input 전달 불가
p = subprocess.Popen(['cat'])
p.communicate(input=b'hello') # 오류 발생!
p = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
p.communicate(input=b'hello') # OK
| 인자 | 설명 | 주의사항 |
|---|---|---|
input | stdin으로 보낼 데이터 | stdin=subprocess.PIPE 필요 |
timeout | 시간 초과 제한 (초 단위) | 초과 시 TimeoutExpired 발생 |
stdout_data, stderr_data = process.communicate(...)
stdout_data: 표준 출력 결과 (stdout=PIPE일 때만)stderr_data: 표준 에러 결과 (stderr=PIPE일 때만)