etc./StackOverFlow

프로그램을 실행하거나 시스템 명령을 호출하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2021. 9. 22. 13:27
반응형

질문자 :freshWoWer


Python 스크립트 내에서 외부 명령(Unix 셸 또는 Windows 명령 프롬프트에서 입력한 것처럼)을 어떻게 호출합니까?



답변자 : David Cournapeau


표준 라이브러리에서 subprocess 모듈을 사용합니다.

 import subprocess subprocess.run(["ls", "-l"])

os.system subprocess.run 의 장점은 더 유연하다는 것입니다( stdout , stderr , "실제" 상태 코드 , 더 나은 오류 처리 등을 얻을 수 있습니다...).

os.system 대한 문서 에서도 subprocess 를 사용할 것을 권장합니다.

subprocess 모듈은 새로운 프로세스를 생성하고 결과를 검색하기 위한 보다 강력한 기능을 제공합니다. 이 기능을 사용하는 것보다 해당 모듈을 사용하는 것이 좋습니다. 몇 가지 유용한 레시피 subprocess 문서의 하위 프로세스 모듈로 이전 함수 교체 섹션을 참조하세요.

Python 3.4 및 이전 버전에서는 .run subprocess.call 사용합니다.

 subprocess.call(["ls", "-l"])


답변자 : Eli Courtwright


다음은 외부 프로그램을 호출하는 방법과 각각의 장단점에 대한 요약입니다.

  1. os.system("some_command with args") 는 명령과 인수를 시스템 쉘에 전달합니다. 실제로 이러한 방식으로 여러 명령을 한 번에 실행할 수 있고 파이프 및 입력/출력 리디렉션을 설정할 수 있기 때문에 이것은 좋습니다. 예를 들어:

     os.system("some_command < input_file | another_command > output_file")

    그러나 이것이 편리하기는 하지만 공백 등과 같은 셸 문자의 이스케이프를 수동으로 처리해야 합니다. 다른 한편, 이것은 또한 단순히 쉘 명령이고 실제로는 외부 프로그램이 아닌 명령을 실행할 수 있게 합니다. 설명서를 참조하십시오.

  2. stream = os.popen("some_command with args") 는 해당 프로세스의 표준 입력/출력에 액세스하는 데 사용할 수 있는 파일과 같은 객체를 제공한다는 점을 제외하고 os.system 과 동일한 작업을 수행합니다. 모두 약간 다르게 i/o를 처리하는 popen의 3가지 다른 변형이 있습니다. 모든 것을 문자열로 전달하면 명령이 쉘로 전달됩니다. 목록으로 전달하면 아무 것도 탈출하는 것에 대해 걱정할 필요가 없습니다. 설명서를 참조하십시오.

  3. subprocess 모듈의 Popen 클래스입니다. os.popen 대체하기 위한 것이지만 너무 포괄적이기 때문에 약간 더 복잡하다는 단점이 있습니다. 예를 들어 다음과 같이 말할 수 있습니다.

     print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()

    대신에

     print os.popen("echo Hello World").read()

    그러나 4개의 다른 popen 함수 대신에 하나의 통합된 클래스에 모든 옵션이 있는 것이 좋습니다. 설명서를 참조하십시오.

  4. subprocess 모듈의 call 함수입니다. 이것은 기본적으로 Popen 클래스와 같으며 모든 동일한 인수를 사용하지만 명령이 완료될 때까지 기다렸다가 반환 코드를 제공합니다. 예를 들어:

     return_code = subprocess.call("echo Hello World", shell=True)

    설명서를 참조하십시오.

  5. Python 3.5 이상을 사용하는 경우 위와 비슷하지만 훨씬 더 유연하고 명령 실행이 완료되면 CompletedProcess subprocess.run

  6. os 모듈에는 C 프로그램에 있는 모든 fork/exec/spawn 기능도 있지만 직접 사용하지 않는 것이 좋습니다.

subprocess 모듈은 아마도 당신이 사용하는 것이어야 합니다.

