Learn Subprocess.run() in Python [Step-by-Step Examples]

subprocess.run() is a Python function that is part of the subprocess module, which allows you to create and manage additional processes from within your Python script. It is a high-level function for running shell commands or other processes and is often used to replace the older os.system() and os.spawn*() functions.

Here’s the basic syntax of subprocess.run():

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
Code language: Python (python)

Here is an explanation of some of the key parameters:

  • args: This is a required argument and should be a list or string containing the command you want to run and its arguments.
  • stdin, stdout, stderr: These parameters allow you to specify the standard input, standard output, and standard error of the subprocess. They can be set to subprocess.PIPE to capture or redirect these streams.
  • shell: If set to True, the args parameter is treated as a single command string, and the command is run in a shell. This can be useful for running complex shell commands with pipes and redirects. However, be cautious when using shell=True to avoid security risks associated with shell injection.
  • cwd: Specifies the working directory for the subprocess.
  • timeout: Sets a timeout for the subprocess in seconds. If the subprocess runs longer than the specified timeout, it will be terminated.
  • check: If set to True, subprocess.run() will raise a CalledProcessError if the command returns a non-zero exit status, indicating an error.
  • encoding and errors: These parameters control the text encoding and error handling for input and output.
  • text: If set to True, the stdout and stderr streams will be treated as text and returned as strings rather than bytes.
  • env: Allows you to specify environment variables for the subprocess.

Here’s an example of using subprocess.run() to execute a simple shell command:

import subprocess

# Run a basic shell command (list form)
result = subprocess.run(["ls", "-l"], stdout=subprocess.PIPE, text=True)

# Print the command's output
print(result.stdout)
Code language: Python (python)

In this example, we run the ls -l command, capture its standard output, and print it. You can use subprocess.run() to run any command-line program or script, passing the appropriate command and arguments in the args parameter.

Learn More >> What Is The Difference Between Subprocess.popen And Subprocess.run

Running A Simple Command

Here’s an example of running a simple command using subprocess.run():

import subprocess

# Define the command as a list of strings
command = ["echo", "Hello, World!"]

# Run the command
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)

# Print the command's output
print(result.stdout)
Code language: Python (python)

In this example, we define the command variable as a list of strings, where the first string is the command to run (“echo”) and the second string is its argument (“Hello, World!”). We then use subprocess.run() to execute the command, capturing its standard output. Finally, we print the output, which will display “Hello, World!” to the console.

Capturing The Output Of A Command

You can capture the output of a command using subprocess.run() by specifying stdout=subprocess.PIPE in the subprocess.run() call. This redirects the standard output of the command to a pipe, allowing you to access and manipulate the output in your Python script. Here’s an example:

import subprocess

# Define the command as a list of strings
command = ["ls", "-l"]

# Run the command and capture its output
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)

# Check if the command was successful (exit code 0)
if result.returncode == 0:
    # Access and print the captured output
    print("Command Output:")
    print(result.stdout)
else:
    print(f"Command failed with exit code {result.returncode}")
Code language: Python (python)

In this example, we run the ls -l command and capture its standard output. We use stdout=subprocess.PIPE to redirect the output to a pipe. After running the command, we check the returncode attribute of the result object to see if the command was successful (exit code 0). If it was successful, we print the captured output using result.stdout.

You can replace ls -l with any other command you want to run, and the captured output will be available for further processing within your Python script.

Handling All Errors And Exceptions

When using subprocess.run() to run external commands, it’s important to handle errors and exceptions effectively to ensure the robustness of your Python script. Here are some common techniques to handle errors and exceptions when using subprocess.run():

Check the Exit Code:

  1. The returncode attribute of the CompletedProcess object returned by subprocess.run() contains the exit code of the command. A value of 0 typically indicates success, while non-zero values usually indicate an error.
  2. You can check the exit code and take appropriate actions based on it.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
    # Command was successful
    print(result.stdout)
else:
    # Command failed, handle the error
    print(f"Command failed with exit code {result.returncode}")
    print(result.stderr)Code language: Python (python)

Handling Exceptions:

  • subprocess.run() can raise various exceptions, such as subprocess.CalledProcessError if check=True and the command returns a non-zero exit code.
  • You can use a try...except block to catch exceptions and handle them gracefully.
try:
    result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True)
    print(result.stdout)
except subprocess.CalledProcessError as e:
    # Command failed with a non-zero exit code
    print(f"Command failed with exit code {e.returncode}")
    print(e.stderr)
except Exception as e:
    # Handle other exceptions, e.g., FileNotFoundError
    print(f"An error occurred: {str(e)}")
Code language: Python (python)

