programing

'shell='의 실제 의미하위 프로세스에서 참'

newsource 2022. 9. 24. 12:40

'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 등이 있습니다.sendmailILS.

「」를 합니다.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 문자열일 bytesPython 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/shpid '아예'입니다.pid/bin/sh★★★★★★★★★★★★★★★★★★★★★★★★★★★★s.kill(), 죽인다, 죽인다./bin/shsleep아직 거기 있어요

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