복붙노트

[PYTHON] Python subprocess.check_output ()에서 예외 출력을 잡는 방법?

PYTHON

Python subprocess.check_output ()에서 예외 출력을 잡는 방법?

파이썬 내에서 Bitcoin 지불을하려고합니다. bash에서 나는 보통 이것을 할 것이다 :

bitcoin sendtoaddress <bitcoin address> <amount>

그래서 예를 들면 :

bitcoin sendtoaddress 1HoCUcbK9RbVnuaGQwiyaJGGAG6xrTPC9y 1.4214

성공한 경우 트랜잭션 ID를 출력으로 받지만 비트 코인 잔액보다 큰 금액을 전송하려고하면 다음과 같은 출력이 표시됩니다.

error: {"code":-4,"message":"Insufficient funds"}

파이썬 프로그램에서 나는 이제 다음과 같이 지불을 시도합니다 :

import subprocess

try:
    output = subprocess.check_output(['bitcoin', 'sendtoaddress', address, str(amount)])
except:
    print "Unexpected error:", sys.exc_info()

균형이 충분하다면 잘 작동하지만, 균형이 충분하지 않으면 sys.exc_info ()가 다음을 인쇄합니다.

(<class 'subprocess.CalledProcessError'>, CalledProcessError(), <traceback object at 0x7f339599ac68>)

그것은 내가 명령 줄에 얻을 오류를 포함하지 않습니다. 그래서 내 질문은; 파이썬에서 출력 된 오류 ({ "코드": - 4, "메시지": "불충분 한 자금"})을 어떻게 얻을 수 있습니까?

모든 팁을 환영합니다!

해결법

  1. ==============================

    1.subprocess.check_output () 문서에 따르면 오류 발생시 발생하는 예외에는 오류 세부 정보에 액세스하는 데 사용할 수있는 출력 특성이 있습니다.

    subprocess.check_output () 문서에 따르면 오류 발생시 발생하는 예외에는 오류 세부 정보에 액세스하는 데 사용할 수있는 출력 특성이 있습니다.

    try:
        subprocess.check_output(...)
    except subprocess.CalledProcessError as e:
        print e.output
    

    그런 다음이 문자열을 분석하고 json 모듈을 사용하여 오류 세부 정보를 구문 분석 할 수 있어야합니다.

    if e.output.startswith('error: {'):
        error = json.loads(e.output[7:]) # Skip "error: "
        print error['code']
        print error['message']
    
  2. ==============================

    2.나는 받아 들인 해결책이 오류 텍스트가 stderr에보고 된 경우를 처리한다고 생각하지 않습니다. 내 테스트에서 예외의 출력 특성에는 stderr의 결과가 포함되지 않았으며 docs는 check_output ()에서 stderr = PIPE를 사용하는 것에 대해 경고합니다. 대신 표준 오류 지원을 추가하여 J.F Sebastian의 솔루션에 약간의 개선점을 제안합니다. 우리는 결국 오류를 처리하려고 노력하고 있으며, 표준 오류는 종종보고되는 곳입니다.

    나는 받아 들인 해결책이 오류 텍스트가 stderr에보고 된 경우를 처리한다고 생각하지 않습니다. 내 테스트에서 예외의 출력 특성에는 stderr의 결과가 포함되지 않았으며 docs는 check_output ()에서 stderr = PIPE를 사용하는 것에 대해 경고합니다. 대신 표준 오류 지원을 추가하여 J.F Sebastian의 솔루션에 약간의 개선점을 제안합니다. 우리는 결국 오류를 처리하려고 노력하고 있으며, 표준 오류는 종종보고되는 곳입니다.

    from subprocess import Popen, PIPE
    
    p = Popen(['bitcoin', 'sendtoaddress', ..], stdout=PIPE, stderr=PIPE)
    output, error = p.communicate()
    if p.returncode != 0: 
       print("bitcoin failed %d %s %s" % (p.returncode, output, error))
    
  3. ==============================

    3."내 bitcoin balance보다 큰 금액을 전송하려고"하는 것은 예상치 못한 오류가 아닙니다. 불필요하게 예외를 발생시키지 않으려면 check_output () 대신 Popen.communicate ()를 직접 사용할 수 있습니다.

    "내 bitcoin balance보다 큰 금액을 전송하려고"하는 것은 예상치 못한 오류가 아닙니다. 불필요하게 예외를 발생시키지 않으려면 check_output () 대신 Popen.communicate ()를 직접 사용할 수 있습니다.

    from subprocess import Popen, PIPE
    
    p = Popen(['bitcoin', 'sendtoaddress', ..], stdout=PIPE)
    output = p.communicate()[0]
    if p.returncode != 0: 
       print("bitcoin failed %d %s" % (p.returncode, output))
    
  4. ==============================

    4.여기에는 좋은 대답이 있지만이 답변에는 예외의 기본 동작 인 스택 추적 결과의 텍스트가 나오지 않습니다.

    여기에는 좋은 대답이 있지만이 답변에는 예외의 기본 동작 인 스택 추적 결과의 텍스트가 나오지 않습니다.

    포맷 된 추적 정보를 사용하려면 다음과 같이하십시오.

    import traceback
    
    try:
        check_call( args )
    except CalledProcessError:
        tb = traceback.format_exc()
        tb = tb.replace(passwd, "******")
        print(tb)
        exit(1)
    

    여러분이 말할 수 있듯이 위 코드는 check_call (args)에 암호가 표시되는 것을 막기 위해 유용합니다.

  5. from https://stackoverflow.com/questions/24849998/how-to-catch-exception-output-from-python-subprocess-check-output by cc-by-sa and MIT license