it-swarm-ko.tech

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

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

4038
freshWoWer

표준 라이브러리에서 subprocess 모듈 을보십시오.

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

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

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

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

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

3905
David Cournapeau

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

  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를 처리하는 3 가지 다른 종류의 popen이 있습니다. 모든 것을 문자열로 전달하면 명령이 셸로 전달됩니다. 당신이 그들을 목록으로 전달하면 아무것도 탈출에 대해 걱정할 필요가 없습니다. 설명서 를 참조하십시오.

  3. Popen 모듈의 subprocess 클래스 이것은 _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. call 모듈의 subprocess 함수 이것은 기본적으로 Popen 클래스와 동일하며 동일한 인수를 모두 사용하지만 명령이 완료 될 때까지 기다렸다가 리턴 코드를 제공합니다. 예를 들면 다음과 같습니다.

    _return_code = subprocess.call("echo Hello World", Shell=True)  
    _

    설명서 를 참조하십시오.

  5. Python 3.5 이상인 경우 새로운 subprocess.run 함수를 사용할 수 있습니다.이 기능은 위와 비슷하지만 더 유연하고- CompletedProcess 명령 실행이 완료되면 객체입니다.

  6. Os 모듈에는 C 프로그램에서 가질 수있는 모든 fork/exec/spawn 함수가 있지만 직접 사용하지 않는 것이 좋습니다.

subprocess 모듈은 아마도 당신이 사용해야합니다.

마지막으로 Shell이 ​​문자열로 실행하도록 최종 명령을 전달하는 모든 메소드에 대해 이스케이프 처리해야합니다. 심각한 보안 문제가 있습니다 전달한 문자열의 일부를 완전히 신뢰할 수없는 경우. 예를 들어, 사용자가 문자열의 일부 또는 일부를 입력하는 경우. 확실하지 않은 경우 상수와 함께이 방법 만 사용하십시오. 의미에 대한 힌트를 제공하려면 다음 코드를 고려하십시오.

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

사용자가 전체 파일 시스템을 지울 수있는 "엄마가 나를 사랑하지 않는 && rm -rf /"라는 것을 입력했다고 상상해보십시오.

2827
Eli Courtwright

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

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

292
EmmEff

일부 힌트는 호출 프로세스에서 자식 프로세스를 분리합니다 (백그라운드에서 자식 프로세스 시작).

자식 프로세스가 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'라인에서 기다리고 싶지 않다는 것입니다. 그러나 예제에서 "여기에 더 많은 코드가 있습니다"라는 줄 뒤에 어떤 일이 발생하는지는 명확하지 않습니다.

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

Windows (win xp)에서는 longtask.py가 작업을 마칠 때까지 부모 프로세스가 완료되지 않습니다. CGI 스크립트에서 원하는 것이 아닙니다. 이 문제는 파이썬에만 국한된 것이 아니라 _ ​​PHP community에서 문제가 동일합니다.

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

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

명령의 결과를 반환하려면 os.popen 를 사용할 수 있습니다. 그러나이 버전은 2.6 이후 버전에서 subprocess module 를 사용하기 때문에 더 이상 사용되지 않습니다.

113
Alexandra Franks

Shell이 ​​당신을 위해 이스케이프 처리하기 때문에 os.system 대신 서브 프로세스 모듈을 사용하는 것이 좋습니다. 그러므로 훨씬 안전합니다 : http://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost'])
113
sirwart
import os
os.system("your command")

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

101
nimish

파이썬으로 외부 명령을 호출 할 수있게 해주는 많은 라이브러리가 있습니다. 각 라이브러리에 대해 설명을하고 외부 명령을 호출하는 예제를 보여줍니다. 예제로 사용한 명령은 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는 "운영 체제 종속 기능"에 사용됩니다. 또한 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 [email protected]:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')

fabric

fabric은 Python 2.5 및 2.7 라이브러리입니다. 로컬 및 원격 셸 명령을 실행할 수 있습니다. 패브릭은 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

