파이썬에서 외부 명령 호출하기

freshWoWer 08/19/2017. 30 answers, 2.045.096 views
python shell command subprocess external

파이썬 스크립트 내에서 외부 명령 (예 : 유닉스 쉘 또는 Windows 명령 프롬프트에서 입력 한 것처럼)을 호출하려면 어떻게해야합니까?

2 Comments
Triton Man 03/19/2015
여기에 쉘과 파이썬을 통합하는 데 유용한 튜토리얼이 있습니다 : dreamsyssoft.com/python-scripting-tutorial/shell-tutorial.ph p
6 J.F. Sebastian 06/12/2015
@TritonMan : 좋은 튜토리얼이 아닙니다. for line in proc.stdout: 또는 for line in proc.stdout.readlines(): (moronic) 대신 for line in iter(proc.stdout.readline, '') in Python 2의 for line in proc.stdout.readlines(): . Python : subprocess.communicate ()에서 스트리밍 입력 읽기

30 Answers


David Cournapeau 02/14/2017.

표준 라이브러리의 하위 프로세스 모듈 을 살펴보십시오.

from subprocess import call
call(["ls", "-l"]) 

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

공식 문서 는 대체 os.system ()에 대한 subprocess 모듈을 권장합니다.

subprocess 모듈은 새 프로세스를 생성하고 결과를 검색 할 수있는보다 강력한 기능을 제공합니다. 이 모듈을 사용하는 것이 [ os.system() ] 함수를 사용하는 것보다 os.system() .

subprocess 문서의 " 하위 함수 모듈을 하위 프로세스 모듈로 바꾸기 "섹션에는 유용한 방법이있을 수 있습니다.

subprocess 모듈에 대한 공식 문서 :

5 comments
155 nosklo 05/26/2009
os.system을 빠른 / 더티 / 한 번 사용하는 이유를 알 수 없습니다. 하위 프로세스가 훨씬 좋아 보인다.
33 Liam 07/29/2010
나는 하위 프로세스가 더 좋다는 데 완전히 동의한다. 이처럼 빠른 스크립트를 작성하여 서브 프로세스 모듈이없는 Python 2.3.4가있는 이전 서버에서 실행해야했습니다.
6 goldenmean 11/10/2013
call (..) oython 2.7.6 : Traceback (가장 최근 호출 마지막) : 27 행의 <module> call ( "dir") 파일에서 "E : \ Ajit \ MyPython \ synonyms1.py" <br/> "C : \ Python27 \ lib \ subprocess.py"파일 524 행은 Popen (* popenargs, ** kwargs) .wait () subprocess.py ", 줄 711, init errread, errwrite) 파일"C : \ Python27 \ lib \ subprocess.py ", 줄 948, _execute_child startupinfo에서) <br/> WindowsError : [오류 2] 시스템이 지정된 파일을 찾을 수 없습니다.
61 J.F. Sebastian 12/21/2013
@ goldenmean : 제 추측으로는 Windows에 ls.exe 가 없습니다. 보십시오 call("dir", shell=True)

Eli Courtwright 04/11/2016.

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

  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 과 같은 일을 할 것입니다. 단, 프로세스와 관련된 표준 입력 / 출력에 액세스 할 수있는 파일과 유사한 객체를 제공합니다. 모든 3 가지 I / O를 약간 다르게 처리하는 popen의 다른 변종이 있습니다. 모든 것을 문자열로 전달하면 명령이 셸로 전달됩니다. 목록으로 전달하면 아무 것도 피할 걱정할 필요가 없습니다. 설명서를 참조하십시오.

  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. 파이썬 3.5 또는 그 이후 버전을 사용하고 있다면 새로운 subprocess.run 함수를 사용할 수 있습니다.이 함수는 위와 비슷하지만 더욱 유연하며 명령이 실행되면 CompletedProcess 객체를 반환합니다.

  6. os 모듈은 또한 C 프로그램에서 가지고있는 모든 fork / exec / spawn 함수를 가지고 있지만 직접적으로 사용하는 것을 권장하지 않습니다.

subprocess 모듈은 아마도 여러분이 사용하는 모듈이어야합니다.

마침내 셸이 최종 명령을 문자열로 전달하고 모든 명령을 이스케이프 처리해야하는 모든 방법에 대해 알아 두십시오. 전달한 문자열의 일부가 완전히 신뢰할 수없는 경우 There are serious security implications . 예를 들어, 사용자가 문자열의 일부 또는 전부를 입력하는 경우. 확신이 없으면 상수와 함께이 메소드 만 사용하십시오. 함축적 인 의미를 부여하려면 다음 코드를 고려하십시오.

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

