파이썬에서 시스템 호출을 만들고 파이썬 프로그램에서 조작 할 수있는 문자열에 출력을 저장하려고합니다.
#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")
여기에 몇 가지 제안을 포함하여 몇 가지 시도를했습니다.
그러나 운없이.
파이썬에서 시스템 호출을 만들고 파이썬 프로그램에서 조작 할 수있는 문자열에 출력을 저장하려고합니다.
#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")
여기에 몇 가지 제안을 포함하여 몇 가지 시도를했습니다.
그러나 운없이.
답변:
Python 2.7 또는 Python 3에서
Popen
객체를 직접 만드는 대신 subprocess.check_output()
함수 를 사용하여 명령의 출력을 문자열에 저장할 수 있습니다 .
from subprocess import check_output
out = check_output(["ntpq", "-p"])
파이썬 2.4-2.6에서
communicate
방법을 사용하십시오 .
import subprocess
p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE)
out, err = p.communicate()
out
당신이 원하는 것입니다.
다른 답변에 대한 중요 사항
내가 명령을 어떻게 전달했는지 주목하십시오. 이 "ntpq -p"
예는 또 다른 문제를 제기합니다. Popen
쉘을 호출하지 않기 때문에 명령 및 옵션 목록 —을 사용합니다 ["ntpq", "-p"]
.
Popen.communicate
은 프로세스가 종료 될 때까지 반환되지 않습니다.
p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.check_output()
a가 아닌 bytes
객체를 반환 합니다 str
. 결과를 인쇄하는 것만으로도 아무런 차이가 없습니다. 그러나 myString.split("\n")
결과 와 같은 방법을 사용 하려면 먼저 bytes
객체를 디코딩해야 합니다. 예 subprocess.check_output(myParams).decode("utf-8")
를 들어.
universal_newlines=True
파이썬 3에서 매개 변수로 추가 하면 문자열 객체를 얻는 데 도움이되었습니다. universal_newlines가 True 인 경우 기본 인코딩을 사용하여 텍스트 모드로 열립니다. 그렇지 않으면 이진 스트림으로 열립니다.
이것은 stdout을 리디렉션하는 데 도움이되었습니다 (stderr도 비슷하게 처리 할 수 있습니다).
from subprocess import Popen, PIPE
pipe = Popen(path, stdout=PIPE)
text = pipe.communicate()[0]
그래도 문제가 해결되지 않으면 발생한 문제를 정확하게 지정하십시오.
\n
합니다.
pipe.returncode == 0
마지막 줄 이후에도 확인하고 싶을 것입니다 .
Popen
는 stdout
및 의 튜플을 반환 하기 때문에 stderr
액세스 [0]
할 때 stdout
. 당신은 또한 할 수있는 text, err = pipe.communicate()
다음 text
당신이 무엇을 기대해야합니다
pwd
이것이 단지 예 라고 가정하면 다음과 같이 할 수 있습니다.
import subprocess
p = subprocess.Popen("pwd", stdout=subprocess.PIPE)
result = p.communicate()[0]
print result
다른 예 와 자세한 내용은 하위 프로세스 설명서 를 참조하십시오.
subprocess.Popen : http://docs.python.org/2/library/subprocess.html#subprocess.Popen
import subprocess
command = "ntpq -p" # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)
#Launch the shell command:
output = process.communicate()
print output[0]
Popen 생성자에서 shell 이 True 인 경우 명령을 시퀀스가 아닌 문자열로 전달해야합니다. 그렇지 않으면 명령을 목록으로 나누십시오.
command = ["ntpq", "-p"] # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
당신이는 popen 초기화로, 또한 표준 오류를 읽을 필요가 있다면, 당신은 설정할 수 있습니다 열려진 에 subprocess.PIPE 하거나 subprocess.STDOUT :
import subprocess
command = "ntpq -p" # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
#Launch the shell command:
output, error = process.communicate()
파이썬 2.7+의 경우 관용적 인 대답은 subprocess.check_output()
또한 서브 프로세스를 호출 할 때 인수를 다루는 것이 약간 혼란 스러울 수 있으므로주의해야합니다.
args가 자신 만의 args가없는 단일 명령 인 경우 (또는 shell=True
설정 한 경우) 문자열 일 수 있습니다. 그렇지 않으면 목록이어야합니다.
예를 들어 ... ls
명령 을 호출하려면 다음 과 같이하십시오.
from subprocess import check_call
check_call('ls')
이것도 마찬가지입니다 :
from subprocess import check_call
check_call(['ls',])
그러나 일부 args를 쉘 명령에 전달하려면 다음 을 수행 할 수 없습니다 .
from subprocess import check_call
check_call('ls -al')
대신 목록으로 전달해야합니다.
from subprocess import check_call
check_call(['ls', '-al'])
그만큼 shlex.split()
함수는 하위 프로세스를 만들기 전에 문자열을 쉘과 같은 구문으로 나누는 데 유용 할 수 있습니다.
from subprocess import check_call
import shlex
check_call(shlex.split('ls -al'))
이것은 나를 위해 완벽하게 작동합니다.
import subprocess
try:
#prints results and merges stdout and std
result = subprocess.check_output("echo %USERNAME%", stderr=subprocess.STDOUT, shell=True)
print result
#causes error and merges stdout and stderr
result = subprocess.check_output("copy testfds", stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError, ex: # error code <> 0
print "--------error------"
print ex.cmd
print ex.message
print ex.returncode
print ex.output # contains stdout and stderr together
이것은 나에게 완벽했다. 리턴 코드, stdout 및 stderr가 튜플에 표시됩니다.
from subprocess import Popen, PIPE
def console(cmd):
p = Popen(cmd, shell=True, stdout=PIPE)
out, err = p.communicate()
return (p.returncode, out, err)
예를 들어 :
result = console('ls -l')
print 'returncode: %s' % result[0]
print 'output: %s' % result[1]
print 'error: %s' % result[2]
받아 들여진 대답은 여전히 좋으며 새로운 기능에 대한 몇 가지 언급입니다. python 3.6부터는에서 직접 인코딩을 처리 할 수 있습니다 ( 문서check_output
참조) . 이제 문자열 객체를 반환합니다 :
import subprocess
out = subprocess.check_output(["ls", "-l"], encoding="utf-8")
python 3.7에서는 매개 변수 capture_output
가 subprocess.run ()에 추가되었습니다. 이 매개 변수 는 Popen / PIPE 처리 중 일부를 수행합니다 . python 문서를 참조하십시오 .
import subprocess
p2 = subprocess.run(["ls", "-l"], capture_output=True, encoding="utf-8")
p2.stdout
import os
list = os.popen('pwd').read()
이 경우 목록에 하나의 요소 만 있습니다.
os.popen
subprocess
모듈 을 위해 더 이상 사용되지 않습니다 .
나는 여기에 다른 답변을 기반으로 작은 함수를 작성했습니다.
def pexec(*args):
return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].rstrip()
용법:
changeset = pexec('hg','id','--id')
branch = pexec('hg','id','--branch')
revnum = pexec('hg','id','--num')
print('%s : %s (%s)' % (revnum, changeset, branch))
다음은 단일 변수에서 프로세스의 stdout 및 stderr을 캡처합니다. Python 2 및 3과 호환됩니다.
from subprocess import check_output, CalledProcessError, STDOUT
command = ["ls", "-l"]
try:
output = check_output(command, stderr=STDOUT).decode()
success = True
except CalledProcessError as e:
output = e.output.decode()
success = False
명령이 배열이 아닌 문자열 인 경우 접두사로 다음을 지정하십시오.
import shlex
command = shlex.split(command)
파이썬 3.5의 경우 이전 답변을 기반으로 함수를 작성했습니다. 로그가 삭제되었을 수 있습니다.
import shlex
from subprocess import check_output, CalledProcessError, STDOUT
def cmdline(command):
log("cmdline:{}".format(command))
cmdArr = shlex.split(command)
try:
output = check_output(cmdArr, stderr=STDOUT).decode()
log("Success:{}".format(output))
except (CalledProcessError) as e:
output = e.output.decode()
log("Fail:{}".format(output))
except (Exception) as e:
output = str(e);
log("Fail:{}".format(e))
return str(output)
def log(msg):
msg = str(msg)
d_date = datetime.datetime.now()
now = str(d_date.strftime("%Y-%m-%d %H:%M:%S"))
print(now + " " + msg)
if ("LOG_FILE" in globals()):
with open(LOG_FILE, "a") as myfile:
myfile.write(now + " " + msg + "\n")
"ntpq -p"
의 다른 부분이다, 당신이 요구하는 것보다 문제.