CompTIA Linux+ (XK0-006)Automation, Orchestration and ScriptingMedium
A developer needs to create a Python script that uses the `subprocess` module to run an external shell command and capture its standard output. The command to be executed is `ls -l /tmp`. Which of the following Python code snippets correctly executes the command and captures its output as a string?
- Aimport subprocess process = subprocess.Popen(['ls', '-l', '/tmp'], stdout=subprocess.PIPE) output = process.communicate()[0]
- Bimport subprocess output = subprocess.call(['ls', '-l', '/tmp'], stdout=subprocess.PIPE)
- Cimport subprocess output = subprocess.check_output('ls -l /tmp', shell=True)
- Dimport subprocess output = subprocess.run(['ls', '-l', '/tmp'], capture_output=True, text=True).stdout
Show answer & explanationAnswer & explanation
Correct answer: D. import subprocess output = subprocess.run(['ls', '-l', '/tmp'], capture_output=True, text=True).stdout
The `subprocess.run()` function is the recommended way to run external commands in Python 3.5+. Setting `capture_output=True` captures stdout and stderr, and `text=True` (or `encoding='utf-8'`) decodes the output into a string. The captured stdout is then accessed via the `.stdout` attribute of the returned `CompletedProcess` object.
Why the other options are wrong
- A. `subprocess.Popen()` is a lower-level interface. While correct, `subprocess.run()` is preferred for simple command execution and output capture due to its higher-level abstraction and convenience.
- B. `subprocess.call()` returns the exit code, not the output. `stdout=subprocess.PIPE` would capture output, but it's not returned by `call`.
- C. `subprocess.check_output()` works but is less flexible than `subprocess.run()` and can raise `CalledProcessError`. It also defaults to bytes output.
Python `subprocess.run()`
The `subprocess.run()` function is the recommended high-level API for running external commands in Python. It waits for the command to complete and returns a `CompletedProcess` object.
- Introduced in Python 3.5; replaces `call`, `check_call`, `check_output` for most use cases.
- `capture_output=True` captures stdout and stderr.
- `text=True` (or `encoding`) decodes output to string; otherwise, it's bytes.
- Returns `CompletedProcess` object with `stdout`, `stderr`, and `returncode` attributes.
Memory trick: Run the command, capture the text, then you're all set!