명령

commandsos.popen에 대한 래퍼 함수를 ​​포함하지만 subprocess이 더 좋은 대안이므로 Python 3에서 제거되었습니다.

이 편집은 J.F. Sebastian의 의견을 바탕으로 이루어졌습니다.

63
Tom Fuller

나는 항상 이런 것들에 대해 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)
60
Jorge E. Cardona

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

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

child = pexpect.spawn('ftp 192.168.0.24')

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

child.sendline('anonymous')

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

호출중인 명령의 출력이 필요하면 다음에 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 매개 변수에 유의하십시오.

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

53
Facundo Casco

표준 라이브러리 포함

서브 프로세스 모듈 (파이썬 3) 사용 :

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

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

파이썬 버전 노트 : 파이썬 2를 사용하고 있다면, subprocess.call 도 비슷한 방식으로 작동합니다.

ProTip : shlex.splitrun, call 및 기타 subprocess 함수에 대한 명령을 구문 분석하는 데 도움을 줄 수 있습니다. 목록 :

import shlex
import subprocess
subprocess.run(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 지원을 중단했기 때문에 예전만큼 굉장하지 않았습니다. pip install sh별로 설치하십시오.

51
Honza Javorek

최신 정보:

코드가 이전 Python 버전과의 호환성을 유지할 필요가없는 경우 subprocess.run이 권장되는 방법입니다. Python 3.5 기준 보다 일관성 있고 Envoy와 비슷한 사용 편의성을 제공합니다. (배관은 간단하지 않습니다. 이 질문에 대한 질문 참조)

다음은 docs 의 예입니다.

프로세스를 실행하십시오.

>>> 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 를 시도하는 것이 좋습니다. 하위 프로세스의 래퍼이며, 이전 모듈과 함수는 대체 목표 입니다. 특사는 인간의 하위 프로세스입니다.

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'>]
45
Joe

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

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()
45
Usman Khan

결과의 출력없이 :

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

결과 출력 :

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here")
34
Zuckonit

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

... 또는 아주 간단한 명령 :

import os
os.system('cat testfile')
28
Ben Hoffstein

또한 Plumbum

>>> 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
27
stuckintheshuck

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

여기 더 많은 정보를 얻으십시오.

27
Martin W

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

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

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

왜?

파이썬 3.5부터는 문서에서 subprocess.run 을 권장합니다.

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

다음은 가능한 가장 단순한 사용 예입니다. 정확히 묻습니다.

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> 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에 전달할 수 있습니다.

>>> cp = subprocess.run('python --version', 
                        stderr=subprocess.PIPE, 
                        stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''

(나는 버전 정보가 stdout 대신에 stderr에 놓이게하는 것이 흥미롭고 약간 직관력이 없다는 것을 안다.)

명령 목록 전달

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

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

args 만 위치 정보를 전달해야합니다.

완전한 서명

다음은 help(run)에 표시된 소스의 실제 서명입니다.

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

popenargskwargsPopen 생성자에 제공됩니다. input은 하위 프로세스의 표준 입력으로 파이프되는 바이트 문자열 (인코딩을 지정하는 경우 유니 코드 또는 universal_newlines=True) 일 수 있습니다.

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

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

Check가 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을 사용할 때? 나는 인수만으로 유스 케이스를 찾기 위해 애를 먹는다. 그러나 Popen을 직접 사용하면 poll, 'send_signal', 'terminate'및 'wait'등의 메서드에 액세스 할 수 있습니다.

source 에 주어진대로 Popen 서명이 있습니다. 이것은 정보의 가장 정확한 캡슐화라고 생각합니다 (help(Popen)과 반대 됨).

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             Shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None):

그러나 더 유익한 것은 Popen documentation :

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=False,
                 startupinfo=None, creationflags=0, restore_signals=True,
                 start_new_session=False, pass_fds=(), *, encoding=None, errors=None)