마지막으로, 쉘이 실행할 최종 명령을 문자열로 전달하는 모든 메소드에 대해 이스케이프에 대한 책임은 사용자에게 있음을 유의하십시오. 전달한 문자열의 일부를 완전히 신뢰할 수 없는 경우 심각한 보안 문제가 있습니다. 예를 들어, 사용자가 문자열의 일부/일부를 입력하는 경우입니다. 확실하지 않은 경우 이러한 메서드를 상수와 함께 사용하십시오. 의미에 대한 힌트를 제공하기 위해 다음 코드를 고려하십시오.

 print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()

사용자가 전체 파일 시스템을 지울 수 my mama didnt love me && rm -rf / "를 입력한다고 상상해 보십시오.



답변자 : EmmEff


일반적인 구현:

 import subprocess p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in p.stdout.readlines(): print line, retval = p.wait()

stdout 데이터로 원하는 작업을 자유롭게 수행할 수 있습니다. 사실, 해당 매개변수( stdout=stderr= os.system() 처럼 작동합니다.



답변자 : newtover


호출 프로세스에서 하위 프로세스 분리(백그라운드에서 하위 프로세스 시작)에 대한 몇 가지 힌트.

CGI 스크립트에서 긴 작업을 시작하려고 한다고 가정합니다. 즉, 자식 프로세스는 CGI 스크립트 실행 프로세스보다 오래 살아야 합니다.

하위 프로세스 모듈 문서의 고전적인 예는 다음과 같습니다.

 import subprocess import sys # Some code here pid = subprocess.Popen([sys.executable, "longtask.py"]) # Call subprocess # Some more code here

여기서 아이디어는 longtask.py가 완료될 때까지 'call subprocess' 줄에서 기다리고 싶지 않다는 것입니다. 그러나 예제의 'some more code here' 행 다음에 어떤 일이 발생하는지 명확하지 않습니다.

대상 플랫폼은 FreeBSD였지만 개발은 Windows에서 했기 때문에 Windows에서 먼저 문제에 직면했습니다.

Windows(Windows XP)에서 부모 프로세스는 longtask.py가 작업을 완료할 때까지 완료되지 않습니다. CGI 스크립트에서 원하는 것이 아닙니다. 문제는 파이썬에만 국한된 것이 아닙니다. PHP 커뮤니티에서 문제는 동일합니다.

해결책은 DETACHED_PROCESS 프로세스 생성 플래그 를 Windows API의 기본 CreateProcess 함수에 전달하는 것입니다. pywin32를 설치했다면 win32process 모듈에서 플래그를 가져올 수 있습니다. 그렇지 않으면 직접 정의해야 합니다.

 DETACHED_PROCESS = 0x00000008 pid = subprocess.Popen([sys.executable, "longtask.py"], creationflags=DETACHED_PROCESS).pid

/* UPD 2015.10.27 @eryksun이 아래 주석에서 의미상 올바른 플래그는 CREATE_NEW_CONSOLE(0x00000010)임을 명시합니다. */

FreeBSD에는 또 다른 문제가 있습니다. 상위 프로세스가 완료되면 하위 프로세스도 완료됩니다. 그리고 그것은 CGI 스크립트에서도 원하는 것이 아닙니다. 일부 실험에서는 sys.stdout을 공유하는 데 문제가 있는 것으로 나타났습니다. 그리고 작동 솔루션은 다음과 같습니다.

 pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

나는 다른 플랫폼에서 코드를 확인하지 않았고 FreeBSD에서 동작의 이유를 모릅니다. 아시는 분 계시면 아이디어 공유 부탁드립니다. Python에서 백그라운드 프로세스 시작에 대한 인터넷 검색은 아직 빛을 발산하지 않습니다.



답변자 : nimish


import os os.system("your command")

명령이 정리되지 않기 때문에 이것은 위험합니다. 'os' 및 'sys' 모듈에 대한 관련 문서는 Google에 맡기겠습니다. 비슷한 일을 하는 많은 함수(exec* 및 spawn*)가 있습니다.



답변자 : sirwart


os.system 대신에 subprocess 모듈을 사용하는 것이 좋습니다. 쉘 이스케이프를 수행하므로 훨씬 안전하기 때문입니다.

 subprocess.call(['ping', 'localhost'])


답변자 : Alexandra Franks


import os cmd = 'ls -al' os.system(cmd)

명령의 결과를 반환하려면 os.popen 을 사용할 수 있습니다. 그러나 이것은 다른 답변에서 잘 다룬 subprocess 모듈 을 위해 버전 2.6부터 더 이상 사용되지 않습니다.



답변자 : Tom Fuller


Python으로 외부 명령을 호출할 수 있는 다양한 라이브러리가 있습니다. 각 라이브러리에 대해 설명을 제공하고 외부 명령을 호출하는 예를 보여주었습니다. 예제로 사용한 명령은 ls -l (모든 파일 나열)입니다. 내가 나열하고 각 라이브러리에 대한 문서를 링크한 라이브러리에 대해 더 알고 싶다면.

출처

이것들은 모든 라이브러리입니다

이것이 당신이 사용할 라이브러리를 결정하는 데 도움이 되기를 바랍니다. :)

