하위 프로세스 호출에서 종료 코드 및 stderr 가져오기
하위 프로세스 - call, check_call, check_output에서 제공하는 기능을 읽고 각 기능이 어떻게 작동하고 기능이 서로 다른지 이해합니다.현재 check_output을 사용하고 있으므로 stdout에 액세스할 수 있으며 다음과 같이 "try block"을 사용하여 예외를 탐지했습니다.
# "cmnd" is a string that contains the command along with it's arguments.
try:
cmnd_output = check_output(cmnd, stderr=STDOUT, shell=True, timeout=3, universal_newlines=True);
except CalledProcessError:
print("Status : FAIL")
print("Output: \n{}\n".format(cmnd_output))
예외가 발생하면 "cmnd_output"이 초기화되지 않고 stderr에 액세스할 수 없는 경우 다음 오류 메시지가 표시됩니다.
print("Output: \n{}\n".format(cmnd_output))
UnboundLocalError: local variable 'cmnd_output' referenced before assignment
예외로 인해 try 블록에서 "cmnd_output"에 대한 할당이라고 하는 추가 처리 없이 "check_output"이 즉시 bail이 발생하기 때문이라고 생각합니다.제가 틀렸다면 고쳐주세요.
stderr(stout으로 보내도 괜찮습니다)에 액세스하고 종료 코드에 액세스할 수 있는 방법이 있습니까?예외 없이 종료 코드를 기준으로 수동으로 통과/실패를 확인할 수 있습니다.
감사합니다, 아흐메드
이 버전을 사용해 보십시오.
import subprocess
try:
output = subprocess.check_output(
cmnd, stderr=subprocess.STDOUT, shell=True, timeout=3,
universal_newlines=True)
except subprocess.CalledProcessError as exc:
print("Status : FAIL", exc.returncode, exc.output)
else:
print("Output: \n{}\n".format(output))
이렇게 하면 통화가 성공한 경우에만 출력이 인쇄됩니다.의 경우 반품 코드와 출력을 출력합니다.
허용된 해결책은 당신이 혼합해도 괜찮은 경우를 포함합니다.stdout
그리고.stderr
그러나 자녀 프로세스(이유가 무엇이든 간에)가 사용하기로 결정한 경우stderr
에 더하여stdout
실패하지 않은 출력(즉, 중요하지 않은 경고 출력)의 경우, 주어진 솔루션이 바람직하지 않을 수 있습니다.
예를 들어, JSON으로 변환하는 것과 같은 출력에 대한 추가 처리를 수행할 경우, 다음과 같이 혼합합니다.stderr
그러면 추가로 인해 출력이 순수 JSON이 아니기 때문에 전체 프로세스가 실패합니다.stderr
산출량.
이 경우에 도움이 될 만한 것은 다음과 같습니다.
cmd_args = ... what you want to execute ...
pipes = subprocess.Popen(cmd_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#If you are using python 2.x, you need to include shell=True in the above line
std_out, std_err = pipes.communicate()
if pipes.returncode != 0:
# an error happened!
err_msg = "%s. Code: %s" % (std_err.strip(), pipes.returncode)
raise Exception(err_msg)
elif len(std_err):
# return code is 0 (no error), but we may want to
# do something with the info on std_err
# i.e. logger.warning(std_err)
# do whatever you want with std_out
# i.e. json.loads(std_out)
제안된 두 솔루션 모두 stdout/stderr을 혼합하거나 다음을 사용합니다.Popen
그것은 사용하는 것만큼 간단하지 않습니다.check_output
그러나 다음을 사용하는 동안 동일한 작업을 수행하고 stdout/stderr을 별도로 유지할 수 있습니다.check_output
파이프를 사용하여 단순히 stderr을 캡처하는 경우:
import sys
import subprocess
try:
subprocess.check_output(cmnd, stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
print('exit code: {}'.format(e.returncode))
print('stdout: {}'.format(e.output.decode(sys.getfilesystemencoding())))
print('stderr: {}'.format(e.stderr.decode(sys.getfilesystemencoding())))
이 예에서는 stderr을 캡처했으므로 예외의 경우 사용할 수 있습니다.stderr
속성(파이프로 캡처하지 않으면 그냥.None
).
저도 비슷한 요구사항이 있었고, 다음과 같은 것들이 저에게 효과가 있었습니다.
try:
with open ("vtcstderr.out", "w") as file:
rawOutput = subprocess.check_output(
command,
stderr=file,
shell=True
)
except subprocess.CalledProcessError as error:
# this is the stdout
rawOutput = error.output
with open ("vtcstderr.out", "r") as file:
# this is the stderr
errorLines = file.readlines()
try 문 앞에 변수 cmnd_output을 초기화하는 것이 어떻습니까?그렇게 하면 당신이 기대하는 대로 작동할 것입니다.다음 행을 사용할 수 있습니다. try 문 위에 추가하기만 하면 됩니다.
cmnd_output = ''
언급URL : https://stackoverflow.com/questions/16198546/get-exit-code-and-stderr-from-subprocess-call
'programing' 카테고리의 다른 글
Rspec에서 특정 테스트만 실행하려면 어떻게 해야 합니까? (0) | 2023.05.31 |
---|---|
node.js 앱을 백그라운드 서비스로 실행하려면 어떻게 해야 합니까? (0) | 2023.05.31 |
NSZombie란 무엇입니까? (0) | 2023.05.31 |
Vue 2 - 음소거 소품 Vue-warn (0) | 2023.05.31 |
RVM: gemset의 모든 gem 제거 (0) | 2023.05.31 |