사용자가 "my mama didnt love me && rm -rf /"라고 입력했다고 상상해보십시오.

5 comments
8 Casebash 05/16/2010
명령 모듈에 대해서는 언급하지 않았습니다.
111 Eli Courtwright 05/16/2010
@Casebash : 문서에서 The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. 한다고 언급했기 때문에 언급하지 않았습니다 The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. 나는 비슷하게 popen2 모듈을 언급하지 않았다. 왜냐하면이 모듈 또한 쓸모 없기 때문이다. 그리고 모듈과 commands 모듈은 실제로 Python 3.0 이후 버전에서 사라졌다. 내 대답을 편집하는 대신, 나는 이러한 의견을 이러한 모듈이 언급되는 방식으로 보도록 할 것이다.
15 PhoebeB 11/15/2010
하위 프로세스 사용에 대한 훌륭한 기사 : doughellmann.com/PyMOTW/subprocess
11 jldupont 01/21/2012
명령 모듈은 이제 더 이상 사용되지 않습니다.
13 simao 06/12/2012
대부분의 경우 Popen 객체를 직접 인스턴스화 할 필요는 없으며 subprocess.check_callsubprocess.check_output 사용할 수 있습니다.

EmmEff 12/10/2016.

나는 일반적으로 다음을 사용한다.

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() 처럼 작동합니다.

5 comments
19 J.F. Sebastian 11/16/2012
.readlines() all 행을 한 번에 읽습니다. 즉, 하위 프로세스가 종료 될 때까지 차단합니다 (파이프의 끝을 닫음). 실시간으로 읽으려면 (버퍼링 문제가없는 경우) 다음을 수행 할 수 있습니다. for line in iter(p.stdout.readline, ''): print line,
EmmEff 11/17/2012
"버퍼링 문제가 없다면"무슨 뜻인지 자세히 설명해 주시겠습니까? 프로세스가 확실히 차단되면 서브 프로세스 호출도 차단됩니다. 원래의 예에서도 마찬가지입니다. 버퍼링과 관련하여 다른 일이 발생할 수 있습니까?
9 J.F. Sebastian 11/17/2012
자식 프로세스는 라인 버퍼링 대신 비 대화식 모드에서 블록 버퍼링을 사용할 수 있으므로 p.stdout.readline() (참고 : 끝에는 없음)은 자식이 버퍼를 채울 때까지 데이터를 보지 않습니다. 자식이 많은 양의 데이터를 생성하지 않으면 실시간으로 출력되지 않습니다. 질문 에서 두 번째 이유를 참조하십시오 . 왜 파이프 (popen ())를 사용하지 않는 것이 좋습니까? . 이 해결책 (pexpect, pty, stdbuf)에는 몇 가지 해결 방법이 제공 됩니다.
2 J.F. Sebastian 04/10/2013
@Paul : 코드에서 예기치 않은 결과가 나오는 경우 문제를 재현하고 새로운 질문으로 게시 하는 완벽한 최소 코드 예제 를 만들 수 있습니다. 무슨 일이 일어나기를 기대하며 그 대신에 어떤 일이 일어나는 지 언급하십시오.
2 Paul 04/11/2013
모든 권리는 귀하의 조언을 stackoverflow.com/questions/15945585/... 감사합니다!

newtover 07/27/2017.

호출 프로세스에서 자식 프로세스 분리 (백그라운드에서 자식 프로세스 시작)에 대한 힌트.

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

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

import subprocess
import sys

# some code here

pid = subprocess.Popen([sys.executable, "longtask.py"]) # call subprocess

# some more code here 

여기에있는 아이디어는 longtask.py가 끝날 때까지 'call subprocess'라인에서 기다리고 싶지 않다는 것입니다. 그러나 예제에서 "여기에 더 많은 코드가 있습니다"라는 줄 뒤에 어떤 일이 발생하는지는 명확하지 않습니다.

내 타겟 플랫폼은 무료 였지만 개발은 창문에 있었기 때문에 창문에 먼저 문제가 발생했습니다.

윈도우에서 (win xp), longtask.py가 작업을 마칠 때까지 부모 프로세스는 끝나지 않을 것이다. CGI 스크립트에서 원하는 것이 아닙니다. 문제는 파이썬에만 국한되지 않습니다. PHP 커뮤니티에서는 문제가 동일합니다.