하위 프로세스

하위 프로세스를 사용하면 외부 명령을 호출하고 입력/출력/오류 파이프(stdin, stdout 및 stderr)에 연결할 수 있습니다. 하위 프로세스는 명령 실행을 위한 기본 선택이지만 때로는 다른 모듈이 더 좋습니다.

 subprocess.run(["ls", "-l"]) # Run command subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command

운영 체제

os는 "운영 체제 종속 기능"에 사용됩니다. os.systemos.popen 외부 명령을 호출하는 데 사용할 수도 있습니다(참고: subprocess.popen도 있습니다). subprocess.run 을 사용할 필요가 없거나 사용 방법을 모르는 사람들을 위한 간단한 대안입니다.

 os.system("ls -l") # Run command os.popen("ls -l").read() # This will run the command and return any output

sh는 프로그램을 함수인 것처럼 호출할 수 있는 하위 프로세스 인터페이스입니다. 이것은 명령을 여러 번 실행하려는 경우에 유용합니다.

 sh.ls("-l") # Run command normally ls_cmd = sh.Command("ls") # Save command as a variable ls_cmd() # Run command as if it were a function

plumbum은 "스크립트와 같은" Python 프로그램을 위한 라이브러리입니다. sh 에서와 같이 함수와 같은 프로그램을 호출할 수 있습니다. Plumbum은 셸 없이 파이프라인을 실행하려는 경우에 유용합니다.

 ls_cmd = plumbum.local("ls -l") # Get command ls_cmd() # Run command

기대하다

pexpect를 사용하면 자식 응용 프로그램을 생성하고 제어하고 출력에서 패턴을 찾을 수 있습니다. 이것은 Unix에서 tty를 예상하는 명령에 대한 하위 프로세스에 대한 더 나은 대안입니다.

 pexpect.run("ls -l") # Run command as normal child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application child.expect('Password:') # When this is the output child.sendline('mypassword')

구조

fabric은 Python 2.5 및 2.7 라이브러리입니다. 로컬 및 원격 셸 명령을 실행할 수 있습니다. Fabric은 SSH(Secure Shell)에서 명령을 실행하기 위한 간단한 대안입니다.

 fabric.operations.local('ls -l') # Run command as normal fabric.operations.local('ls -l', capture = True) # Run command and receive output

사절

Envoy는 "인간을 위한 하위 프로세스"로 알려져 있습니다. subprocess 모듈 주변의 편리한 래퍼로 사용됩니다.

 r = envoy.run("ls -l") # Run command r.std_out # Get output

명령

commands os.popen 에 대한 래퍼 함수가 포함되어 subprocess 가 더 나은 대안이기 때문에 Python 3에서 제거되었습니다.



답변자 : Community Wiki


표준 라이브러리와 함께

하위 프로세스 모듈 (Python 3)을 사용합니다.

 import subprocess subprocess.run(['ls', '-l'])

권장되는 표준 방법입니다. 그러나 더 복잡한 작업(파이프, 출력, 입력 등)은 구성하고 작성하는 데 지루할 수 있습니다.

Python 버전에 대한 참고 사항: 여전히 Python 2를 사용하는 경우 subprocess.call 이 비슷한 방식으로 작동합니다.

