서브 프로세스에서 'shell = True'의 실제 의미
subprocess
모듈로 다른 프로세스를 호출하고 있습니다. 그러나 질문이 있습니다.
다음 코드에서 :
callProcess = subprocess.Popen(['ls', '-l'], shell=True)
과
callProcess = subprocess.Popen(['ls', '-l']) # without shell
둘 다 작동합니다. 문서를 읽은 후에 shell=True
쉘을 통해 코드를 실행 한다는 것을 알게되었습니다 . 즉, 부재시 프로세스가 직접 시작됩니다.
그래서 내 경우에 선호해야 할 것은-프로세스를 실행하고 결과를 얻어야합니다. 쉘 내부 또는 외부에서 호출하면 어떤 이점이 있습니까?
쉘을 통해 전화하지 않는 이점은 '미스터리 프로그램'을 호출하지 않는다는 것입니다. POSIX에서 환경 변수 SHELL
는 어떤 바이너리가 "쉘"로 호출되는지를 제어합니다. Windows에는 bourne shell 하위 항목이 없으며 cmd.exe 만 있습니다.
따라서 쉘을 호출하면 사용자가 선택한 프로그램이 호출되며 플랫폼에 따라 다릅니다. 일반적으로 쉘을 통한 호출을 피하십시오.
쉘을 통해 호출하면 쉘의 일반적인 메커니즘에 따라 환경 변수 및 파일 글로브를 확장 할 수 있습니다. POSIX 시스템에서 쉘은 파일 glob을 파일 목록으로 확장합니다. Windows에서는 파일 glob (예 : "*. *")이 셸에 의해 확장되지 않습니다 (그러나 명령 행의 환경 변수 는 cmd.exe에 의해 확장 됨).
환경 변수 확장 및 파일 글로브를 원한다고 생각 ILS
되면 쉘을 통해 서브 프로그램 호출을 수행 한 네트워크 서비스에 대한 1992 년 의 공격을 조사하십시오 . 예를 들어 다양한 sendmail
백도어가 포함 ILS
됩니다.
요약하면을 사용하십시오 shell=False
.
>>> import subprocess
>>> subprocess.call('echo $HOME')
Traceback (most recent call last):
...
OSError: [Errno 2] No such file or directory
>>>
>>> subprocess.call('echo $HOME', shell=True)
/user/khong
0
shell 인수를 true 값으로 설정하면 하위 프로세스가 중간 쉘 프로세스를 생성하고 명령을 실행하도록 지시합니다. 즉, 중간 쉘을 사용한다는 것은 명령, 문자열, 변수, 글로브 패턴 및 기타 특수 쉘 기능이 명령이 실행되기 전에 처리됨을 의미합니다. 이 예에서 $ HOME은 echo 명령 전에 처리되었습니다. 실제로 이것은 쉘 확장이있는 명령의 경우이며 ls -l 명령은 간단한 명령으로 간주됩니다.
소스 : 서브 프로세스 모듈
쉘을 통해 프로그램을 실행한다는 것은 프로그램에 전달 된 모든 사용자 입력이 호출 된 쉘의 구문과 의미 규칙에 따라 해석됨을 의미합니다. 기껏해야 사용자가 이러한 규칙을 준수해야하기 때문에 사용자에게 불편을 초래할뿐입니다. 예를 들어, 따옴표 나 공백과 같은 특수 쉘 문자가 포함 된 경로는 이스케이프되어야합니다. 최악의 경우 사용자가 임의의 프로그램을 실행할 수 있기 때문에 보안 누출이 발생합니다.
shell=True
단어 분할 또는 매개 변수 확장과 같은 특정 쉘 기능을 사용하는 것이 편리한 경우가 있습니다. 그러나 이러한 기능이 필요한 경우 다른 모듈을 사용하십시오 (예 : os.path.expandvars()
매개 변수 확장 또는 shlex
워드 분할). 이것은 더 많은 작업을 의미하지만 다른 문제는 피합니다.
한마디로 : 피하십시오 shell=True
.
Shell = True에서 문제가 발생할 수있는 예는 다음과 같습니다.
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / # THIS WILL DELETE EVERYTHING IN ROOT PARTITION!!!
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
여기에서 문서를 확인하십시오 : subprocess.call ()
여기에있는 다른 답변은 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로 이식 할 수 없습니다.
참고 URL : https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess
'Programing' 카테고리의 다른 글
MVVM을 사용하여 WPF에서 대화 상자 처리 (0) | 2020.04.16 |
---|---|
REST 웹 서비스를 사용하여 메타 데이터가있는 파일을 어떻게 업로드합니까? (0) | 2020.04.16 |
GROUP BY 절에 나타나거나 집계 함수에 사용되어야합니다. (0) | 2020.04.16 |
java.util.Set에 get (int index)이없는 이유는 무엇입니까? (0) | 2020.04.16 |
서브 클래스는 개인 필드를 상속합니까? (0) | 2020.04.16 |