여기에있는 다른 답변은 subprocess
문서에 언급 된 보안주의 사항을 적절히 설명합니다 . 그러나 그 외에도 쉘을 시작하여 실행하려는 프로그램을 시작하는 오버 헤드는 종종 쉘 기능을 실제로 사용하지 않는 상황에서는 불필요하고 어리 석습니다. 또한, 특히 숨겨진 쉘이나 제공하는 서비스에 익숙하지 않은 경우 숨겨진 추가 복잡성이 두렵 습니다.
쉘과의 상호 작용이 사소한 것이 아니라면, 이제 파이썬 스크립트와 쉘 스크립트를 모두 이해하기 위해 파이썬 스크립트의 독자와 관리자 (나중에있을 수도 있고 아닐 수도 있음)가 필요합니다. "명시적인 것이 묵시적인 것보다 낫다" 라는 파이썬 모토를 기억하십시오 . 파이썬 코드가 동등한 (그리고 종종 매우 간결한) 쉘 스크립트보다 다소 복잡 할지라도 쉘을 제거하고 기능을 원시 파이썬 구문으로 대체하는 것이 좋습니다. 외부 프로세스에서 수행되는 작업을 최소화하고 가능한 한 자신의 코드 내에서 제어를 유지하는 것은 가시성을 향상시키고 원하거나 원치 않는 부작용의 위험을 줄임으로써 종종 좋은 생각입니다.
와일드 카드 확장, 변수 보간 및 리디렉션은 모두 기본 Python 구문으로 간단하게 대체 할 수 있습니다. 파이썬에서 일부 또는 전부를 합리적으로 다시 작성할 수없는 복잡한 쉘 파이프 라인은 아마도 쉘 사용을 고려할 수있는 상황입니다. 여전히 성능 및 보안 관련 사항을 이해해야합니다.
사소한 경우에는 피하기 위해 shell=True
간단히 교체하십시오.
subprocess.Popen("command -with -options 'like this' and\\ an\\ argument", shell=True)
와
subprocess.Popen(['command', '-with','-options', 'like this', 'and an argument'])
첫 번째 인수가 전달할 문자열 목록이며 문자열 execvp()
및 백 슬래시 이스케이프 쉘 메타 문자를 인용하는 것이 일반적으로 필요하지 않은 (유용하거나 올바른) 방법에 주목 하십시오. 어쩌면 쉘 변수를 따옴표로 묶을 때를 참조하십시오 .
따로, 패키지 Popen
의 가장 간단한 래퍼 중 하나가 원하는 것을 수행하는 경우가 종종 subprocess
있습니다. 최근에 충분한 파이썬을 가지고 있다면 아마도을 사용해야 subprocess.run
합니다.
- 함께
check=True
명령이 실패 실행 한 경우 그것이 실패합니다.
- 로
stdout=subprocess.PIPE
그 명령의 출력을 캡처합니다.
- 다소 모호하게도
universal_newlines=True
출력을 적절한 유니 코드 문자열로 디코딩합니다 ( bytes
Python 3의 경우 시스템 인코딩에 있습니다).
그렇지 않은 경우, 많은 태스크의 경우, check_output
명령이 성공했는지 확인하거나 check_call
수집 할 출력이 없는지 명령에서 출력을 얻으려고합니다 .
David Korn의 인용을 인용하겠습니다. "휴대용 쉘 스크립트보다 이식 가능한 쉘을 작성하는 것이 더 쉽습니다." 심지어 subprocess.run('echo "$HOME"', shell=True)
Windows로 이식 할 수 없습니다.
-l
전달 됩니다 . 대부분의 경우 목록 대신 문자열 인수를 사용해야 합니다./bin/sh
ls
shell=True
shell=True