ProTip: shlex.split run , call 및 기타 subprocess 기능에 대한 명령을 구문 분석하는 데 도움이 될 수 있습니다.

 import shlex import subprocess subprocess.run(shlex.split('ls -l'))

외부 종속성

외부 종속성을 상관하지 않는 경우, 사용 :

 from plumbum.cmd import ifconfig print(ifconfig['wlan0']())

최고의 subprocess 래퍼입니다. 크로스 플랫폼입니다. 즉, Windows 및 Unix 계열 시스템에서 모두 작동합니다. pip install plumbum .

또 다른 인기 있는 라이브러리는 sh입니다 .

 from sh import ifconfig print(ifconfig('wlan0'))

그러나 sh 는 Windows 지원을 중단했기 때문에 예전만큼 굉장하지 않습니다. pip install sh .



답변자 : Jorge E. Cardona


저는 항상 다음과 같은 fabric

 from fabric.operations import local result = local('ls', capture=True) print "Content:/n%s" % (result, )

그러나 이것은 좋은 도구인 것 같습니다: sh (Python 하위 프로세스 인터페이스) .

예를 살펴보십시오.

 from sh import vgdisplay print vgdisplay() print vgdisplay('-v') print vgdisplay(v=True)


답변자 : athanassis


"pexpect" Python 라이브러리도 확인하십시오.

외부 프로그램/명령, 심지어 ssh, ftp, telnet 등을 대화식으로 제어할 수 있습니다. 다음과 같이 입력하면 됩니다.

 child = pexpect.spawn('ftp 192.168.0.24') child.expect('(?i)name .*: ') child.sendline('anonymous') child.expect('(?i)password')


답변자 : Facundo Casco


호출하는 명령의 출력이 필요한 경우 subprocess.check_output (Python 2.7+)을 사용할 수 있습니다.

 >>> subprocess.check_output(["ls", "-l", "/dev/null"]) 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'

또한 shell 매개변수에 유의하십시오.

쉘이 True 이면 지정된 명령이 쉘을 통해 실행됩니다. 이것은 대부분의 시스템 셸에서 제공하는 향상된 제어 흐름을 위해 Python을 주로 사용하고 여전히 셸 파이프, 파일 이름 와일드카드, 환경 변수 확장 및 ~ 사용자 홈으로의 확장과 같은 다른 셸 기능에 대한 편리한 액세스를 원하는 경우에 유용할 수 있습니다. 예배 규칙서. 그러나 Python 자체는 많은 쉘과 유사한 기능의 구현을 제공합니다(특히 glob , fnmatch , os.walk() , os.path.expandvars() , os.path.expanduser()shutil ).



답변자 : Joe


업데이트:

subprocess.run 은 코드가 이전 Python 버전과의 호환성을 유지할 필요가 없는 경우 Python 3.5 에서 권장되는 접근 방식입니다. Envoy와 유사한 사용 편의성과 일관성을 제공합니다. (파이핑은 그렇게 간단하지 않습니다. 방법은 이 질문을 참조하십시오.)

다음은 설명서 의 몇 가지 예입니다.

프로세스 실행:

 >>> subprocess.run(["ls", "-l"]) # Doesn't capture output CompletedProcess(args=['ls', '-l'], returncode=0)

실행 실패 시 발생:

 >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

캡처 출력:

 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

원래 답변:

Envoy를 사용하는 것이 좋습니다. 하위 프로세스의 래퍼로, 이전 모듈과 기능 을 교체하는 것을 목표로 합니다. Envoy는 인간을 위한 하위 프로세스입니다.

README의 사용 예:

 >>> r = envoy.run('git config', data='data to pipe in', timeout=2) >>> r.status_code 129 >>> r.std_out 'usage: git config [options]' >>> r.std_err ''

파이프 물건도 주변에:

 >>> r = envoy.run('uptime | pbcopy') >>> r.command 'pbcopy' >>> r.status_code 0 >>> r.history [<Response 'uptime'>]


답변자 : Usman Khan


