'shell='의 실제 의미하위 프로세스에서 참'
'다'로 .subprocess
게 요.그런데 궁금한 게 있어요.
다음 코드:
callProcess = subprocess.Popen(['ls', '-l'], shell=True)
그리고.
callProcess = subprocess.Popen(['ls', '-l']) # without shell
아아아아아아아아아아아아아아아아아아악 는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.shell=True
셸을 통해 코드를 실행하는 것을 의미합니다.즉, 부재 시에는 프로세스가 직접 시작됩니다.
이 경우 어떤 프로세스를 실행하여 출력을 얻을 필요가 있습니다.셸 내부 또는 외부에서 호출하면 어떤 이점이 있습니까?
셸을 통해 호출하지 않는 이점은 '미스터리 프로그램'을 호출하지 않는다는 것입니다.에서는 환경변수 POSIX 서 on 。SHELL
「쉘되는 바이너리를 에서는, 의 하위는 뿐입니다.「 」는 「shell」입니다.Windows 의 본 셸 cmd.exe 를 사용합니다.
따라서 셸을 호출하면 사용자가 선택한 프로그램이 호출되며 플랫폼에 의존합니다.일반적으로 셸을 통한 호출을 피합니다.
셸을 통해 호출하면 셸의 일반적인 메커니즘에 따라 환경 변수와 파일글로브를 확장할 수 있습니다.POSIX 시스템에서는 셸이 파일글로브를 파일 목록으로 확장합니다.Windows 에서는, 파일 glob(예를 들면 「*.*」)은 셸에 의해서 전개되지 않습니다(커맨드 라인의 환경 변수는 cmd.exe 에 의해서 전개됩니다).
및는, 「」를 참조해 .ILS
셸을 통해 서브 프로그램 호출을 실행한 네트워크 서비스에 대한 1992-ish 공격.를 들면 다양한 various를,음, 음음음음음음 examples examples examples 등이 있습니다.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에서 문제가 발생할 수 있는 예를 다음에 나타냅니다.
>>> 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()
셸을 통해 프로그램을 실행한다는 것은 프로그램에 전달된 모든 사용자 입력이 호출된 셸의 구문 및 의미 규칙에 따라 해석된다는 것을 의미합니다.사용자는 이러한 규칙을 따라야 하기 때문에 이는 기껏해야 사용자에게 불편함을 줄 뿐입니다.예를 들어 따옴표나 공백과 같은 특수 셸 문자를 포함하는 경로는 이스케이프해야 합니다.최악의 경우 사용자가 임의의 프로그램을 실행할 수 있기 때문에 보안 유출이 발생합니다.
shell=True
는 단어 분할이나 파라미터 확장과 같은 특정 셸 기능을 사용하는 데 편리할 수 있습니다. 이러한 「」등)을 사용합니다.os.path.expandvars()
또는 """의 경우shlex
더 일을 .이는 더 많은 작업을 의미하지만 다른 문제를 방지합니다.
피하세요: 피하세요.shell=True
★★★★★★★★★★★★★★★★★★.
의 주의사항에 설명하고 .이러한 경고는, 「 」에도되어 있습니다.subprocess
문서를 참조해 주세요.그러나 이와 더불어 실행하고자 하는 프로그램을 시작하기 위해 셸을 시작하는 오버헤드는 종종 불필요하며 셸의 기능을 실제로 사용하지 않는 상황에서는 분명 어리석은 작업입니다.게다가 셸이나 셸이 제공하는 서비스에 대해 잘 모르는 경우, 복잡성이 더해져 공포에 떨게 됩니다.
셸과의 상호작용이 중요하지 않은 경우, Python 스크립트(미래의 자신일 수도 있고 아닐 수도 있음)의 리더와 유지관리자가 Python 스크립트와 셸 스크립트를 모두 이해해야 합니다.Python 모토인 "explicit is better implicit"을 기억하십시오. Python 코드가 동등한 셸 스크립트(그리고 종종 매우 간결함)보다 다소 더 복잡하더라도 셸을 제거하고 기능을 Python 네이티브 구성으로 교체하는 것이 더 나을 수 있습니다.외부 프로세스에서 이루어지는 작업을 최소화하고 가능한 한 자신의 코드 내에서 제어를 유지하는 것은 단순히 가시성을 향상시키고 원하는 부작용과 원하지 않는 부작용의 위험을 줄이기 위해 종종 좋은 아이디어입니다.
와일드카드 확장, 변수 보간 및 리다이렉션은 모두 네이티브 Python 구조로 쉽게 대체할 수 있습니다.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()
문자열 및 백슬래시 변환 셸 메타문자의 따옴표는 일반적으로 필요하지 않습니다(또는 유용하거나 정확합니다).따옴표로 셸 변수를 묶는 경우를 참조하십시오.
네가 직접 알아내고 싶지 않다면shlex.split()
이 기능을 사용할 수 있습니다.Python 표준 라이브러리의 일부이지만 셸 명령 문자열이 정적인 경우 개발 중에 한 번만 실행하고 결과를 스크립트에 붙여넣을 수 있습니다.
여러분은 피하려고 , 피하려고 합니다.Popen
의 중 subprocess
패키지는 당신이 원하는 대로 할 수 있습니다.최신 Python이 충분히 있다면 를 사용해야 합니다.
- ★★★★★★★★★★★★★★★★
check=True
이치노 - ★★★★★★★★★★★★★★★★
stdout=subprocess.PIPE
이치노 - ★★★★★★★★★★★★★★★★
text=True
( 다소 (의어)를 있다universal_newlines=True
Unicode(Unicode 문자열일bytes
Python 3)을 사용.
그렇지 않은 경우 많은 작업에서 명령어가 성공했는지 또는 수집할 출력이 없는지 확인하면서 명령어 출력을 얻어야 합니다.
이렇게 하다' '이렇게 하다', '이렇게 하다'까지.subprocess.run('echo "$HOME"', shell=True)
【윈도우즈】
위의 Anwser는 올바르게 설명하지만 충분히 명확하지는 않습니다.ps
이치노
import time
import subprocess
s = subprocess.Popen(["sleep 100"], shell=True)
print("start")
print(s.pid)
time.sleep(5)
s.kill()
print("finish")
실행해, 표시된다.
start
832758
finish
ㄹ게요를 하시면 됩니다.ps -auxf > 1
전에finish
, , 을 누릅니다.ps -auxf > 2
후에finish
1
cy 71209 0.0 0.0 9184 4580 pts/6 Ss Oct20 0:00 | \_ /bin/bash
cy 832757 0.2 0.0 13324 9600 pts/6 S+ 19:31 0:00 | | \_ python /home/cy/Desktop/test.py
cy 832758 0.0 0.0 2616 612 pts/6 S+ 19:31 0:00 | | \_ /bin/sh -c sleep 100
cy 832759 0.0 0.0 5448 532 pts/6 S+ 19:31 0:00 | | \_ sleep 100
지?를 직접 ? 직접 실행하는 대신sleep 100
실행됩니다.실제로 동작합니다./bin/sh
★pid
'아예'입니다.pid
/bin/sh
★★★★★★★★★★★★★★★★★★★★★★★★★★★★s.kill()
, 죽인다, 죽인다./bin/sh
sleep
아직 거기 있어요
2
cy 69369 0.0 0.0 533764 8160 ? Ssl Oct20 0:12 \_ /usr/libexec/xdg-desktop-portal
cy 69411 0.0 0.0 491652 14856 ? Ssl Oct20 0:04 \_ /usr/libexec/xdg-desktop-portal-gtk
cy 832646 0.0 0.0 5448 596 pts/6 S 19:30 0:00 \_ sleep 100
다음 을 할 수 있을까, 을 할 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수./bin/sh
【Linux】【Linux】【Linux】【Linux】【Linux】【Linux】【Linux】【Linux】키로 했습니다. 진짜 것 요.shell
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」/bin/bash
비슷해요.
「」와 셸·프로그래밍에 , 「Linux」의 「Linux」의 「Linux」의 「Linux」의 「Linux」의 「Linux」의 「Linux」의 「Linux」의 「Linux」의 「Linux」가 됩니다.sh
★★★★★★★★★★★★★★★★★」bash
를 직접 할 수 ls
/usr/bin/ls
.ls
당신을 위해 운영하고 있습니다.
은 '' 뒤에 입니다.$
환경변수로 사용합니다.이 두 개의 python 스크립트를 비교하여 자신을 찾을 수 있습니다.
subprocess.call(["echo $PATH"], shell=True)
subprocess.call(["echo", "$PATH"])
가장 중요한 것은 스크립트로서 Linux 명령을 실행할 수 있다는 것입니다.를 들면, 「」등if
else
네이티브 가 아닙니다.
shell=False를 사용하여 명령어를 목록으로 제공한다고 가정합니다.일부 악의적인 사용자가 'rm' 명령을 삽입하려고 했습니다.'rm'이 인수로 해석되어 'ls'가 'rm'이라는 이름의 파일을 찾으려 합니다.
>>> subprocess.run(['ls','-ld','/home','rm','/etc/passwd'])
ls: rm: No such file or directory
-rw-r--r-- 1 root root 1172 May 28 2020 /etc/passwd
drwxr-xr-x 2 root root 4096 May 29 2020 /home
CompletedProcess(args=['ls', '-ld', '/home', 'rm', '/etc/passwd'], returncode=1)
shell=False는 입력을 적절하게 제어하지 않으면 기본적으로 안전하지 않습니다.위험한 명령어는 실행할 수 있습니다.
>>> subprocess.run(['rm','-rf','/home'])
CompletedProcess(args=['rm', '-rf', '/home'], returncode=0)
>>> subprocess.run(['ls','-ld','/home'])
ls: /home: No such file or directory
CompletedProcess(args=['ls', '-ld', '/home'], returncode=1)
>>>
대부분의 응용 프로그램을 컨테이너 환경에서 쓰고 있으며 어떤 셸이 호출되는지 알고 있으며 사용자 입력을 받지 않습니다.
따라서 제 사용 사례에서는 보안상의 위험은 없습니다.또, 긴 일련의 커맨드를 작성하는 것도 훨씬 쉬워집니다.내가 틀리지 않았으면 좋겠다.
언급URL : https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess
'programing' 카테고리의 다른 글
vuex 및 Vue-native-websocket 플러그인에서 WebSockets 데이터 수신 (0) | 2022.09.24 |
---|---|
JUnit 테스트를 통해 SLF4J(로그백 포함) 로깅을 대행 수신하려면 어떻게 해야 합니까? (0) | 2022.09.24 |
PDO 버전 Atribut은 어디에서 유래합니까? (0) | 2022.09.24 |
여러 개의 하위 행을 하나의 행 MYSQL로 결합 (0) | 2022.09.24 |
MySQL과 MariaDB 쿼리 실행 계획의 차이점 (0) | 2022.09.24 |