새 프로세스에서 하위 프로그램을 실행합니다. POSIX에서 클래스는 os.execvp ()와 같은 동작을 사용하여 하위 프로그램을 실행합니다. Windows에서는 클래스는 Windows CreateProcess () 함수를 사용합니다. Popen의 주장은 다음과 같습니다.

Popen에 대한 나머지 문서를 이해하는 것은 독자의 연습 과제로 남겨 둡니다.

24
Aaron Hall

이것은 간단 할 수 있습니다 :

import os
cmd = "your command"
os.system(cmd)
23
Samadi Salahedine

용도:

import os

cmd = 'ls -al'

os.system(cmd)

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

더 많은 os 함수의 경우 here 는 설명서입니다.

23
Priyankara

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

19
cdunn2001

나는 subprocess 와 함께 사용하는 경향이있다 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)
18
Emil Stenström

os.system는 결과를 저장할 수 없으므로 일부 목록이나 결과에 결과를 저장하려는 경우 subprocess.call가 작동합니다.

17
Saurabh Bangad

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

subprocess.Popen는 <command>를 하위 프로세스로 실행합니다. 필자의 경우 다른 프로그램 인 <b>과 통신해야하는 <a> 파일을 실행해야합니다. 

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

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

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

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

17
Atinc Delican

나는 아주 좋아한다 Shell_command 그 단순함. 서브 프로세스 모듈 위에 구축됩니다.

다음은 docs의 예제입니다.

>>> from Shell_command import Shell_call
>>> Shell_call("ls *.py")
setup.py  Shell_command.py  test_Shell_command.py
0
>>> Shell_call("ls -l *.py")
-rw-r--r-- 1 ncoghlan ncoghlan  391 2011-12-11 12:07 setup.py
-rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 Shell_command.py
-rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_Shell_command.py
0
16
mdwhatcott

os 모듈을 사용하십시오.

import os
os.system("your command")

import os
os.system("ifconfig")
15
abhi krishnan

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

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

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

리눅스에서는 독립적으로 실행될 외부 명령 (python 스크립트가 종료 된 후에도 계속 실행 됨)을 호출하려는 경우 task spooler 또는 at 명령

작업 스풀러의 예 :

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

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

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

    ts -S <number-of-slots>

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

14
Yuval Atzmon

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

from subprocess import Popen

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

subprocess.Popen 을 확인하십시오.

13
admire

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
12
Swadhikar C

명령을 실행하고 결과를 다시 얻는 가장 간단한 방법은 다음과 같습니다.

from commands import getstatusoutput

try:
    return getstatusoutput("ls -ltr")
except Exception, e:
    return None
11
Garfield

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)

노바 네트리스트의 출력

+--------------------------------------+------------+------+
| 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
11
IRSHAD

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

이들은 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]
10
Uroš Jarc

종종 외부 명령에 다음 기능을 사용하며 특히 장기 실행 프로세스에 유용합니다. 아래의 메소드 tails process output 동안 실행 중이고 출력이 반환되면 예외 발생 프로세스가 실패한 경우.

프로세스가 poll () 메소드의 프로세스를 사용하여 수행되면 나타납니다.

import subprocess,sys

def exec_long_running_proc(command, args):
    cmd = "{} {}".format(command, " ".join(str(arg) if ' ' not in arg else arg.replace(' ','\ ') for arg in args))
    print(cmd)
    process = subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    # Poll process for new output until finished
    while True:
        nextline = process.stdout.readline().decode('UTF-8')
        if nextline == '' and process.poll() is not None:
            break
        sys.stdout.write(nextline)
        sys.stdout.flush()

    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise Exception(command, exitCode, output)

다음과 같이 호출 할 수 있습니다.

exec_long_running_proc(command = "Hive", args=["-f", hql_path])
9
am5

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
8
Valery Ramusik

다음은 외부 명령을 호출하고 명령의 출력을 반환하거나 인쇄하는 것입니다.

파이썬 서브 프로세스 check_output은 유용합니다.

