Python Subprocess: A Comprehensive Guide to Executing External Commands

Pankaj Singh 10 Jan, 2024 • 7 min read

Introduction

Python subprocess is a powerful module that allows you to execute external commands from within your Python script. It provides a way to interact with the command line and run shell commands, system commands, external scripts, and more. In this comprehensive guide, we will explore the various features and functionalities of the subprocess module, along with best practices and tips for using it effectively.

Python Subprocess

Getting Started with Python Subprocess

You can import it into your Python script using the following line of code:

Code

import subprocess

Now that you have imported the subprocess module let’s dive into running basic commands with the subprocess.

Running a Basic Command With a Subprocess

The subprocess module provides several functions for executing external commands. One of the simplest ways to run a command is by using the `subprocess.run()` function. This function takes the command as a string and executes it. Here’s an example:

Code

import subprocess

result = subprocess.run("ls", shell=True, capture_output=True, text=True)

print(result.stdout)

In the above example, we are running the `ls` command to list the files and directories in the current directory. The `shell=True` argument tells the subprocess to use the shell to execute the command. The `capture_output=True` argument captures the output of the command, and the `text=True` argument ensures that the output is returned as a string.

Executing External Commands with Python subprocess

Apart from the `subprocess.run()` function, the subprocess module provides other functions for executing external commands. Let’s explore some of them.

Running a command with subprocess.run()

The `subprocess.run()` function is versatile and allows you to run a command and capture its output. It returns a `CompletedProcess` object that contains information about the command’s execution. Here’s an example:

Code

import subprocess

result = subprocess.run(["echo", "Hello, World!"], capture_output=True, text=True)

print(result.stdout)

In the above example, we are running the `echo` command to print “Hello, World!”. The command is passed as a list of strings, where each element represents a part of the command. The output of the command is captured and printed using the `result.stdout` attribute.

Capturing the output of a command

The subprocess module provides various ways to capture the output of a command. In addition to the `subprocess.run()` function, you can use the `subprocess.check_output()` function to capture the output as a byte string, or the `subprocess.PIPE` constant to capture the output as a file-like object. Here’s an example:

Code

import subprocess

output = subprocess.check_output("ls", shell=True)

print(output.decode())

In the above example, we are using the `subprocess.check_output()` function to capture the output of the `ls` command. The `shell=True` argument tells the subprocess to use the shell to execute the command. The output is returned as a byte string, which we decode and print using the `output.decode()` method.

Handling command line arguments

When executing external commands, you often need to pass command line arguments. The subprocess module allows you to pass arguments as a list of strings, where each element represents an argument. Here’s an example:

Code

import subprocess

subprocess.run(["echo", "Hello,", "World!"])

In the above example, we are passing the arguments “Hello,” and “World!” to the `echo` command. Each argument is represented as a separate element in the list.

Running commands asynchronously with subprocess.Popen()

The subprocess module also provides the `subprocess.Popen()` function, which allows you to run commands asynchronously. This means that you can start a command and continue with other tasks without waiting for the command to complete. Here’s an example:

Code

import subprocess

process = subprocess.Popen(["ping", "google.com"])

# Continue with other tasks

In the above example, we are using the `subprocess.Popen()` function to start the `ping` command to google.com. The command is started in the background, and we can continue with other tasks while it is running.

Advanced Techniques with Python Subprocess

In addition to the basic functionalities, the subprocess module provides advanced techniques for interacting with external commands. Let’s explore some of them.

Redirecting input and output streams

The subprocess module allows you to redirect the input and output streams of a command. You can redirect the input from a file or a string, and redirect the output to a file or a variable. Here’s an example:

Code

import subprocess

with open("input.txt", "r") as file:

    subprocess.run(["grep", "keyword"], stdin=file)

result = subprocess.run(["ls"], capture_output=True, text=True)

with open("output.txt", "w") as file:

    file.write(result.stdout)

In the above example, we are redirecting the input of the `grep` command from a file named “input.txt”. We are also redirecting the output of the `ls` command to a file named “output.txt”.

Setting environment variables

The subprocess module allows you to set environment variables for the command’s execution. You can pass a dictionary of environment variables to the `subprocess.run()` function using the `env` argument. Here’s an example:

Code

import subprocess

env = {"PATH": "/usr/local/bin"}

subprocess.run(["echo", "$PATH"], env=env, shell=True)

In the above example, we are setting the `PATH` environment variable to “/usr/local/bin” for the execution of the `echo` command. The `shell=True` argument tells the subprocess to use the shell to execute the command.

Handling errors and exceptions