이것이 내가 명령을 실행하는 방법입니다. 이 코드에는 필요한 모든 것이 있습니다.

 from subprocess import Popen, PIPE cmd = "ls -l ~/" p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE) out, err = p.communicate() print "Return code: ", p.returncode print out.rstrip(), err.rstrip()


답변자 : Ben Hoffstein


하위 프로세스를 사용하십시오.

...또는 매우 간단한 명령의 경우:

 import os os.system('cat testfile')


답변자 : Aaron Hall


Python에서 프로그램을 실행하거나 시스템 명령을 호출하는 방법

간단하게 CompletedProcess 객체를 반환하는 subprocess.run 사용합니다.

 >>> from subprocess import run >>> from shlex import split >>> completed_process = run(split('python --version')) Python 3.8.8 >>> completed_process CompletedProcess(args=['python', '--version'], returncode=0)

( run 은 사전적으로 구문 분석된 쉘 인수의 목록을 원합니다 - 이것은 공백으로 구분된 쉘에 입력하는 것입니다. 그러나 공백이 인용된 위치는 아닙니다. 따라서 특수 기능인 split 사용하여 문자 그대로 입력할 것을 분할하십시오. 당신의 껍질에)

왜요?

Python 3.5부터 문서는 subprocess.run을 권장합니다.

하위 프로세스를 호출하는 데 권장되는 접근 방식은 처리할 수 있는 모든 사용 사례에 대해 run() 함수를 사용하는 것입니다. 고급 사용 사례의 경우 기본 Popen 인터페이스를 직접 사용할 수 있습니다.

다음은 가능한 가장 간단한 사용법의 예입니다. 요청한 대로 정확히 수행됩니다.

 >>> from subprocess import run >>> from shlex import split >>> completed_process = run(split('python --version')) Python 3.8.8 >>> completed_process CompletedProcess(args=['python', '--version'], returncode=0)

run 은 명령이 성공적으로 완료될 때까지 기다린 다음 CompletedProcess 개체를 반환합니다. 대신 TimeoutExpired timeout= 인수를 제공한 경우) 또는 CalledProcessError check=True 를 전달한 경우)를 발생시킬 수 있습니다.

위의 예에서 유추할 수 있듯이 stdout과 stderr은 모두 기본적으로 자신의 stdout과 stderr로 연결됩니다.

반환된 객체를 검사하고 주어진 명령과 반환 코드를 볼 수 있습니다.

 >>> completed_process.args ['python', '--version'] >>> completed_process.returncode 0

출력 캡처

출력을 캡처하려면 subprocess.PIPE 를 적절한 stderr 또는 stdout 전달할 수 있습니다.

 >>> from subprocess import PIPE >>> completed_process = run(shlex.split('python --version'), stdout=PIPE, stderr=PIPE) >>> completed_process.stdout b'Python 3.8.8\n' >>> completed_process.stderr b''

그리고 해당 속성은 바이트를 반환합니다.

명령 목록 전달

명령 문자열을 수동으로 제공하는 것(질문에서 제안하는 것처럼)에서 프로그래밍 방식으로 빌드된 문자열을 제공하는 것으로 쉽게 이동할 수 있습니다. 프로그래밍 방식으로 문자열을 작성하지 마십시오. 이것은 잠재적인 보안 문제입니다. 입력을 신뢰하지 않는다고 가정하는 것이 좋습니다.

 >>> import textwrap >>> args = ['python', textwrap.__file__] >>> cp = run(args, stdout=subprocess.PIPE) >>> cp.stdout b'Hello there.\n This is indented.\n'

참고로 args 만 위치적으로 전달되어야 합니다.

전체 서명

다음은 소스의 실제 서명이며 help(run) 로 표시됩니다.

 def run(*popenargs, input=None, timeout=None, check=False, **kwargs):

popenargskwargs 받는 주어진다 Popen 생성자입니다. input 은 하위 프로세스의 stdin으로 파이프되는 universal_newlines=True 지정하는 경우 유니코드)일 수 있습니다.

문서는 timeout=check=True 내가 할 수 있는 것보다 더 잘 설명합니다.