인수로 명령을 실행하고 출력을 바이트 문자열로 반환하십시오.

import subprocess
proc = subprocess.check_output('ipconfig /all')
print proc
7
Rajiv Sharma

용도:

import subprocess

p = subprocess.Popen("df -h", Shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("\n")

그것은 니스 출력을 제공합니다.

['Filesystem      Size  Used Avail Use% Mounted on',
 '/dev/sda6        32G   21G   11G  67% /',
 'none            4.0K     0  4.0K   0% /sys/fs/cgroup',
 'udev            1.9G  4.0K  1.9G   1% /dev',
 'tmpfs           387M  1.4M  386M   1% /run',
 'none            5.0M     0  5.0M   0% /run/lock',
 'none            1.9G   58M  1.9G   3% /run/shm',
 'none            100M   32K  100M   1% /run/user',
 '/dev/sda5       340G  222G  100G  69% /home',
 '']
7
David Okwii

토론에 추가하기 만하면 파이썬 콘솔을 사용하여 include하면 IPython 에서 외부 명령을 호출 할 수 있습니다. IPython 프롬프트에서 접두어 '!'로 쉘 명령을 호출 할 수 있습니다. Python 코드를 Shell과 결합하여 Shell 스크립트의 출력을 Python 변수에 할당 할 수도 있습니다.

예를 들면 :

In [9]: mylist = !ls

In [10]: mylist
Out[10]:
['file1',
 'file2',
 'file3',]
7
imagineerThat

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

외부 명령을 호출하는 간단한 방법은 os.system(...)을 사용하는 것입니다. 이 함수는 명령의 종료 값을 반환합니다. 그러나 단점은 우리가 stdout과 stderr를 얻지 못할 것이라는 것입니다.

ret = os.system('some_cmd.sh')
if ret != 0 :
    print 'some_cmd.sh execution returned failure'

백그라운드에서 파이썬으로 외부 명령 호출하기

subprocess.Popenos.system를 사용하는 대신 외부 명령을 실행하는 데 유연성을 제공합니다. 백그라운드에서 명령을 시작하고 명령이 끝날 때까지 기다릴 수 있습니다. 그 후에 우리는 stdout과 stderr를 얻을 수 있습니다.

proc = subprocess.Popen(["./some_cmd.sh"], stdout=subprocess.PIPE)
print 'waiting for ' + str(proc.pid)
proc.wait()
print 'some_cmd.sh execution finished'
(out, err) = proc.communicate()
print 'some_cmd.sh output : ' + out

백그라운드에서 Python으로 장시간 실행되는 외부 명령을 호출하고 잠시 후 중지

subprocess.Popen를 사용하여 백그라운드에서 장기간 실행되는 프로세스를 시작하고 작업이 완료되면 언젠가는 종료 할 수도 있습니다.

proc = subprocess.Popen(["./some_long_run_cmd.sh"], stdout=subprocess.PIPE)
# Do something else
# Now some_long_run_cmd.sh exeuction is no longer needed, so kill it
os.system('kill -15 ' + str(proc.pid))
print 'Output : ' proc.communicate()[0]
6
rashok

파이썬으로 외부 명령을 실행하는 많은 다른 방법이 있습니다. 그리고 그들 모두는 장점과 단점이 있습니다.

저의 동료들과 저와 함께 파이썬 시스템 관리 도구를 작성해 왔기 때문에 많은 외부 명령을 실행해야하며 때로는 비동기 적으로 블록하거나 비동기 적으로 실행, 제한 시간 초과, 매 초마다 업데이트하기를 원합니다.

반환 코드와 오류 를 처리하는 다양한 방법이 있으며 출력을 구문 분석하고 새로운 입력을 제공 할 수 있습니다 (예 : expect 종류의 스타일). 또는 stdin, stdout 및 stderr을 다른 tty에서 실행되도록 리디렉션해야합니다 (예 : 화면 사용시).

그래서 아마도 외부 명령에 많은 래퍼를 써야 할 것입니다. 여기에 우리가 작성한 Python 모듈이 있습니다. 당신이 원한다면 거의 모든 것을 처리 할 수 ​​있고, 그렇지 않다면 쉽게 확장 할 수 있습니다.

https://github.com/hpcugent/vsc-base/blob/master/lib/vsc/utils/run.py

6
Jens Timmerman

예를 들어 (Linux) :

import subprocess
subprocess.run('mkdir test.dir', Shell=True)

이렇게하면 현재 디렉토리에 test.dir이 생성됩니다. 참고 :

import subprocess
subprocess.call('mkdir test.dir', Shell=True)

Os.system을 사용하는 동일한 코드는 다음과 같습니다.

import os
os.system('mkdir test.dir')

모범 사례는 os 대신 subprocess를 사용하고 .call보다 .run이 우선합니다. 하위 프로세스에 대해 알아야 할 것은 here . 입니다. 또한 모든 파이썬 문서는 here 에서 다운로드 할 수 있습니다. PDF를 .Zip 형식으로 다운로드했습니다. 튜토리얼 .pdf (81 페이지)에 os 모듈에 대한 개요가 나와 있기 때문에 언급합니다. 게다가, 그것은 파이썬 코더를위한 권위있는 자료입니다.

6
user8468899

파이썬 3.5+에서는 서브 프로세스 모듈에서 실행하는 함수 를 사용하는 것이 좋습니다. 이렇게하면 CompletedProcess 객체가 반환되므로 반환 코드뿐만 아니라 출력도 쉽게 얻을 수 있습니다.

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)
5
Chiel ten Brinke

