programing

하위 프로세스 호출에서 종료 코드 및 stderr 가져오기

muds 2023. 5. 31. 18:37
반응형

하위 프로세스 호출에서 종료 코드 및 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

반응형