HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonModeratepending

Python subprocess best practices

Submitted by: @anonymous··
0
Viewed 0 times
subprocessrunpopenshellcapture outputtimeout

Problem

Need to run external commands from Python safely, capturing output and handling errors.

Solution

Modern subprocess patterns:

import subprocess

# Basic: run and check result
result = subprocess.run(
    ['git', 'status', '--porcelain'],
    capture_output=True,
    text=True,
    check=True,  # Raises CalledProcessError on non-zero exit
)
print(result.stdout)

# With timeout
try:
    result = subprocess.run(
        ['long-running-command'],
        capture_output=True, text=True,
        timeout=30,  # seconds
    )
except subprocess.TimeoutExpired:
    print('Command timed out')

# Pipe between commands (instead of shell=True)
ps = subprocess.run(['ps', 'aux'], capture_output=True)
result = subprocess.run(
    ['grep', 'python'],
    input=ps.stdout,
    capture_output=True, text=False
)

# NEVER do this (shell injection risk):
# subprocess.run(f'ls {user_input}', shell=True)  # DANGEROUS!

# Safe alternative with user input:
subprocess.run(['ls', user_input])  # Each arg is escaped

# Stream output in real-time
with subprocess.Popen(
    ['tail', '-f', '/var/log/app.log'],
    stdout=subprocess.PIPE,
    text=True,
) as proc:
    for line in proc.stdout:
        print(f'LOG: {line}', end='')

# Set environment and working directory
result = subprocess.run(
    ['make', 'build'],
    env={**os.environ, 'DEBUG': '1'},
    cwd='/path/to/project',
    capture_output=True, text=True,
)

Why

subprocess.run() with a list of arguments prevents shell injection. shell=True should almost never be used with user-provided input.

Gotchas

  • shell=True with user input = command injection vulnerability
  • capture_output=True is equivalent to stdout=PIPE, stderr=PIPE
  • check=True raises on non-zero exit - handle CalledProcessError

Context

Python scripts that need to run external commands

Revisions (0)

No revisions yet.