해결 방법은 DETACHED_PROCESS 프로세스 생성 플래그 를 win 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에서의 행동의 이유를 모른다. 누구라도 알고 있다면 아이디어를 공유하십시오. 파이썬에서 배경 프로세스를 시작한다고해서 아직 밝혀지지 않았다.

5 comments
maranas 04/09/2010
답변 해주셔서 감사합니다! 나는 pydev + eclipse에서 py2exe 응용 프로그램을 개발할 때 가능한 "특이한 점"을 발견했습니다. 이클립스의 출력 창이 종료되지 않았기 때문에 주 스크립트가 분리되지 않았다는 것을 알 수있었습니다. 스크립트가 완료까지 실행 되더라도 여전히 리턴을 기다리고 있습니다. 그러나 py2exe 실행 파일을 컴파일하려고 시도하면 예상대로 문제가 발생합니다 (분리 된 프로세스를 실행 한 다음 종료합니다). 확실하지는 않지만 실행 파일 이름이 더 이상 프로세스 목록에 없습니다. 이 방법은 모든 접근법 (os.system ( "start *"), os.P_DETACH, subprocs 등을 포함한 os.spawnl)
Alexey Lebedev 04/16/2012
Windows gotcha : 비록 내가 DETACHED_PROCESS로 프로세스를 생성했는데, 파이썬 데몬을 죽였을 때 모든 포트가 생성 된 프로세스가 종료 될 때까지 해제되지 않았을 것입니다. WScript.Shell은 모든 문제를 해결했습니다. 예 : pastebin.com/xGmuvwSx
1 J.F. Sebastian 11/16/2012
CREATE_NEW_PROCESS_GROUP 플래그가 필요할 수도 있습니다. 직계 아이가 퇴사 한 경우에도 자녀 과정을 기다리는 Popen을 보십시오.
1 eryksun 10/27/2015
다음은 올바르지 않습니다. "[o] n windows (win xp), longtask.py가 작업을 마칠 때까지 부모 프로세스가 완료되지 않습니다." 부모 프로세스는 정상적으로 종료되지만 콘솔 창 (conhost.exe 인스턴스)은 마지막에 연결된 프로세스가 종료 될 때만 닫히고 자식 프로세스는 부모 콘솔을 상속했을 수 있습니다. creationflags DETACHED_PROCESS 를 설정하면 자식이 콘솔을 상속하거나 만들지 못하도록 방지 할 수 있습니다. 새로운 콘솔을 원하면 CREATE_NEW_CONSOLE (0x00000010)을 사용하십시오.
1 eryksun 10/27/2015
분리 된 프로세스로 실행하는 것이 올바르지 않다는 것을 의미하지는 않습니다. 즉, 표준 콘솔 핸들을 파일, 파이프 또는 os.devnull 로 설정해야 할 수도 있습니다. 그렇지 않으면 일부 콘솔 프로그램이 오류로 종료되기 때문입니다. 하위 프로세스가 상위 프로세스와 동시에 사용자와 상호 작용하게하려면 새 콘솔을 작성하십시오. 하나의 창에서 두 가지를 모두 시도하는 것은 혼란 스러울 것입니다.

sirwart 04/04/2014.

쉘 대신 이스케이프 처리를하므로 훨씬 안전합니다 : os.system 대신 서브 프로세스 모듈을 사용하는 것이 좋습니다. http://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost']) 
2 comments
Joe Skora 09/18/2008
그리고 하위 프로세스를 사용하면 프로세스의 입력 / 출력 스트림 등에 쉽게 연결할 수 있습니다.
6 habnabit 09/18/2008
하위 프로세스는 쉘을 완전히 사용하지 않으므로 쉘에서 쉘을 이스케이프 처리하지 않습니다. 그것은 실제로 시동이 조금 빨라지고 오버 헤드가 적다는 것을 의미합니다.

Alexandra Franks 01/26/2016.
import os
cmd = 'ls -al'
os.system(cmd) 

명령의 결과를 반환하려면 os.popen 을 사용할 수 있습니다. 그러나이 버전은 하위 프로세스 모듈 을 위해 버전 2.6부터 사용되지 않으며, 다른 답변은 잘 설명되어 있습니다.

3 comments
BuvinJ 04/12/2017
cmd = subprocess.list2cmdline( [ 'my','list','of','tokens' ] ) 을 추가하여 이스케이프를 처리하십시오.
Karlos 04/15/2017
여러 환경 시스템에서 실행될 때 로컬 OS 매핑 간결함

