Python中获取命令退出码遇异常:终端正常但Python调用结果不符
Hey there! Let's break down why your current approach isn't working and get you a solution that both shows the command's output on screen and captures the correct exit code.
Why Your Current Methods Are Failing
Let's unpack the issues with each of your attempts:
os.system(commandA)+os.popen('echo $?')
Every call toos.system,os.popen, orsubprocessspawns a separate child process with its own isolated environment. When you runos.popen('echo $?')afteros.system, you're getting the exit code of theechocommand itself (which is always 0, since it runs successfully)—not the exit code ofcommandA.The good news? You don't need the
echo $?workaround at all.os.systemreturns the command's exit status directly; you just need to parse it correctly (it returns a 16-bit value where the high 8 bits hold the actual exit code):import os ret = os.system(commandA) exit_code = ret >> 8 # Extracts the exit code (1 in your case) print(f"Exit code: {exit_code}")This will also show
commandA's output on your screen by default.os.popen('commandA;echo $?').read()
This works for capturing the exit code because both commands run in the same child process, soecho $?picks upcommandA's exit code. Butos.popencaptures the command's stdout by default, which means you won't see anything on the screen—all output is stored in the string returned by.read().
The Recommended Solution: subprocess.run()
The subprocess module is the modern, flexible way to run external commands in Python, and it solves both your problems seamlessly: it shows the command's output on screen and lets you access the exit code directly.
Basic Usage (No Exception on Failure)
This runs commandA, prints its output to your terminal, and lets you check the exit code afterward:
import subprocess # Split your command into a list (use shell=True only if necessary, as it's less secure) result = subprocess.run(commandA.split()) # Access the exit code directly print(f"Command exit code: {result.returncode}")
Handling Failure Explicitly
If you want to automatically handle the failure case (e.g., raise an error when the command exits with a non-zero code), use check=True:
import subprocess try: # Raises an exception if commandA exits with a non-zero code result = subprocess.run(commandA.split(), check=True) print("Command succeeded!") except subprocess.CalledProcessError as e: print(f"Command failed with exit code: {e.returncode}") # The command's output is still printed to the screen by default
Why This Works
subprocess.run()executescommandAin a single child process, soresult.returncodedirectly gives you the command's exit code.- By default,
stdoutandstderrinherit the current process's output streams—so you'll see all ofcommandA's output on your terminal just like when you run it manually in the shell.
内容的提问来源于stack exchange,提问作者Jieke Wei

