Python · Process Management
Python Subprocesses: Set Timeouts and Handle Exit Codes Explicitly
Give external commands explicit arguments, bounded waits and distinct handling for failure and timeout.

A command that works in a terminal can still hang or fail when called by an application. Give every subprocess a clear input contract and a failure policy.
Pass arguments explicitly
Use subprocess.run with a sequence such as [tool_path, "--version"], where tool_path identifies the intended executable. With shell=False, the default, arguments are not interpreted as shell syntax. Validate allowed options independently; avoiding a shell does not make every command safe.
Bound the wait
Set timeout to a duration appropriate for the operation. If run exceeds that timeout, Python kills and waits for the child before raising TimeoutExpired. Process creation can delay when the timeout becomes observable, so this is not a strict wall-clock deadline for every platform.
Make failures visible
Use check=True when a nonzero exit code should fail the operation. Handle CalledProcessError separately from TimeoutExpired so callers can distinguish a rejected command from a stalled one.
Choose output handling
capture_output=True collects stdout and stderr; text=True decodes them as text. For large or unbounded output, prefer a deliberate file or streaming strategy instead of accumulating everything in memory.
Test success, nonzero exit and timeout paths. Report useful context without exposing secrets in arguments or captured output.