하위 프로세스 실행 방법을 사용하여 Python에서 셸 명령을 실행하는 방법

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess는 새 프로세스를 만들고 입력 및 출력 데이터 스트림과 상호 작용하는 데 사용할 수 있는 내장 Python 모듈입니다. 간단히 말해서 셸 명령을 실행하고 일반적으로 Linux 파일 시스템의 다양한 bin 폴더에 흩어져 있는 실행 가능한 바이너리를 실행하는 데 사용할 수 있습니다. 실행 가능한 바이너리에 대한 전체 경로를 제공하고 바이너리와 연결된 명령줄 스위치를 사용할 수도 있습니다. 이 문서에서는 Python 앱에서 subprocess 모듈과 실행 방법을 사용하는 방법을 설명합니다. 이 기사의 모든 코드 샘플은 Ubuntu 20.04에서 Python 3.8.2로 테스트되었습니다.

Subprocess.run 메서드

Subprocess.run 메서드는 인수 목록을 사용합니다. 메서드가 호출되면 명령을 실행하고 프로세스가 완료될 때까지 기다렸다가 마지막에 CompletedProcess 개체를 반환합니다. CompletedProcess 개체는 stdout, stderr, 메서드를 호출하는 동안 사용된 원래 인수 및 반환 코드를 반환합니다. Stdout은 명령에 의해 생성된 데이터 스트림을 참조하는 반면 stderr은 프로그램 실행 중에 발생한 모든 오류를 나타냅니다. 0이 아닌 반환 코드(종료 코드)는 subprocess.run 메서드에서 실행된 명령에 오류가 있음을 의미합니다.







예 1: Subprocess.run 메서드를 사용하여 텍스트 파일의 출력 내용

아래 명령은 name=John 문자열이 포함되어 있다고 가정하고 data.txt 파일의 내용을 출력합니다.



수입 하위 프로세스
하위 프로세스.운영(['고양이', '데이터.txt'])

위의 코드를 실행하면 다음 출력이 반환됩니다.



이름=남자
완료된 프로세스(인수=['고양이', '데이터.txt'],반환 코드=0)

list 인수의 첫 번째 요소는 실행할 명령의 이름입니다. 목록에서 첫 번째 요소 다음에 오는 모든 요소는 명령줄 옵션 또는 스위치로 간주됩니다. 단일 대시 및 이중 대시도 사용하여 옵션을 정의할 수 있습니다. 예를 들어, 디렉토리에 있는 파일과 폴더를 나열하려면 코드는 subprocess.run([ls, -l]입니다. 이러한 대부분의 경우 쉘 명령에서 공백으로 구분된 인수를 개별 요소로 간주할 수 있습니다. subprocess.run 메소드에 제공된 목록입니다.





예 2: Subprocess.run 메서드의 출력 억제

subprocess.run 메소드의 출력을 억제하려면 stdout=subprocess.DEVNULL 및 stderr=subprocess.DEVNULL을 추가 인수로 제공해야 합니다.

수입 하위 프로세스

하위 프로세스.운영(['고양이', '데이터.txt'],표준 출력=하위 프로세스.DEVNULL,
표준 오류=하위 프로세스.DEVNULL)

위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.



CompletedProcess(args=['cat', 'data.txt'], returncode=0)

예 3: Subprocess.run 메서드의 출력 캡처

subprocess.run 메소드의 출력을 캡처하려면 capture_output=True라는 추가 인수를 사용하십시오.

수입 하위 프로세스
산출= 하위 프로세스.운영(['고양이', '데이터.txt'],캡처_출력=진실)
인쇄 (산출)

위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.

완료된 프로세스(인수=['고양이', '데이터.txt'],반환 코드=0,
표준 출력=NS'이름=존N',표준 오류=NS'')

output.stdout 및 output.stderr 메서드를 사용하여 stdout 및 stderr 값에 개별적으로 액세스할 수 있습니다. 출력은 바이트 시퀀스로 생성됩니다. 문자열을 출력으로 얻으려면 output.stdout.decode(utf-8) 메소드를 사용하십시오. 문자열 형식으로 출력을 가져오기 위해 subprocess.run 호출에 대한 추가 인수로 text=True를 제공할 수도 있습니다. 종료 상태 코드를 얻으려면 output.returncode 메서드를 사용할 수 있습니다.

예 4: Subprocess.run 메서드로 실행된 명령 실패 시 예외 발생

명령이 0이 아닌 상태로 종료될 때 예외를 발생시키려면 check=True 인수를 사용하십시오.

수입 하위 프로세스
하위 프로세스.운영(['고양이', '데이터.TX'],캡처_출력=진실,텍스트=진실,확인하다=진실)

위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.

CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: 명령 '['cat', 'data.tx']'
0이 아닌 종료 상태 1을 반환했습니다.

예제 5: Subprocess.run 메서드로 실행된 명령에 문자열 전달

input='string' 인수를 사용하여 subprocess.run 메서드로 실행할 명령에 문자열을 전달할 수 있습니다.

수입 하위 프로세스
산출= 하위 프로세스.운영(['고양이'], 입력='데이터.txt',캡처_출력=진실,
텍스트=진실,확인하다=진실)
인쇄 (산출)

위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.

CompletedProcess(args=['cat'], returncode=0, stdout='data.txt', stderr='')

보시다시피 위의 코드는 data.txt를 파일 객체가 아닌 문자열로 전달합니다. data.txt를 파일로 전달하려면 stdin 인수를 사용하십시오.

~와 함께 열려있는('데이터.txt') 같이NS:
산출= 하위 프로세스.운영(['고양이'],표준 입력=NS,캡처_출력=진실,
텍스트=진실,확인하다=진실)
인쇄 (산출)

위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.

CompletedProcess(args=['cat'], returncode=0, stdout='name=John ', stderr='')

예 6: Subprocess.run 메서드를 사용하여 셸에서 직접 명령 실행

기본 명령과 그 뒤에 오는 옵션에서 분할된 문자열을 사용하는 대신 명령을 있는 그대로 쉘에 직접 실행할 수 있습니다. 이렇게 하려면 추가 인수로 shell=True를 전달해야 합니다. 그러나 shell=True를 사용하면 보안 문제가 발생할 수 있으므로 Python 개발자는 권장하지 않습니다. 보안 영향에 대한 자세한 내용은 다음에서 읽을 수 있습니다. 여기 .

수입 하위 프로세스
하위 프로세스.운영('고양이 'data.txt'',껍데기=진실)

위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.

이름=존

결론

Python의 subprocess.run 메서드는 Python 자체 내에서 셸 명령을 실행할 수 있으므로 매우 강력합니다. 이것은 별도의 파일에 추가 셸 스크립트 코드를 가질 필요 없이 모든 코드를 파이썬 자체로 제한하는 데 도움이 됩니다. 그러나 파이썬 목록에서 셸 명령을 올바르게 토큰화하는 것은 매우 까다로울 수 있습니다. shlex.split() 메서드를 사용하여 간단한 셸 명령을 토큰화할 수 있지만 길고 복잡한 명령, 특히 파이프 기호가 있는 명령에서는 shlex가 명령을 올바르게 분할하지 못합니다. 이러한 경우 디버깅은 까다로운 문제가 될 수 있습니다. 이것을 피하기 위해 shell=True 인수를 사용할 수 있지만 이 작업과 관련된 특정 보안 문제가 있습니다.