Standard Error (stderr) Handling:

  • Sometimes, error messages are written to the standard error stream (stderr) instead of the standard output (stdout). You should capture and handle stderr as well.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
    print(result.stdout)
else:
    print(f"Command failed with exit code {result.returncode}")
    # Print both stdout and stderr for error diagnostics
    print(result.stdout)
    print(result.stderr)
Code language: Python (python)

Timeout Handling:

  • If you specify a timeout value, you can catch a subprocess.TimeoutExpired exception if the command exceeds the specified timeout.
try:
    result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=30)
    print(result.stdout)
except subprocess.TimeoutExpired:
    print("Command timed out")
Code language: Python (python)

By incorporating these error-handling techniques, your Python script can gracefully handle various situations when running external commands using subprocess.run(). This helps ensure that your script remains reliable and robust in the face of unexpected errors or exceptions.

Setting Working Directory And Environment Variables

When using subprocess.run() to run an external command, you can set the working directory and environment variables for the subprocess using the cwd and env parameters, respectively. Here’s how you can do it:

  1. Setting the Working Directory (cwd): You can specify the working directory in which the command should be executed using the cwd parameter. This is useful when you want the subprocess to work in a specific directory.
import subprocess

command = ["ls"]

# Set the working directory
working_directory = "/path/to/directory"
result = subprocess.run(command, cwd=working_directory, stdout=subprocess.PIPE, text=True)

print(result.stdout)Code language: Python (python)
  1. Setting Environment Variables (env): You can set environment variables for the subprocess using the env parameter. This allows you to customize the environment in which the command runs.
import subprocess

command = ["echo", "$MY_VARIABLE"]

# Define custom environment variables
custom_env = {"MY_VARIABLE": "Hello, World!"}

result = subprocess.run(command, stdout=subprocess.PIPE, text=True, env=custom_env)

print(result.stdout)
Code language: Python (python)

In this example, we set the MY_VARIABLE environment variable to "Hello, World!" before running the echo command. The subprocess will have access to this environment variable.

By using cwd and env, you can control the context and environment in which the subprocess runs, making it possible to tailor the execution environment to your specific requirements.

Controlling Input And Output Streams

You can control input and output streams when running external commands using subprocess.run() by specifying the stdin, stdout, and stderr parameters. These parameters allow you to customize how data flows between your Python script and the subprocess.

  1. Controlling Standard Input (stdin): You can provide input to the subprocess by specifying the stdin parameter. There are several options for this parameter:
    • subprocess.PIPE: This captures the standard input stream, allowing you to send input data from your Python script to the subprocess.
    • subprocess.DEVNULL: This discards the standard input, effectively making it empty.
    • A file object: You can pass an open file object to provide input from a file.
    • A string: You can provide input as a string.
    Here’s an example using subprocess.PIPE to pass input to a subprocess:
import subprocess

command = ["cat"]

# Providing input using stdin
input_data = "Hello, subprocess!"
result = subprocess.run(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, input=input_data)

print(result.stdout)
Code language: Python (python)
  1. Redirecting Standard Output (stdout): You can specify how the subprocess’s standard output is handled using the stdout parameter:
  • subprocess.PIPE: This captures the standard output stream, allowing you to read and process the subprocess’s output in your Python script.
  • subprocess.DEVNULL: This discards the standard output, effectively suppressing it.
  • A file object: You can pass an open file object to redirect the subprocess’s output to a file.

Example using subprocess.PIPE to capture and process the output:

import subprocess

command = ["ls"]

# Capturing and processing the output using stdout=subprocess.PIPE
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)

print(result.stdout)
Code language: Python (python)
  1. Redirecting Standard Error (stderr): Similar to standard output, you can control how the subprocess’s standard error is handled using the stderr parameter. The options are the same as for stdout.

Example using subprocess.PIPE to capture and process standard error:

import subprocess

command = ["ls", "nonexistent_directory"]

# Capturing and processing standard error using stderr=subprocess.PIPE
result = subprocess.run(command, stderr=subprocess.PIPE, text=True)

print(result.stderr)Code language: Python (python)

By using these parameters, you can effectively control the flow of data between your Python script and the subprocess, allowing you to provide input, capture output, and handle errors as needed.

Read More;

    by
  • Aniket Singh

    Aniket Singh holds a B.Tech in Computer Science & Engineering from Oriental University. He is a skilled programmer with a strong coding background, having hands-on experience in developing advanced projects, particularly in Python and the Django framework. Aniket has worked on various real-world industry projects and has a solid command of Python, Django, REST API, PostgreSQL, as well as proficiency in C and C++. He is eager to collaborate with experienced professionals to further enhance his skills.

Leave a Comment