nimish 09/18/2008.
import os
os.system("your command") 

이 명령은 지워지지 않으므로 위험합니다. 나는 당신에게 'os'와 'sys'모듈의 관련 문서를 google로 남겨 둡니다. 비슷한 일을 할 수있는 함수 (exec *, spawn *)가 있습니다.


athanassis 05/28/2017.

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

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

child = pexpect.spawn('ftp 192.168.0.24')

child.expect('(?i)name .*: ')

child.sendline('anonymous')

child.expect('(?i)password') 

Jorge E. Cardona 07/23/2013.

나는 항상 다음과 같은 것들을 위해 fabric 을 사용한다.

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

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

예를보세요.

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True) 
1 comments
2 Yauhen Yakimovich 05/23/2013
sh는 서브 프로세스 모듈보다 우수합니다. 더 나은 쉘 통합을 가능하게합니다.

Facundo Casco 12/10/2016.

필요한 것은 호출중인 명령의 출력입니다.
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 자체는 많은 셸과 유사한 기능 (특히 glob , fnmatch , os.walk() , os.path.expandvars() , os.path.expanduser()shutil )의 구현을 제공합니다.


Usman Khan 10/28/2012.

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

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() 
3 comments
Eric 07/23/2013
명령을 문자열로 전달하는 것은 일반적으로 나쁜 생각입니다.
1 Adam Matan 04/02/2014
가독성이 높아지면 하드 코딩 된 명령에 적합하다고 생각합니다.
sam 09/12/2016
감사. Perl과 Ruby에서 나온 Python은 명령을 실행할 때 PITA입니다. 많은 솔루션을 읽으십시오. 당신 포 인 처럼요.

Honza Javorek 08/12/2016.

표준 라이브러리 포함

하위 프로세스 모듈 사용 :

from subprocess import call
call(['ls', '-l']) 

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

참고 : shlex.split 을 사용하면 목록 형식으로 제공하지 않거나 (또는 ​​지정할 수없는 경우가 있기 때문에) call 및 다른 subprocess 함수에 대한 명령을 구문 분석 할 수 있습니다.

import shlex
from subprocess import call
call(shlex.split('ls -l')) 

외부 종속성 사용

외부 의존성에 신경 쓰지 않는다면 plumbum을 사용하십시오 :

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

최고의 subprocess 랩퍼입니다. 그것은 크로스 플랫폼입니다. 즉, Windows와 Unix 계열 시스템 모두에서 작동합니다. pip install plumbum 설치합니다.

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

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

그러나 sh 는 Windows 지원을 떨어 뜨 sh 때문에 예전만큼 뛰어나지 않았습니다. pip install sh .


Joe 05/23/2017.

최신 정보:

코드가 이전 Python 버전과의 호환성을 유지할 필요가없는 경우 subprocess.runPython 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') 

원문 답변 :

나는 대사를 사살하는 것이 좋습니다. 이것은 하위 프로세스의 래퍼이며, 이전 모듈과 함수 를 대체 하는 것을 목표로 합니다. 특사는 인간을위한 하위 프로세스입니다.

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
[] 
2 comments
4 J.F. Sebastian 10/03/2015
주 : 기본적으로 0이 아닌 종료 상태를 무시하는 subprocess.check_call()subprocess.check_call() 또는 subprocess.check_output() 비해 회귀입니다. python -mthis : "명시 적으로 침묵시키지 않으면 오류가 자동으로 전달되지 않습니다."
itirazimvar 09/01/2016
감사의 사절은 하위 프로세스보다 더 잘 작동합니다. esxi_host = {0} extravar1 = {1} extravar2 = {2} extravar3 = {3} \ "". 명령 (extravar1, extravar2 , extravar3) 및 r.envoy.run (명령)

Tom Fuller 05/28/2017.

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

Sources:

These are all the libraries:

바라기를 이것은 당신이 사용할 라이브러리에 대한 결정을 내리는 데 도움이 될 것입니다 :)

subprocess