When executing external commands, it is important to handle errors and exceptions. The subprocess module provides various ways to handle errors, such as checking the return code of the command, capturing the error output, and raising exceptions. Here’s an example:

Code

import subprocess

try:

    subprocess.run(["invalid_command"], check=True)

except subprocess.CalledProcessError as e:

    print("Command failed with return code", e.returncode)

    print("Error output:", e.stderr)

In the above example, we are running an invalid command and using the `check=True` argument to raise an exception if the command fails. We catch the `subprocess.CalledProcessError` exception and print the return code and error output.

Interacting with the command’s process

The subprocess module allows you to interact with the process of the executed command. You can send input to the process, receive output from the process, and even terminate the process if needed. Here’s an example:

Code

import subprocess

process = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

process.stdin.write(b"print('Hello, World!')")

process.stdin.close()

output = process.stdout.read()

print(output.decode())

process.terminate()

In the above example, we are starting a Python interpreter as a subprocess and sending the command `print(‘Hello, World!’)` to it. We then read the output of the process and print it. Finally, we terminate the process using the `process.terminate()` method.

Running commands in the background

The subprocess module allows you to run commands in the background, without blocking the execution of your Python script. You can use the `subprocess.Popen()` function with the `subprocess.DEVNULL` constant to redirect the input and output streams to null. Here’s an example:

Code

import subprocess

subprocess.Popen(["python", "script.py"], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

In the above example, we are running a Python script named “script.py” in the background. The input, output, and error streams of the script are redirected to null, so they do not interfere with the execution of the main script.

Common Use Cases for Python Subprocess

The subprocess module is widely used in various scenarios. Let’s explore some common use cases for using the Python subprocess.

Running shell commands

Python subprocess allows you to run shell commands from within your Python script. This can be useful for automating tasks, executing system commands, and interacting with the command line. Here’s an example:

Code

import subprocess

subprocess.run("ls", shell=True)

In the above example; we are running the `ls` command to list the files and directories in the current directory.

Running system commands

Python subprocess allows you to execute system commands, such as installing packages, updating software, and managing system resources. Here’s an example:

Code

import subprocess

subprocess.run("apt-get install package", shell=True)

In the above example, we are using the `apt-get` command to install a package.

Running external scripts

The Python subprocess allows you to run external scripts, such as shell scripts, Python scripts, and other executable scripts. Here’s an example:

Code

import subprocess

subprocess.run(["python", "script.py"])

In the above example, we are running a Python script named “script.py”.

Running commands with elevated privileges

Python subprocess allows you to run commands with elevated privileges, such as running commands as an administrator or root user. Here’s an example:

Code

import subprocess

subprocess.run(["sudo", "command"])

In the above example, we are running a command with elevated privileges using the `sudo` command.

Running commands with user input

Python subprocess allows you to run commands that require user input, such as interactive programs and command line prompts. Here’s an example:

Code

import subprocess

subprocess.run(["python", "-i"])

In the above example, we are running the Python interpreter in interactive mode, which allows user input.

Best Practices and Tips for Using Python subprocess

When using Python subprocess, it is important to follow best practices and consider certain factors. Here are some tips for using Python subprocess effectively.

Ensuring command security and sanitization

When executing external commands, it is important to ensure command security and sanitization. Always validate and sanitize user input before passing it to subprocess functions to prevent command injection attacks.

Handling different operating systems

Python subprocess works differently on different operating systems. Take into account the differences in command syntax, environment variables, and system commands when writing cross-platform code.

Managing Subprocesses in complex applications

In complex applications, managing subprocesses can be challenging. Consider using higher-level libraries and frameworks, such as Celery or asyncio, to manage subprocesses efficiently.

Debugging and troubleshooting subprocess issues

When encountering issues with subprocesses, it is important to debug and troubleshoot them effectively. Use logging, error handling, and debugging techniques to identify and resolve any problems.

The Conclusion

Python subprocess is a powerful module that allows you to execute external commands from within your Python script. It provides various functionalities, including running commands, capturing output, handling errors, and interacting with the command’s process. By following best practices and considering various factors, you can use Python subprocess effectively in your projects.

Ready to supercharge your AI & ML journey? Join our Certified AI & ML BlackBelt Plus Program today! Gain a competitive edge with personalized learning paths, 1:1 mentorship, and hands-on guided projects. Power ahead in your AI & ML career! Enroll now for on-demand doubt-clearing sessions and embark on the path to becoming an AI & ML expert with Python. Don’t miss out – the future of tech awaits you!

Pankaj Singh 10 Jan 2024

Frequently Asked Questions

Lorem ipsum dolor sit amet, consectetur adipiscing elit,

Responses From Readers

Clear