간단한 방법은 os 모듈을 사용하는 것입니다.

import os
os.system('ls')

또는 하위 프로세스 모듈을 사용할 수도 있습니다.

import subprocess
subprocess.check_call('ls')

결과를 변수 try에 저장하려면 다음을 수행하십시오.

import subprocess
r = subprocess.check_output('ls')
4
amehta

subprocess.call 을 사용하십시오.

from subprocess import call

# using list
call(["echo", "Hello", "world"])

# single string argument varies across platforms so better split it
call("echo Hello world".split(" "))
4
andruso

Popen Python 모듈의 subprocess 함수를 사용하는 것이 Linux 명령을 실행하는 가장 간단한 방법입니다. Popen.communicate() 함수는 명령 출력을 제공합니다. 예를 들어

import subprocess

..
process = subprocess.Popen(..)   # Pass command and arguments to the function
stdout, stderr = process.communicate()   # Get command output and error
..
4
Asif Hasnain

명령을 호출하는 방법은 여러 가지가 있습니다.

  • 예 :

and.exe에 두 개의 매개 변수가 필요한 경우. cmd에서 sample.exe를 호출 할 수 있습니다 : and.exe 2 3 그리고 5가 화면에 표시됩니다.

파이썬 스크립트를 사용하여 and.exe를 호출하면 우리는 다음과 같이해야합니다.

  1. os.system(cmd,...)

    • os.system(("and.exe" + " " + "2" + " " + "3"))
  2. os.popen(cmd,...)

    • os.popen(("and.exe" + " " + "2" + " " + "3"))
  3. subprocess.Popen(cmd,...)
    • subprocess.Popen(("and.exe" + " " + "2" + " " + "3"))

너무 어렵 기 때문에 cmd와 공백을 연결할 수 있습니다.

import os
cmd = " ".join(exename,parameters)
os.popen(cmd)
4
liuyip

Python 노트북 ( Jupyter , Zeppelin, Databricks 또는 Google Cloud Datalab)에서 Shell 명령을 호출해야하는 경우 ! 접두사를 사용할 수 있습니다.

예를 들어,

!ls -ilF
3
dportman

이 사용 사례를 돕기 위해 작은 라이브러리를 작성했습니다.

https://pypi.org/project/citizenshell/