하위 프로세스를 사용하면 외부 명령을 호출하여 입력 / 출력 / 오류 파이프 (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는 "운영 체제 종속 기능"에 사용됩니다. 또한 os.systemos.popen (참고 : subprocess.popen도 있음)을 사용하여 외부 명령을 호출하는 데 사용할 수 있습니다. os는 항상 쉘을 실행하며 subprocess.run 을 사용할 필요가 없거나 사용법을 모르는 사람들을위한 간단한 대안입니다.

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

sh

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

plumbum은 "script-like"Python 프로그램을위한 라이브러리입니다. sh 처럼 함수와 같은 프로그램을 호출 할 수 있습니다. plumbum은 쉘없이 파이프 라인을 실행하려는 경우에 유용합니다.

ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command 

pexpect

pexpect를 사용하면 하위 응용 프로그램을 생성하고 제어하고 출력에서 ​​패턴을 찾을 수 있습니다. 이것은 유닉스에서 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

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

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

commands 에는 os.popen 에 대한 래퍼 (wrapper) 함수가 포함되어 있지만 subprocess 가 더 나은 대안이므로 Python 3에서 제거되었습니다.

편집은 JF Sebastian의 코멘트를 기반으로했습니다.

4 comments
Tom Fuller 10/29/2016
나는 무엇이든을 놓쳤는가?
3 J.F. Sebastian 11/02/2016
pexpectUnix 에서 tty를 기대하는 명령에 유용하고 pexpect쉘을 호출하지 않고 파이프 라인실행하는 데 유용 할 수 있으며 fabric 은 다음과 같은 간단한 방법으로 유용합니다. ssh를 통해 명령을 실행하면, subprocess ( os 와는 다르다)는 묻지 않는 한 쉘을 실행하지 않는다. 외부 명령을 실행하는 기본 선택이며 때로는 대안 이 필요할 수도 있다 .
Tom Fuller 11/02/2016
귀하의 의견을 기반으로 내 대답을 편집했습니다 :)
1 J.F. Sebastian 11/02/2016
os "외부 명령"기능은 내부적으로 subprocess 로 구현됩니다. subprocess 모듈의 모든 기능을 필요로하지 않으며 subprocess.run() 및 다른 언어를 사용하는 방법을 배울 시간이없는 다른 언어 ( system() , popen() 이 공용 API 임)에서 유용 할 수 있습니다. 기타 하위 프로세스 '기능을 제공합니다.

Zuckonit 05/28/2017.

결과의 출력없이 :

import os
os.system("your command here") 

결과 출력 :

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here") 
1 comments
2 Ramsharan 10/19/2013
with output of result 나오는 부분 with output of result 마음 with output of result . 나는 숭고한 콘솔에서 사용하기 위해 이것을 필요로했다.

stuckintheshuck 10/10/2014.

또한 Plumbum

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand()
>>> 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 
1 comments
J.F. Sebastian 07/13/2015
또는 약간의 마법을 추가하십시오. from plumbum.cmd import ls, grep; output = (ls | grep['pattern'])() from plumbum.cmd import ls, grep; output = (ls | grep['pattern'])()

Ben Hoffstein 11/02/2014.

https://docs.python.org/2/library/subprocess.html

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

import os
os.system('cat testfile') 

Martin W 12/10/2016.

os.system 은 괜찮지 만 날짜는 종류가 다릅니다. 그것은 또한 안전하지 않습니다. 대신 subprocess 사용해보십시오. subprocess 는 sh를 직접 호출하지 않으므로 os.system 보다 안전 os.system .

여기에서 자세한 정보를 얻으십시오.


William Keller 12/10/2016.

os.systemsubprocess 모듈로 대체되었습니다. 서브 프로세스를 대신 사용하십시오.

3 comments
14 Michael Mior 03/29/2010
아마도 subprocess 를 사용하는 예입니까?
5 Mark Amery 12/22/2016
수락 된 응답이 subprocess 더 일찍 그리고 더 자세하게 제안했다는 것을 감안할 때, 나는이 답변에 아무런 가치가 없다고 생각합니다.
sudo 04/23/2017
os.system 의 문제점은 무엇입니까? 가장 직관적이며, 문자열에 넣은 것을 실행하고 사람들이 허용 된 답안 아래에 나열된 모든 경고를 가지고 있지 않습니다.

cdunn2001 01/18/2011.

subprocess.check_call 은 반환 값을 테스트하지 않으려는 경우에 편리합니다. 오류가 발생하면 예외가 발생합니다.


Atinc Delican 12/10/2016.

여기에 언급되지 않은 또 다른 차이점이 있습니다.

subprocess.Popensubprocess.Popen 실행합니다. 필자의 경우 다른 프로그램과 통신해야하는 파일을 실행해야합니다.

