표준 스트림 (Standard Streams)
표준 스트림은 프로그램과 환경(보통 터미널) 간의 입출력 통로입니다.
Unix, Unix 계열 OS(Windows 일부 포함)에서 자동으로 세 개의 스트림이 열립니다.
표준 스트림의 종류
- 표준 입력 (STDIN):
- 사용자 입력 데이터를 처리.
- 파일 디스크립터: 0
- 표준 출력 (STDOUT):
- 프로그램의 일반 출력을 표시.
- 파일 디스크립터: 1
- 표준 에러 (STDERR):
- 에러 메시지를 출력.
- 파일 디스크립터: 2
Python에서의 표준 스트림
<stdio.h> 헤더 파일에서 정의된 stdin, stdout, stderr는 Python의 sys 모듈을 통해 다룰 수 있습니다.
import sys
# 표준 출력
print("Python", "Java", file=sys.stdout)
# 표준 에러
print("Python", "Java", file=sys.stderr)
subprocess 모듈과 run
- Python의 subprocess 모듈은 외부 프로세스 호출과 상호작용을 지원합니다.
- run 함수는 간단한 프로세스 호출 및 결과 처리에 적합합니다.
subprocess.run 주요 매개변수
- stdin, stdout, stderr: 표준 스트림 데이터 연결 방법 설정.
- None: 기본값(터미널 연결).
- subprocess.PIPE: 파이프 연결.
- subprocess.STDOUT: 표준 에러(stderr)를 표준 출력(stdout)과 병합.
- shell: 셸을 통해 명령 실행 여부 (True/False).
- text: 텍스트 스트림을 문자열로 처리(기본값은 False로 바이트 처리).
1. 명령 실행 및 출력 캡처
from subprocess import run
# 명령 실행 및 결과 캡처
result = run(["echo", "Hello World"], capture_output=True, text=True)
print(result.stdout) # "Hello World\\n"
2. 표준 입력 데이터 전달
- 명령 실행 시 데이터를 표준 입력으로 전달하려면 input 인자를 사용합니다.
from subprocess import run
# 표준 입력 데이터를 전달하여 결과 받기
result = run(
["cat"],
input="data to send\\nmore data\\n",
capture_output=True,
text=True
)
print(result.stdout
3. 타임아웃 처리
- timeout 매개변수로 명령 실행 제한 시간을 설정할 수 있습니다.
- 제한 시간이 초과되면 TimeoutExpired 예외가 발생합니다.
from subprocess import run, TimeoutExpired
try:
result = run(["sleep", "10"], timeout=5, capture_output=True)
except TimeoutExpired:
print("명령이 타임아웃되었습니다.")
4. 표준 출력과 표준 에러 병합
- stderr=subprocess.STDOUT를 사용하여 표준 출력과 에러를 병합합니다.
from subprocess import run, STDOUT
# 표준 출력과 에러를 병합하여 하나의 스트림으로 처리
result = run(["ls", "-l", "/invalid_path"], capture_output=True, stderr=STDOUT, text=True)
print(result.stdout) # 출력과 에러가 함께 출력
5. 실시간 출력 읽기
- run은 기본적으로 명령 종료까지 대기하므로 실시간 출력 처리가 필요할 경우 Popen을 사용하거나 로그 처리 도구를 사용하는 것이 적합합니다.
- run으로 실시간 출력은 직접 제공되지 않습니다.
6. sys.stdout 및 sys.stderr 활용
- sys.stdout과 sys.stderr를 사용하여 출력 흐름을 제어할 수 있습니다.
import sys
# 일반 출력
sys.stdout.write("This is standard output\\n")
# 에러 출력
sys.stderr.write("This is an error message\\n")
subprocess.run 주요 특징
- 간단한 명령 실행과 결과 캡처에 적합.
- 기본적으로 명령 실행 후 프로세스 종료를 기다림.
- 파이프와 입력 데이터를 함께 처리하는 Popen보다 직관적이며, 대부분의 작업을 대체 가능.
subprocess.run은 표준 출력/에러 처리, 데이터 전달, 타임아웃 처리 등 간단한 프로세스 호출에 적합하며, 복잡한 실시간 스트림 처리나 비동기 작업은 Popen을 사용할 수 있습니다.