다음을 사용하여 설치할 수 있습니다. 

pip install citizenshell

그리고 다음과 같이 사용 :

from citizenshell import sh
assert sh("echo Hello World") == "Hello World"

Stderr에서 stdout을 분리하고 다음과 같이 종료 코드를 추출 할 수 있습니다.

result = sh(">&2 echo error && echo output && exit 13")
assert result.stdout() == ["output"]
assert result.stderr() == ["error"]
assert result.exit_code() == 13

멋진 점은 출력 처리를 시작하기 전에 기본 Shell이 ​​종료 될 때까지 기다릴 필요가 없다는 것입니다.

for line in sh("for i in 1 2 3 4; do echo -n 'It is '; date +%H:%M:%S; sleep 1; done", wait=False)
    print ">>>", line + "!"

wait = False 덕분에 줄을 인쇄 할 수 있습니다.

>>> It is 14:24:52!
>>> It is 14:24:53!
>>> It is 14:24:54!
>>> It is 14:24:55!

더 많은 예제는 https://github.com/meuter/citizenshell 에서 찾을 수 있습니다.

3
Cédric

파이썬을 사용하여 쉘 명령을 실행할 수있는 두 가지 주요한 방법이 있습니다. 아래에 언급 된 두 예제 모두 파이썬을 사용하여 현재 작업 디렉토리 (pwd)의 이름을 얻는 방법을 보여줍니다. pwd 대신 다른 Unix 명령을 사용할 수 있습니다. 

1.> 1 번째 방법 :파이썬에서 os module을 사용할 수 있고, system () function을 사용하여 파이썬에서 쉘 명령을 실행할 수 있습니다.

import os
os.system('pwd')

산출:

/Users/siddharth

1.> 두 번째 방법 :또 다른 방법은 subprocess module 및 call () function을 사용하는 것입니다. 

import subprocess
subprocess.call('pwd')

산출:

/Users/siddharth
3

나는 다음과 같은 방법을 '실행'하고 STDOUT, STDERR 및 exit 상태를 종료하는 데 도움이 될 것을 권장합니다. 이것의 호출자는 프로세스의 실제 상태를 알기 위해 'run'메소드를 사용하여 사전 리턴을 읽을 수 있습니다. 

  def run (cmd):
       print "+ DEBUG exec({0})".format(cmd)
       p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, Shell=True)
       (out, err) = p.communicate()
       ret        = p.wait()
       out        = filter(None, out.split('\n'))
       err        = filter(None, err.split('\n'))
       ret        = True if ret == 0 else False
       return dict({'output': out, 'error': err, 'status': ret})
  #end
2
Viswesn

몇 가지 조사를 한 후에 다음 코드를 작성하면 매우 유용합니다. 기본적으로 stdout과 stderr를 실시간으로 출력합니다. 그것이 그것을 필요로하는 다른 누군가를 돕기를 바랍니다.

stdout_result = 1
stderr_result = 1


def stdout_thread(pipe):
    global stdout_result
    while True:
        out = pipe.stdout.read(1)
        stdout_result = pipe.poll()
        if out == '' and stdout_result is not None:
            break

        if out != '':
            sys.stdout.write(out)
            sys.stdout.flush()


def stderr_thread(pipe):
    global stderr_result
    while True:
        err = pipe.stderr.read(1)
        stderr_result = pipe.poll()
        if err == '' and stderr_result is not None:
            break

        if err != '':
            sys.stdout.write(err)
            sys.stdout.flush()


def exec_command(command, cwd=None):
    if cwd is not None:
        print '[' + ' '.join(command) + '] in ' + cwd
    else:
        print '[' + ' '.join(command) + ']'

    p = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
    )

    out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,))
    err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,))

    err_thread.start()
    out_thread.start()

    out_thread.join()
    err_thread.join()

    return stdout_result + stderr_result
2
Jake W

