Python: Capture 7-Zip Stdout and Stderr Separately
This guide demonstrates how to execute 7-Zip commands from a Python
script while isolating the standard output (stdout) and
standard error (stderr) streams into distinct variables. By
using Python's built-in subprocess module, you can
programmatically extract diagnostic logs, verify compression or
extraction progress, and catch specific execution errors without
intermingling the data streams.
Using subprocess.run
(Python 3.7+)
The most straightforward method to capture both streams separately is
subprocess.run() with stdout=subprocess.PIPE
and stderr=subprocess.PIPE. Setting text=True
ensures the outputs are decoded from raw bytes into strings.
import subprocess
# Define the 7-Zip command and arguments
cmd = ["7z", "a", "backup.7z", "data_folder/"]
# Execute the process and capture streams separately
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Access stdout and stderr
stdout_data = result.stdout
stderr_data = result.stderr
return_code = result.returncode
print(f"Exit Code: {return_code}")
print("--- STDOUT ---")
print(stdout_data)
print("--- STDERR ---")
print(stderr_data)Alternatively, capture_output=True can be used as
shorthand for setting both stdout and stderr
to subprocess.PIPE:
result = subprocess.run(cmd, capture_output=True, text=True)Real-Time Streaming
with subprocess.Popen
If 7-Zip is archiving large directories, subprocess.run
will block until the process finishes. To read both streams concurrently
during execution without blocking or causing buffer deadlocks, use
subprocess.Popen along with standard threading or the
communicate() method.
The communicate() method waits for completion and
guarantees proper separation:
import subprocess
cmd = ["7z", "x", "backup.7z", "-oextracted/"]
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# communicate() reads both streams until EOF and avoids deadlock
stdout_data, stderr_data = process.communicate()
if process.returncode != 0:
print(f"7-Zip encountered an error (Code {process.returncode}):")
print(stderr_data)
else:
print("Archive extracted successfully:")
print(stdout_data)Interpreting 7-Zip Return Codes
When processing the outputs, note that 7-Zip uses specific exit codes:
- 0: Normal execution (Success)
- 1: Warning (Non-fatal error, such as locked files skipped)
- 2: Fatal error
- 7: Command line error
- 8: Not enough memory for operation
- 255: User stopped the process
Even when non-fatal warnings occur (Exit Code 1), 7-Zip may write
operational details to stdout while placing error-specific
diagnostics into stderr. Checking both streams alongside
result.returncode provides the most accurate status of the
archive operation.