203 — Running Shell Commands from Python

Intermediate

Use Python's stdlib `subprocess.run()` to shell out to system commands from your scripts — capturing stdout and stderr, checking exit codes, raising errors on failure with `check=True`, and passing custom environments. Then extend `env_deploy_check.py` with a live system health check that shells out to `git` or `df`.

Learning Objectives

1
Run shell commands from Python using subprocess.run() and inspect the CompletedProcess result object
2
Capture command stdout and stderr as strings with capture_output=True and text=True
3
Detect command failures by checking returncode and branch on success or failure
4
Raise CalledProcessError automatically on non-zero exit codes using check=True
5
Understand when shell=False (default, safe) and shell=True (convenient, risky) are appropriate
6
Pass a custom environment dictionary to a subprocess using the env= parameter
7
Prevent hung subprocesses with the timeout= parameter and handle TimeoutExpired
8
Extend env_deploy_check.py with a subprocess-based system check that shells out and reports results
Step 1

Set up the lesson 203 workspace

Create a dedicated directory, activate the virtual environment, and confirm the `subprocess` module is available. `subprocess` is part of the Python standard library — no pip install needed.

Commands to Run

mkdir -p ~/devops-python/lesson-203
cd ~/devops-python/lesson-203
source ~/devops-python/lesson-101/devops-env/bin/activate
python3 -c "import subprocess; print('subprocess module OK'); print('run available:', callable(subprocess.run))"

What This Does

The subprocess module lets Python scripts start external programs, capture their output, and react to their exit codes — replacing the older os.system() and os.popen() calls. subprocess.run() is the high-level, recommended API added in Python 3.5.

It replaces subprocess.call(), subprocess.check_call(), and subprocess.check_output() for the vast majority of use cases.

Expected Outcome

Your terminal prompt shows (devops-env).

The one-liner prints subprocess module OK and run available: True.

Pro Tips

  • 1
    If you placed your virtual environment at a different path in Lesson 101, adjust the `source` command to match your actual venv location.
  • 2
    `subprocess.run()` was added in Python 3.5 and `capture_output=True` was added in Python 3.7. Because this course targets Python 3.10+, both are safe to use without version guards.
Was this step helpful?

All Steps (0 / 8 completed)