HOWTO · Python
Python에서 Windows CMD 명령을 실행하고 출력을 가져오는 방법
Python에서 os.system()으로 Windows CMD 명령을 실행하거나, subprocess 모듈의 파이프를 사용해 명령 출력을 캡처합니다.
이 페이지의 내용
Windows CMD 명령을 Python에서 실행할 때, 명령이 콘솔에 출력만 표시하면 되는 경우에는 os.system()을 사용합니다. 이 함수는 명령의 출력을 Python 문자열로 반환하지 않고 상태 값을 반환합니다. Python에서 출력을 읽어야 한다면 파이프와 communicate()를 사용하는 subprocess 모듈을 이용하세요.
Python 스크립트에서 CMD 명령을 실행하고 os.system()으로 출력 가져오기
os.system() 함수는 명령을 운영 체제의 명령 처리기에 전달합니다. Windows에서는 os.system("cmd /c echo hello")처럼 간단히 사용할 수 있습니다. CMD가 echo hello를 실행하면 텍스트가 콘솔에 표시됩니다. 함수의 반환값은 명령의 상태를 나타내며, 화면에 표시된 텍스트를 담고 있지는 않습니다.
출력을 사람이 읽으면 되는 간단한 명령에는 이 방법을 사용하세요. 여기서는 Windows CMD 구문을 사용합니다. dir, cd, md는 CMD에서 사용하는 명령이며, 세 가지 모두 CMD 내장 명령입니다. cd라는 이름은 다른 셸에서도 쓰이므로 이 명령 이름들이 Windows에만 있는 것은 아닙니다. Python 프로그램 안에서 명령 결과를 사용하거나 표준 출력과 표준 오류를 따로 처리해야 한다면 subprocess를 사용하세요.
신뢰할 수 없는 입력으로 명령 문자열을 만들지 마세요. 명령 처리기는 셸 메타문자를 구문으로 해석할 수 있으므로, os.system()을 사용할 때는 신뢰할 수 있는 고정 명령만 전달하세요.
Python 스크립트에서 CMD 명령을 실행하고 subprocess 모듈로 출력 가져오기
subprocess.Popen()을 사용하면 표준 출력과 표준 오류를 각각 별도의 파이프로 연결해 프로세스를 시작할 수 있습니다. communicate()를 호출하면 두 스트림을 모두 읽고 프로세스가 끝날 때까지 기다립니다. 한쪽 파이프가 가득 찼는데 다른 쪽을 읽지 않아 발생할 수 있는 교착 상태를 피할 수 있습니다. 캡처한 값은 바이트이므로 텍스트로 처리하기 전에 명령이 사용하는 인코딩으로 디코딩하세요.
이 독립 실행형 예제는 Windows에서는 CMD를, 그 외 플랫폼에서는 현재 Python 인터프리터를 사용하므로 두 환경 모두에 캡처 패턴을 적용할 수 있습니다. 예제는 캡처한 줄을 출력합니다.
import os
import subprocess
import sys
if os.name == "nt":
command = ["cmd", "/c", "echo", "hello"]
else:
command = [sys.executable, "-c", "print('hello')"]
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
stdout, stderr = process.communicate()
print(stdout.decode("utf-8").strip())
hello
Windows에서 cmd /c는 명령을 실행한 뒤 종료합니다. /k는 명령을 실행한 뒤에도 명령 처리기를 열린 상태로 두므로, 일반적으로 스크립트에는 적합하지 않습니다. 기본값인 shell=False에서는 Python이 지정된 실행 파일을 직접 시작하며, 인수를 해석할 추가 셸을 실행하지 않습니다. 그러나 그 실행 파일이 cmd인 경우, cmd는 여전히 명령줄을 해석하고 CMD 구문을 처리합니다. shell=False가 신뢰할 수 없는 값을 안전하게 만들어 주지는 않습니다. 신뢰할 수 없는 입력을 CMD 명령줄에 넣지 마세요. 가능하다면 독립 실행 파일을 인수 목록과 함께 직접 호출하는 방식을 선호하세요. 명령이 UTF-8이 아닌 텍스트를 출력한다면 캡처한 바이트를 해당 명령이 사용하는 인코딩으로 디코딩하세요. 호출 코드에서 성공과 실패를 구분해야 한다면 process.returncode를 확인하세요.
자세한 내용은 Python subprocess 문서를 참고하세요.