Sultan 은이 목적을위한 최신 패키지입니다. 사용자 권한 관리 및 유용한 오류 메시지 추가에 대한 유용한 정보를 제공합니다.

from sultan.api import Sultan

with Sultan.load(Sudo=True, hostname="myserver.com") as sultan:
  sultan.yum("install -y tree").run()
1
Zach Valenta

오류를 처리하고 출력 및 다른 내용을 리디렉션하는 래퍼를 작성했습니다.

import shlex
import psutil
import subprocess

def call_cmd(cmd, stdout=sys.stdout, quiet=False, Shell=False, raise_exceptions=True, use_shlex=True, timeout=None):
    """Exec command by command line like 'ln -ls "/var/log"'
    """
    if not quiet:
        print("Run %s", str(cmd))
    if use_shlex and isinstance(cmd, (str, unicode)):
        cmd = shlex.split(cmd)
    if timeout is None:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=sys.stderr, Shell=shell)
        retcode = process.wait()
    else:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=sys.stderr, Shell=shell)
        p = psutil.Process(process.pid)
        finish, alive = psutil.wait_procs([p], timeout)
        if len(alive) > 0:
            ps = p.children()
            ps.insert(0, p)
            print('waiting for timeout again due to child process check')
            finish, alive = psutil.wait_procs(ps, 0)
        if len(alive) > 0:
            print('process {} will be killed'.format([p.pid for p in alive]))
            for p in alive:
                p.kill()
            if raise_exceptions:
                print('External program timeout at {} {}'.format(timeout, cmd))
                raise CalledProcessTimeout(1, cmd)
        retcode = process.wait()
    if retcode and raise_exceptions:
        print("External program failed %s", str(cmd))
        raise subprocess.CalledProcessError(retcode, cmd)

다음과 같이 호출 할 수 있습니다.

cmd = 'ln -ls "/var/log"'
stdout = 'out.txt'
call_cmd(cmd, stdout)
1
Asav Patel

Eli가 위에서 설명한 subprocess module 은 매우 강력하지만 습지 표준 시스템 호출을 작성하고 그 출력을 검사하는 구문은 불필요하게 지연됩니다.

시스템 호출을하는 가장 쉬운 방법은 commands 모듈 (Linux 만 해당)입니다.

> import commands
> commands.getstatusoutput("grep matter alice-in-wonderland.txt")
(0, "'Then it doesn't matter which way you go,' said the Cat.")

Tuple의 첫 번째 항목은 프로세스의 리턴 코드입니다. 두 번째 항목은 표준 출력 (및 표준 오류, 병합)입니다.


파이썬 개발자들은 명령 모듈을 '비추천'하지만 사용하지 않아도된다는 의미는 아닙니다. 단지 더 이상 개발하지 않는다는 것입니다. 작지만 중요한 기능에서 이미 완벽하기 때문에 괜찮습니다.

1
Colonel Panic

일부 답변은 파이썬의 이전 버전과 관련되었거나 os.system 모듈을 사용하고 있었기 때문에 나는 subprocessname__을 python 3.5+에서 사용하고자하는 나와 같은 사람들에게이 답변을 게시합니다. 다음은 Linux의 트릭입니다.

import subprocess