timeout 인수는 Popen.communicate()에 전달됩니다. 시간 초과가 만료되면 자식 프로세스가 종료되고 대기합니다. TimeoutExpired 예외는 자식 프로세스가 종료된 후 다시 발생합니다.

검사가 true이고 프로세스가 0이 아닌 종료 코드로 종료되면 CalledProcessError 예외가 발생합니다. 해당 예외의 속성은 인수, 종료 코드, 캡처된 경우 stdout 및 stderr을 보유합니다.

check=True 대한 이 예는 내가 생각해낼 수 있는 것보다 낫습니다.

 >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

확장 서명

문서에 제공된 확장된 서명은 다음과 같습니다.

 subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)

이것은 args 목록만 위치적으로 전달되어야 함을 나타냅니다. 따라서 나머지 인수를 키워드 인수로 전달하십시오.

팝픈

대신 Popen 을 사용할 때? 나는 주장만으로 유스 케이스를 찾는 데 어려움을 겪을 것입니다. Popen 직접 사용 poll , 'send_signal', 'terminate' 및 'wait'를 포함한 메서드에 액세스할 수 있습니다.

다음 은 소스에 제공된 Popen 서명입니다. 나는 이것이 정보의 가장 정확한 캡슐화라고 생각합니다 ( help(Popen) 과 반대).

 def __init__(self, args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, user=None, group=None, extra_groups=None, encoding=None, errors=None, text=None, umask=-1, pipesize=-1):

그러나 더 많은 정보를 제공 하는 것은 Popen 문서입니다 .

 subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None)

새 프로세스에서 자식 프로그램을 실행합니다. POSIX에서 클래스는 os.execvp()와 유사한 동작을 사용하여 자식 프로그램을 실행합니다. Windows에서 클래스는 Windows CreateProcess() 함수를 사용합니다. Popen에 대한 인수는 다음과 같습니다.

Popen 에 대한 나머지 문서를 이해하는 것은 독자를 위한 연습으로 남겨둘 것입니다.



답변자 : Martin W


os.system 은 괜찮지만 구식입니다. 또한 그다지 안전하지 않습니다. subprocess 시도하십시오. subprocess 는 sh를 직접 호출하지 않으므로 os.system 보다 더 안전합니다.

더 많은 정보를 얻을 여기 .



답변자 : stuckintheshuck


플럼범도 있다

 >>> from plumbum import local >>> ls = local["ls"] >>> ls LocalCommand(<LocalPath /bin/ls>) >>> ls() u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n' >>> notepad = local["c:\\windows\\notepad.exe"] >>> notepad() # Notepad window pops up u'' # Notepad window is closed by user, command returns


답변자 : fameman