하위 프로세스를 사용해 보았습니다. 실행은 성공적이었습니다. 그러나 통신 할 수 없었다. 터미널에서 둘 다 실행하면 정상입니다.

하나 더 : (참고 : kwrite는 다른 응용 프로그램과 다르게 작동합니다. 파이어 폭스 결과로 아래를 시도하면 같은 결과가 나올 수 없습니다)

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

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


Priyankara 05/28/2017.

용도:

import os

cmd = 'ls -al'

os.system(cmd) 

os -이 모듈은 운영 체제 종속 기능을 이식 할 수있는 방법을 제공합니다.

더 많은 함수에 대해서는 여기 에 문서가 있습니다.

3 comments
PolarisUser 10/09/2015
cmd의 결과를 파일로 푸시 할 수있는 방법이 있습니까? 나는 웹 사이트를 컬링하고 있는데 파일로 가기를 원합니다.
user2820579 10/16/2015
이것은 훨씬 간단하고 강력한 솔루션입니다. @PolarisUser 당신은 generic linux 명령을 사용할 수 있습니다 : > outputfile.txt
Corey Goldberg 12/09/2015
그것은 또한 비추천입니다. 하위 프로세스 사용

Saurabh Bangad 06/11/2012.

os.system 은 결과를 저장하는 것을 허용하지 않기 때문에 결과를 일부 목록이나 무언가에 저장하려는 경우 subprocess.call 작동합니다.


Emil Stenström 04/30/2014.

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

>>> 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 05/01/2014.

뻔뻔한 플러그, 나는 이것을 위해 라이브러리를 썼다 : P https://github.com/houqp/shell.py

이것은 기본적으로 popen과 shlex의 래퍼입니다. 또한 파이핑 명령을 지원하므로 파이썬에서 명령을 쉽게 연결할 수 있습니다. 그래서 당신은 다음과 같은 일을 할 수 있습니다 :

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

admire 05/28/2017.

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

from subprocess import Popen

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

하위 프로세스를 확인하십시오. 열어 .


IRSHAD 07/20/2016.

openstack 중성자로부터 네트워크 ID를 가져 오려면 다음을 수행하십시오.

#!/usr/bin/python
import os
netid= "nova net-list | awk '/ External / { print $2 }'"
temp=os.popen(netid).read()  /* here temp also contains new line (\n) */
networkId=temp.rstrip()
print(networkId) 

nova net-list 출력

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+ 

print(networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126 

yuval 11/27/2016.

리눅스에서는 독립적으로 실행될 외부 명령 (파이썬 스크립트가 종료 된 후에도 계속 실행 됨)을 호출하려는 경우 간단한 큐를 작업 스풀러 또는 at 명령으로 사용할 수 있습니다

작업 스풀러의 예 :

import os
os.system('ts ') 

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

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

    ts -S

  2. ts 설치에는 관리자 권한이 필요하지 않습니다. 간단한 make 소스에서 다운로드하여 컴파일하고, 경로에 추가하면 완료됩니다.


urosjarc 05/28/2017.

여기 내 두 센트가 있습니다 : 내 생각에 이것은 외부 명령을 다룰 때 가장 좋은 방법입니다 ...

이들은 execute 메소드의 리턴 값입니다 ...

pass, stdout, stderr = execute(["ls","-la"],"/home/user/desktop") 

이것은 실행 방법입니다 ...

def execute(cmdArray,workingDir):

    stdout = ''
    stderr = ''

    try:
        try:
            process = subprocess.Popen(cmdArray,cwd=workingDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
        except OSError:
            return [False, '', 'ERROR : command(' + ' '.join(cmdArray) + ') could not get executed!']

        for line in iter(process.stdout.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stdout += echoLine

        for line in iter(process.stderr.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stderr += echoLine

    except (KeyboardInterrupt,SystemExit) as err:
        return [False,'',str(err)]

    process.stdout.close()

    returnCode = process.wait()
    if returnCode != 0 or stderr != '':
        return [False, stdout, stderr]
    else:
        return [True, stdout, stderr] 
1 comments
ppperry 07/07/2016
교착 상태 가능성 : 대신 .communicate 메소드 사용

Swadhikar C 05/28/2017.

Windows에서 subprocess 모듈을 가져 와서 subprocess.Popen() , subprocess.Popen().communicate()subprocess.Popen().wait() 을 호출하여 다음과 같이 외부 명령을 실행할 수 있습니다.

# 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 

Related questions

Hot questions

Language

Popular Tags