#subprocess.run() returns a completed process object that can be inspected
c = subprocess.run(["ls", "-ltrh"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(c.stdout.decode('utf-8'))

documentation 에서 언급했듯이, PIPE값은 바이트 시퀀스이며 올바르게 표시하기 위해 디코딩을 고려해야합니다. 최신 버전의 Python의 경우 text=Trueencoding='utf-8'가 kwargs of subprocess.run() 에 추가됩니다. 

위에서 언급 한 코드의 출력은 다음과 같습니다.

total 113M
-rwxr-xr-x  1 farzad farzad  307 Jan 15  2018 vpnscript
-rwxrwxr-x  1 farzad farzad  204 Jan 15  2018 ex
drwxrwxr-x  4 farzad farzad 4.0K Jan 22  2018 scripts
.... # some other lines
1
Farzad Vertigo

더 이상 사용되지 않는 commands 모듈의 Legacy Shell Invocation Functionssubprocess.getoutput()subprocess.getstatusutput()을 사용할 수도 있습니다.

subprocess.getstatusoutput(cmd)

셸에서 exitcode을 실행 한 (output, cmd)을 반환합니다.


subprocess.getoutput(cmd)

Shell에서 stdout을 실행 한 결과 (stderrcmd)를 반환합니다.

0
Pedro Lobito

import을 사용한 다음 파일 이름을 사용할 수 있습니다. 예를 들어 내장 모듈 'random'을 사용하는 경우 : import random

0
Chris Oliver

명령에서NOT사용자 입력을 사용하는 경우이 명령을 사용할 수 있습니다

from os import getcwd
from subprocess import check_output
from shlex import quote

def sh(command):
    return check_output(quote(command), Shell=True, cwd=getcwd(), universal_newlines=True).strip()

그리고 다음과 같이 사용하십시오.

branch = sh('git rev-parse --abbrev-ref HEAD') 

Shell=True는 셸을 생성하므로 파이프와 셸 같은 것들을 사용할 수 있습니다 sh('ps aux | grep python'). 이것은 하드 코딩 된 명령을 실행하고 출력을 처리하는 데 매우 편리합니다. universal_lines=True는 바이너리가 아닌 문자열로 결과가 반환되는지 확인하십시오.

cwd=getcwd() 명령이 인터프리터와 동일한 작업 디렉토리로 실행되는지 확인합니다. git 명령이 위의 git 브랜치 이름 예제와 같이 작동하면 편리합니다.

몇몇 조리법

  • 메가 바이트 단위로 사용 가능한 메모리 : sh('free -m').split('\n')[1].split()[1]
  • 여유 공간/백분율 sh('df -m /').split('\n')[1].split()[4][0:-1]
  • cPU로드 sum(map(float, sh('ps -ef -o pcpu').split('\n')[1:])

그러나 이것은 문서에서 사용자 입력에 대해 안전하지 않습니다.

보안 고려 사항 ¶

다른 popen 함수와는 달리,이 구현은 결코 암시 적으로 시스템 쉘을 호출하지 않습니다. 즉, 쉘 메타 문자를 포함한 모든 문자를 자식 프로세스에 안전하게 전달할 수 있습니다. Shell = True를 통해 셸을 명시 적으로 호출하면 셸 (Shell) 주입 취약점을 피하기 위해 모든 공백과 메타 문자를 적절하게 인용하는 것이 응용 프로그램의 책임입니다.

Shell = True를 사용하면 shlex.quote () 함수를 사용하여 쉘 명령을 생성하는 데 사용될 문자열의 공백 및 쉘 메타 문자를 올바르게 이스케이프 처리 할 수 ​​있습니다.

shlex.quote()을 사용해도 셸 명령에서 사용자 입력을 사용할 때 약간의 편집증을 유지하는 것이 좋습니다. 한 가지 옵션은 하드 코딩 명령을 사용하여 일반 출력을 받아 사용자 입력별로 필터링하는 것입니다. Shell=False를 사용하면 실행하려는 프로세스 만 실행되거나 No such file or directory 오류가 발생합니다.

또한 Shell=True에 약간의 성능 영향이 있습니다. 내 테스트에서 Shell=False (기본값)보다 약 20 % 느린 것으로 보입니다.

In [50]: timeit("check_output('ls -l'.split(), universal_newlines=True)", number=1000, globals=globals())
Out[50]: 2.6801227919995654

In [51]: timeit("check_output('ls -l', universal_newlines=True, Shell=True)", number=1000, globals=globals())
Out[51]: 3.243950183999914
0
geckos

Python Shell 스크립트를 작성하고 시스템에 IPython을 설치 한 경우 bang magic을 사용하여 IPython 내에서 명령을 실행할 수 있습니다.

!ls
filelist = !ls
0