2018년 6월 27일에 출시된 Python 3.7.0( https://docs.python.org/3/whatsnew/3.7.html ) 부터 가장 강력하면서도 간단하게 원하는 결과를 얻을 수 있습니다. 이 답변은 다양한 옵션에 대한 필수 요약을 짧은 방식으로 보여주기 위한 것입니다. 자세한 답변은 다른 답변을 참조하세요.


TL;DR 2021년

os.system(...) 의 가장 큰 장점은 단순성입니다. subprocess 는 특히 Python 3.5에서 더 좋고 여전히 사용하기 쉽습니다.

 import subprocess subprocess.run("ls -a", shell=True)

참고: 이것은 귀하의 질문에 대한 정확한 답변입니다 - 명령 실행

껍데기처럼


선호하는 방법

가능하면 셸 오버헤드를 제거하고 명령을 직접 실행합니다(목록 필요).

 import subprocess subprocess.run(["help"]) subprocess.run(["ls", "-a"])

목록에 프로그램 인수를 전달합니다. 공백이 포함된 인수의 경우 \" 이스케이프를 포함하지 마십시오.


고급 사용 사례

출력 확인

다음 코드는 그 자체로 말합니다.

 import subprocess result = subprocess.run(["ls", "-a"], capture_output=True, text=True) if "stackoverflow-logo.png" in result.stdout: print("You're a fan!") else: print("You're not a fan?")

result.stdout 은 오류를 제외한 모든 일반 프로그램 출력입니다. 그것들을 얻으려면 result.stderr 을 읽으십시오.

capture_output=True - 캡처를 켭니다. 그렇지 않으면 result.stderrresult.stdoutNone 됩니다. Python 3.7 부터 사용 가능합니다.

text=True - 수신된 바이너리 데이터를 쉽게 작업할 수 있는 Python 문자열로 변환하는 Python 3.7에 추가된 편의 인수입니다.

리턴코드 확인

하다

 if result.returncode == 127: print("The program failed for some weird reason") elif result.returncode == 0: print("The program succeeded") else: print("The program failed unexpectedly")

프로그램이 성공했는지(returncode == 0) 확인하고 그렇지 않으면 예외를 throw하려는 경우 더 편리한 기능이 있습니다.

 result.check_returncode()

하지만 Python이므로 자동으로 동일한 작업을 수행하는 훨씬 더 편리한 인수 check

 result = subprocess.run(..., check=True)

stderr은 stdout 안에 있어야 합니다.

오류를 포함하여 stdout 내부에 모든 프로그램 출력을 원할 수 있습니다. 이를 수행하려면 다음을 실행하십시오.

 result = subprocess.run(..., stderr=subprocess.STDOUT)

result.stderrNone 되고 result.stdout 은 모든 것을 포함할 것입니다.

인수 문자열과 함께 shell=False 사용

shell=False 는 인수 목록 을 예상합니다. 그러나 shlex를 사용하여 자체적으로 인수 문자열을 분할할 수 있습니다.

 import subprocess import shlex subprocess.run(shlex.split("ls -a"))

그게 다야

일반적인 문제

이 질문을 접했을 때 Python을 사용하기 시작했을 가능성이 높습니다. 몇 가지 일반적인 문제를 살펴보겠습니다.

FileNotFoundError: [Errno 2] 해당 파일 또는 디렉터리가 없습니다: 'ls -a': 'ls -a'

shell=True 없이 하위 프로세스를 실행하고 있습니다. 목록( ["ls", "-a"] )을 사용하거나 shell=True 설정하십시오.

유형 오류: [...] 없음 유형 [...]

capture_output=True 설정했는지 확인하십시오.

TypeError: [...]가 아닌 바이트열류 객체가 필요합니다.

항상 프로그램에서 바이트 결과를 받습니다. 일반 문자열처럼 작업하려면 text=True 설정하십시오.

subprocess.CalledProcessError: '[...]' 명령이 0이 아닌 종료 상태 1을 반환했습니다.

명령이 성공적으로 실행되지 않았습니다. 반환 코드 검사를 비활성화하거나 실제 프로그램의 유효성을 확인할 수 있습니다.

TypeError: init ()에 예기치 않은 키워드 인수가 있습니다 [...]

3.7.0 이전 버전의 Python을 사용 중일 가능성이 큽니다. 사용 가능한 가장 최근 것으로 업데이트하십시오. 그렇지 않으면 이 스택 오버플로 게시물에 이전 대안 솔루션을 보여주는 다른 답변이 있습니다.



답변자 : Samadi Salahedine


다음과 같이 간단할 수 있습니다.

 import os cmd = "your command" os.system(cmd)


답변자 : Priyankara


사용하다:

 import os cmd = 'ls -al' os.system(cmd)

os - 이 모듈은 운영 체제 종속 기능을 사용하는 이식 가능한 방법을 제공합니다.

더 많은 os 기능에 대한 설명서는 다음 과 같습니다.



답변자 : Atinc Delican


여기에는 앞에서 언급하지 않은 또 다른 차이점이 있습니다.

subprocess.Popen은 <command>를 subprocess.Popen 제 경우에는 <b>라는 다른 프로그램과 통신해야 하는 <a> 파일을 실행해야 합니다.

하위 프로세스를 시도했고 실행에 성공했습니다. 그러나 <b>은(는) <<>과(와) 통신할 수 없습니다. 터미널에서 둘 다 실행하면 모든 것이 정상입니다.

한 가지 더: (참고: kwrite는 다른 응용 프로그램과 다르게 작동합니다. Firefox에서 아래를 시도하면 결과가 동일하지 않습니다.)

os.system("kwrite") 를 시도하면 사용자가 kwrite를 닫을 때까지 프로그램 흐름이 멈춥니다. 그것을 극복하기 위해 os.system(konsole -e kwrite) 대신 시도했습니다. 이번에는 프로그램이 계속 흘러갔지만 kwrite는 콘솔의 하위 프로세스가 되었습니다.

누구나 하위 프로세스가 아닌 kwrite를 실행합니다(즉, 시스템 모니터에서 트리의 가장 왼쪽 가장자리에 나타나야 함).



답변자 : Saurabh Bangad


os.system 은 결과를 저장하는 것을 허용하지 않으므로 결과를 목록이나 다른 것에 저장하려면 subprocess.call 작동합니다.



답변자 : cdunn2001


반환 값을 테스트하지 않으려면 subprocess.check_call 모든 오류에 대해 예외를 throw합니다.



답변자 : Emil Stenström


나는 shlex 와 함께 subprocess 를 사용하는 경향이 있습니다(따옴표 붙은 문자열의 이스케이프 처리).

 >>> import subprocess, shlex >>> command = 'ls -l "/your/path/with spaces/"' >>> call_params = shlex.split(command) >>> print call_params ["ls", "-l", "/your/path/with spaces/"] >>> subprocess.call(call_params)


답변자 : houqp


나는 이것을 위한 라이브러리를 작성했습니다. shell.py .

현재로서는 기본적으로 popen 및 shlex용 래퍼입니다. 또한 파이핑 명령을 지원하므로 Python에서 명령을 더 쉽게 연결할 수 있습니다. 따라서 다음과 같은 작업을 수행할 수 있습니다.

 ex('echo hello shell.py') | "awk '{print $2}'"


답변자 : Swadhikar


Windows에서는 아래와 같이 subprocess.Popen() , subprocess.Popen().communicate()subprocess.Popen().wait() subprocess 모듈을 가져오고 외부 명령을 실행할 수 있습니다.

 # Python script to run a command line import subprocess def execute(cmd): """ Purpose : To execute a command and return exit status Argument : cmd - command to execute Return : exit_code """ process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (result, error) = process.communicate() rc = process.wait() if rc != 0: print "Error: failed to execute command:", cmd print error return result # def command = "tasklist | grep python" print "This process detail: \n", execute(command)

산출:

 This process detail: python.exe 604 RDP-Tcp#0 4 5,660 K


답변자 : Yuval Atzmon


Linux에서 독립적으로 실행되는(Python 스크립트가 종료된 후에도 계속 실행됨) 외부 명령을 호출하려는 경우 간단한 대기열을 작업 스풀러 또는 at 명령으로 사용할 수 있습니다.

작업 스풀러의 예:

 import os os.system('ts <your-command>')

작업 스풀러에 대한 참고 사항( ts ):

  1. 다음을 사용하여 실행할 동시 프로세스 수("슬롯")를 설정할 수 있습니다.

    ts -S <number-of-slots>

  2. ts 설치하는 데 관리자 권한이 필요하지 않습니다. make 소스에서 다운로드하고 컴파일할 수 있으며 경로에 추가하면 완료됩니다.



답변자 : Valery Ramusik


Invoke 는 Python(2.7 및 3.4+) 작업 실행 도구 및 라이브러리입니다. 셸 명령을 실행하기 위한 깨끗하고 높은 수준의 API를 제공합니다.

 >>> from invoke import run >>> cmd = "pip install -r requirements.txt" >>> result = run(cmd, hide=True, warn=True) >>> print(result.ok) True >>> print(result.stdout.splitlines()[-1]) Successfully installed invocations-0.13.0 pep8-1.5.7 spec-1.3.1


답변자 : admire


Popen을 사용하면 프로시저의 상태를 확인할 수 있습니다.

 from subprocess import Popen proc = Popen(['ls', '-l']) if proc.poll() is None: proc.kill()

subprocess.Popen을 확인하십시오.



출처 : Here


출처 : http:www.stackoverflow.com/questions/89228/how-to-execute-a-program-or-call-a-system-command">

반응형