Os popen python windows

Welcome to Python Run Shell Command On Windows tutorial. In this tutorial, you will learn, how to run shell command in python. So let’s move forward.

What is Shell ?

  • In computer science shell is generally seen as a piece of software that provides an interface for a user to some other software or the operating system.
  • So the shell can be an interface between the operating system and the services of the kernel of this operating system

Python Modules For Running Shell command

Python provides lots of modules for executing different operations related to operating system.

Generally there are two important modules which are used to run shell command in python.

  • Subprocess module
  • OS module

Python Run Shell Command Using Subprocess module

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:

  • os.system
  • os.spawn*
  • os.popen*
  • popen2.*
  • commands.*

The subprocess module allows users to communicate from their Python script to a terminal like bash or cmd.exe.

Now we will see different functions of subprocess module.

subprocess.call()

call() method create a separate process and run provided command in this process. 

Write the following code to implement call() method of subprocess module.

import subprocess

subprocess.call(‘dir’, shell=True)

In this example, we will create a process for dir command

It’s output will be as follows.

Python Run Shell Command On Windows

Python Run Shell Command On Windows

subprocess.check_output()

check_output()is used to capture the output for later processing. So let’s see how it works.

import subprocess

output = subprocess.check_output(‘dir’, shell=True)

print(output)

Output

Python Run Shell Command On Windows

Python Run Shell Command On Windows

Python Run Shell Command Using OS module

The OS module is used to interact with underlying operating system in several different ways.

OS is an python built-in module so we don’t need to install any third party module. The os module allows platform independent programming by providing abstract methods.

Executing Shell scripts with os.system()

The  most straight forward approach to run a shell command is by using os.system().

import os

os.system(‘dir’)

Python Run Shell Command On Windows

Python Run Shell Command On Windows

Capturing Output

The problem with this approach is in its inflexibility since you can’t even get the resulting output as a variable. os.system() doesn’t return the result of the called shell commands. So if you want to capture output then you have to use os.popen() method.

The os.popen() command opens a pipe from or to the command line. This means that we can access the stream within Python. This is useful since you can now get the output as a variable. Now let’s see it practically, so write the following code.

import os

output = os.popen(‘dir’).readlines()

print(output)

  •  Here i used readlines() function, which splits each line (including a trailing \n).
  • You can also use read() method which will get the whole output as one string.

Now it’s output will be as follows.

Python Run Shell Command On Windows

So guys, that’s it for Python Run Shell Command On Windows tutorial. I hope it is helpful for you and if you have any query regarding this post then ask your questions in comment section. Thanks Everyone.

Related Articles :

  • How To Add Code To GitHub Using PyCharm
  • Sets In Python Tutorial For Beginners
  • Join Two Lists Python – Learn Joining Two Lists With Examples

The os.popen function in Python’s os module opens a pipe to or from a command. The returned file object can be read from or written to, depending on whether the mode is 'r' (default) or 'w'.

Table of Contents

  1. Introduction
  2. os.popen Function Syntax
  3. Examples
    • Basic Usage
    • Reading Command Output
    • Writing to a Command
  4. Real-World Use Case
  5. Conclusion

Introduction

The os.popen function in Python’s os module allows you to open a pipe to or from a command. This function is useful for capturing the output of a shell command or providing input to a command from within a Python script.

os.popen Function Syntax

Here is how you use the os.popen function:

import os

file_object = os.popen(command, mode='r', buffering=-1)

Parameters:

  • command: A string representing the command to be executed.
  • mode: Mode in which the file is opened. 'r' for reading (default), 'w' for writing.
  • buffering: Buffering policy. -1 means the default buffering policy.

Returns:

  • A file object that can be read from or written to, depending on the mode.

Examples

Basic Usage

Here is an example of how to use the os.popen function to open a pipe to a command and read its output.

Example

import os

# Running a command and reading its output
command = 'echo Hello, World!'
file_object = os.popen(command)
output = file_object.read()
file_object.close()
print(f"Command output: {output}")

Output:

Command output: Hello, World!

Reading Command Output

This example demonstrates how to read the output of a command line by line.

Example

import os

# Running a command and reading its output line by line
command = 'ls -l /home/user'
file_object = os.popen(command)
for line in file_object:
    print(line, end='')
file_object.close()

Output:

(total list of files and directories in /home/user with details)

Writing to a Command

This example demonstrates how to provide input to a command using os.popen with write mode.

Example

import os

# Writing input to a command
command = 'cat > /tmp/testfile.txt'
file_object = os.popen(command, 'w')
file_object.write('This is a test.\nThis is another test.')
file_object.close()

# Verifying the content of the file
with open('/tmp/testfile.txt', 'r') as file:
    content = file.read()
    print(content)

Output:

This is a test.
This is another test.

Real-World Use Case

Running Shell Commands and Capturing Output

In real-world applications, the os.popen function can be used to run shell commands and capture their output for processing or logging purposes.

Example

import os

def run_command(command):
    with os.popen(command) as file_object:
        output = file_object.read()
    return output

# Example usage
command = 'df -h'
output = run_command(command)
print(f"Disk usage information:\n{output}")

Output:

Disk usage information:
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   20G   28G  42% /
...

Conclusion

The os.popen function in Python’s os module opens a pipe to or from a command, allowing you to read from or write to the command’s input or output. This function is useful for capturing the output of shell commands or providing input to commands from within a Python script. While os.popen is useful for simple tasks, consider using the subprocess module for more complex scenarios, as it provides more powerful and flexible tools for running and managing subprocesses. Proper usage of these functions can enhance the automation and integration capabilities of your Python scripts.

Introduction

The os.popen() function is a powerful tool in Python that allows you to execute system commands and capture their output. It creates a pipe between your Python program and the command being executed.

Basic Syntax

Here’s the basic syntax for using os.popen():


import os
file_object = os.popen(command)

Simple Example

Let’s look at a basic example of running a system command:


import os

# Execute 'dir' command (Windows) or 'ls' command (Unix)
output = os.popen('dir' if os.name == 'nt' else 'ls').read()
print(output)

Reading Command Output

There are several ways to read the output of a command:


import os

# Method 1: Read all output at once
output = os.popen('echo "Hello World"').read()

# Method 2: Read line by line
command = os.popen('echo "Line 1\nLine 2"')
for line in command:
    print(line.strip())

# Method 3: Read specific number of bytes
command = os.popen('echo "Test"')
print(command.read(2))  # Reads first 2 bytes

Common Use Cases

Here are some practical examples of using os.popen():


import os

# Get system information
system_info = os.popen('systeminfo' if os.name == 'nt' else 'uname -a').read()

# List running processes
processes = os.popen('tasklist' if os.name == 'nt' else 'ps aux').read()

# Get IP configuration
network_info = os.popen('ipconfig' if os.name == 'nt' else 'ifconfig').read()

Error Handling

It’s important to implement proper error handling when using os.popen():


import os

try:
    command = os.popen('invalid_command')
    output = command.read()
    exit_status = command.close()
    
    if exit_status is not None:
        print(f"Command failed with status: {exit_status}")
    else:
        print("Command succeeded")
except Exception as e:
    print(f"Error occurred: {str(e)}")

Best Practices

  • Always close the file object after use with close()
  • Validate command output before processing
  • Consider using subprocess module for more complex operations
  • Be cautious with user input to prevent command injection

Security Considerations

Never use os.popen() with untrusted input:


# Bad practice - vulnerable to command injection
user_input = input("Enter filename: ")
os.popen(f"type {user_input}")  # Windows
os.popen(f"cat {user_input}")   # Unix

# Good practice - use safe alternatives
with open(user_input, 'r') as file:
    content = file.read()

Related Articles

  • How to Use os.mkdir in Python
  • Python: Using os.listdir to List Files in a Directory

Conclusion

os.popen() is a useful tool for executing system commands in Python, but it should be used with caution. For modern applications, consider using the subprocess module which offers more features and better security. Always validate input and handle errors appropriately when working with system commands.

Introduction

Python offers several options to run external processes and interact with the operating system. However, the methods are different for Python 2 and 3. Python 2 has several methods in the os module, which are now deprecated and replaced by the subprocess module, which is the preferred option in Python 3.

Throughout this article we’ll talk about the various os and subprocess methods, how to use them, how they’re different from each other, on what version of Python they should be used, and even how to convert the older commands to the newer ones.

Hopefully by the end of this article you’ll have a better understanding of how to call external commands from Python code and which method you should use to do it.

First up is the older os.popen* methods.

The os.popen* Methods

The os module offers four different methods that allows us to interact with the operating system (just like you would with the command line) and create a pipe to other commands. These methods I’m referring to are: popen, popen2, popen3, and popen4, all of which are described in the following sections.

The goal of each of these methods is to be able to call other programs from your Python code. This could be calling another executable, like your own compiled C++ program, or a shell command like ls or mkdir.

os.popen

The os.popen method opens a pipe from a command. This pipe allows the command to send its output to another command. The output is an open file that can be accessed by other programs.

The syntax is as follows:

os.popen(command[, mode[, bufsize]])

Here the command parameter is what you’ll be executing, and its output will be available via an open file. The argument mode defines whether or not this output file is readable (‘r’) or writable (‘w’). Appending a ‘b’ to the mode will open the file in binary mode. Thus, for example «rb» will produce a readable binary file object.

In order to retrieve the exit code of the command executed, you must use the close() method of the file object.

The bufsize parameter tells popen how much data to buffer, and can assume one of the following values:

  • 0 = unbuffered (default value)
  • 1 = line buffered
  • N = approximate buffer size, when N > 0; and default value, when N < 0

This method is available for Unix and Windows platforms, and has been deprecated since Python version 2.6. If you’re currently using this method and want to switch to the Python 3 version, here is the equivalent subprocess version for Python 3:

Method Replaced by
pipe = os.popen(‘cmd’, ‘r’, bufsize) pipe = Popen(‘cmd’, shell=True, bufsize=bufsize, stdout=PIPE).stdout
pipe = os.popen(‘cmd’, ‘w’, bufsize) pipe = Popen(‘cmd’, shell=True, bufsize=bufsize, stdin=PIPE).stdin

The code below shows an example of how to use the os.popen method:

import os

p = os.popen('ls -la')
print(p.read())

The code above will ask the operating system to list all files in the current directory. The output of our method, which is stored in p, is an open file, which is read and printed in the last line of the code. The of this code (in the context of my current directory) result is as follows:

$ python popen_test.py 
total 32
drwxr-xr-x   7 scott  staff  238 Nov  9 09:13 .
drwxr-xr-x  29 scott  staff  986 Nov  9 09:08 ..
-rw-r--r--   1 scott  staff   52 Nov  9 09:13 popen2_test.py
-rw-r--r--   1 scott  staff   55 Nov  9 09:14 popen3_test.py
-rw-r--r--   1 scott  staff   53 Nov  9 09:14 popen4_test.py
-rw-r--r--   1 scott  staff   49 Nov  9 09:13 popen_test.py
-rw-r--r--   1 scott  staff    0 Nov  9 09:13 subprocess_popen_test.py

os.popen2

This method is very similar to the previous one. The main difference is what the method outputs. In this case it returns two file objects, one for the stdin and another file for the stdout.

The syntax is as follows:

popen2(cmd[, mode[, bufsize]])

These arguments have the same meaning as in the previous method, os.popen.

The popen2 method is available for both the Unix and Windows platforms. However, it is found only in Python 2. Again, if you want to use the subprocess version instead (shown in more detail below), use the following instead:

Method Replaced by
(child_stdin, child_stdout) = os.popen2(‘cmd’, mode, bufsize) p = Popen(‘cmd’, shell=True, bufsize=bufsize, stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)

The code below shows an example on how to use this method:

import os

in, out = os.popen2('ls -la')
print(out.read())

This code will produce the same results as shown in the first code output above. The difference here is that the output of the popen2 method consists of two files. Thus, the 2nd line of code defines two variables: in and out. In the last line, we read the output file out and print it to the console.

os.popen3

This method is very similar to the previous ones. However, the difference is that the output of the command is a set of three files: stdin, stdout, and stderr.

The syntax is:

os.popen3(cmd[, mode[, bufsize]])

where the arguments cmd, mode, and bufsize have the same specifications as in the previous methods. The method is available for Unix and Windows platforms.

Note that this method has been deprecated and the Python documentation advises us to replace the popen3 method as follows:

Method Replaced by
(child_stdin,
child_stdout,
child_stderr) = os.popen3(‘cmd’, mode, bufsize)
p = Popen(‘cmd’, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
child_stdout,
child_stderr) = (p.stdin, p.stdout, p.stderr)

As in the previous examples, the code below will produce the same result as seen in our first example.

import os

in, out, err = os.popen3('ls -la')
print(out.read())

However, in this case, we have to define three files: stdin, stdout, and stderr. The list of files from our ls -la command is saved in the out file.

os.popen4

As you probably guessed, the os.popen4 method is similar to the previous methods. However, in this case, it returns only two files, one for the stdin, and another one for the stdout and the stderr.

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

This method is available for the Unix and Windows platforms and (surprise!) has also been deprecated since version 2.6. To replace it with the corresponding subprocess Popen call, do the following:

Method Replaced by
(child_stdin, child_stdout_and_stderr) = os.popen4(‘cmd’, mode, bufsize) p = Popen(‘cmd’, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

The following code will produce the same result as in the previous examples, which is shown in the first code output above.

import os

in, out = os.popen4('ls -la')
print(we.read())

As we can see from the code above, the method looks very similar to popen2. However, the out file in the program will show the combined results of both the stdout and the stderr streams.

Summary of differences

The differences between the different popen* commands all have to do with their output, which is summarized in the table below:

Method Arguments
popen stdout
popen2 stdin, stdout
popen3 stdin, stdout, stderr
popen4 stdin, stdout and stderr

In addition the popen2, popen3, and popen4 are only available in Python 2 but not in Python 3. Python 3 has available the popen method, but it is recommended to use the subprocess module instead, which we’ll describe in more detail in the following section.

The susbprocess.Popen Method

The subprocess module was created with the intention of replacing several methods available in the os module, which were not considered to be very efficient. Within this module, we find the new Popen class.

The Python documentation recommends the use of Popen in advanced cases, when other methods such like subprocess.call cannot fulfill our needs. This method allows for the execution of a program as a child process. Because this is executed by the operating system as a separate process, the results are platform dependent.

The available parameters are as follows:

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

One main difference of Popen is that it is a class and not just a method. Thus, when we call subprocess.Popen, we’re actually calling the constructor of the class Popen.

There are quite a few arguments in the constructor. The most important to understand is args, which contains the command for the process we want to run. It can be specified as a sequence of parameters (via an array) or as a single command string.

The second argument that is important to understand is shell, which is defaults to False. On Unix, when we need to run a command that belongs to the shell, like ls -la, we need to set shell=True.

For example, the following code will call the Unix command ls -la via a shell.

import subprocess
subprocess.Popen('ls -la', shell=True)

The results can be seen in the output below:

$ python subprocess_popen_test.py 
total 40
drwxr-xr-x   7 scott  staff  238 Nov  9 09:13 .
drwxr-xr-x  29 scott  staff  986 Nov  9 09:08 ..
-rw-r--r--   1 scott  staff   52 Nov  9 09:13 popen2_test.py
-rw-r--r--   1 scott  staff   55 Nov  9 09:14 popen3_test.py
-rw-r--r--   1 scott  staff   53 Nov  9 09:14 popen4_test.py
-rw-r--r--   1 scott  staff   49 Nov  9 09:13 popen_test.py
-rw-r--r--   1 scott  staff   56 Nov  9 09:16 subprocess_popen_test.py

Using the following example from a Windows machine, we can see the differences of using the shell parameter more easily. Here we’re opening Microsoft Excel from the shell, or as an executable program. From the shell, it is just like if we were opening Excel from a command window.

The following code will open Excel from the shell (note that we have to specify shell=True):

import subprocess
subprocess.Popen("start excel", shell=True)

However, we can get the same results by calling the Excel executable. In this case we are not using the shell, so we leave it with its default value (False); but we have to specify the full path to the executable.

import subprocess
subprocess.Popen("C:\Program Files (x86)\Microsoft Office\Office15\excel.exe")

In addition, when we instantiate the Popen class, we have access to several useful methods:

Method Description
Popen.poll() Checks if the child process has terminated.
Popen.wait() Wait for the child process to terminate.
Popen.communicate() Allows to interact with the process.
Popen.send_signal() Sends a signal to the child process.
Popen.terminate() Stops the child process.
Popen.kill() Kills a child process.

The full list can be found at the subprocess documentation. The most commonly used method here is communicate.

The communicate method allows us to read data from the standard input, and it also allows us to send data to the standard output. It returns a tuple defined as (stdoutdata, stderrdata).

For example, the following code will combine the Windows dir and sort commands.

import subprocess

p1 = subprocess.Popen('dir', shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p2 = subprocess.Popen('sort /R', shell=True, stdin=p1.stdout)

p1.stdout.close()
out, err = p2.communicate() 

In order to combine both commands, we create two subprocesses, one for the dir command and another for the sort command. Since we want to sort in reverse order, we add /R option to the sort call.

We define the stdout of process 1 as PIPE, which allows us to use the output of process 1 as the input for process 2. Then we need to close the stdout of process 1, so it can be used as input by process 2. The communication between process is achieved via the communicate method.

Running this from a Windows command shell produces the following:

> python subprocess_pipe_test.py
11/09/2017  08:52 PM                  234 subprocess_pipe_test.py
11/09/2017  07:13 PM                   99 subprocess_pipe_test2.py
11/09/2017  07:08 PM                   66 subprocess_pipe_test3.py
11/09/2017  07:01 PM                   56 subprocess_pipe_test4.py
11/09/2017  06:48 PM     <DIR>            ..
11/09/2017  06:48 PM     <DIR>            .
 Volume Serial Number is 2E4E-56A3
 Volume in drive D is ECA
 Directory of D:\MyPopen
               4 File(s)            455 bytes
               2 Dir(s)  18,634,326,016 bytes free

Wrapping up

The os methods presented a good option in the past, however, at present the subprocess module has several methods which are more powerful and efficient to use. Among the tools available is the Popen class, which can be used in more complex cases. This class also contains the communicate method, which helps us pipe together different commands for more complex functionality.

What do you use the popen* methods for, and which do you prefer? Let us know in the comments!

Knowing how to execute a shell command in Python helps you create programs to automate tasks on your system.

There are multiple ways to execute a shell command in Python. The simplest ones use the os.system and os.popen functions. The recommended module to run shell commands is the Python subprocess module due to its flexibility in giving you access to standard output, standard error and command piping.

We will start this tutorial with the os module and then we will move to the subprocess module.

This will give you a full understanding of how to handle shell commands in Python.

Let’s start coding!

Using OS System to Run a Command in Python

I have created a simple Python script called shell_command.py.

It uses the system function of the os module to run the Linux date command:

import os

os.system('date')

This is the output of the os.system() function:

$ python shell_command.py
Sun Feb 21 16:01:43 GMT 2021

Let’s see what happens when we run the same code in the Python shell:

>>> import os
>>> os.system('date')
Sun Feb 21 16:01:43 GMT 2021
0               

We still see the output of the date command but we also see a 0 in the last line. That’s the exit code of the Linux command.

A successful command in Linux returns a 0 exit code and a non-zero exit code is returned in case of failure.

Let’s confirm that, by introducing a spelling mistake in the date command:

>>> os.system('daet')
>>> sh: daet: command not found
>>> 32512         

Notice how the exit status is different from the one returned by the Bash shell:

$ daet
-bash: daet: command not found
$ echo $?
127

I have written another article that explains Bash exit codes if it’s something you would like to know more about.

Later on in this article we will make a comparison between os.system and a different Python module called subprocess.

Using OS Popen to Execute Commands

Using os.system() we cannot store the output of the Linux command into a variable. And this is one of the most useful things to do when you write a script.

You usually run commands, store their output in a variable and then implement some logic in your script that does whatever you need to do with that variable (e.g. filter it based on certain criteria).

To be able to store the output of a command in a variable you can use the os.popen() function.

The popen function returns an open file object and to read its value you can use the read method:

>>> import os
>>> output = os.popen('date')
>>> type(output)
<class 'os._wrap_close'>
>>> print(output.__dict__)
{'_stream': <_io.TextIOWrapper name=3 encoding='UTF-8'>, '_proc': }         
>>> output.read()
'Sun Feb 21 16:01:43 GMT 2021\n'         

Have a look at what happens if we use the read method again on the same object:

>>> output.read()
''                

The result is an empty string because we can only read from the file object once.

We can use os.popen and the read function in a single line:

>>> import os
>>> print(os.popen('date').read())
Sun Feb 21 16:01:43 GMT 2021

When executing shell commands in Python it’s important to understand if a command is executed successfully or not.

To do that we can use the close method of the file object returned by os.popen. The close method returns None if the command is executed successfully. It provides the return code of the subprocess in case of error.

Success scenario

>>> output = os.popen('date')
>>> print(output.close())
None         

Failure scenario

>>> output = os.popen('daet')
>>> /bin/sh: daet: command not found

>>> print(output.close())
32512         

We can use the value of output.close() for error handling in our Python scripts.

Makes sense?

Do OS System and OS Popen Wait for Command Completion?

Before moving to a different way of running shell commands in Python, I want to see the behaviour of os.system() and os.popen() with a command that takes few seconds to complete.

We will use the ping command with the -c flag to stop the execution of the command after a specific number of ECHO_RESPONSE packets (in this example 5):

$ ping -c 5 localhost

Execution with os.system

>>> os.system('ping -c 5 localhost')
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.051 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.091 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.066 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.063 ms

--- localhost ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.051/0.068/0.091/0.013 ms
0     

When executing the command with os.system() we see the output for each ping attempt being printed one at the time, in the same way we would see it in the Linux shell.

Execution with os.popen

>>> os.popen('ping -c 5 localhost')
<os._wrap_close object at 0x10bc8a190> 
>>> os.popen('ping -c 5 localhost').read()
'PING localhost (127.0.0.1): 56 data bytes\n64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.055 ms\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.059 ms\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.073 ms\n64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.135 ms\n64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.077 ms\n\n--- localhost ping statistics ---\n5 packets transmitted, 5 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 0.055/0.080/0.135/0.029 ms\n'         

When using os.popen() we don’t see the output in the Python shell immediately.

The output gets buffered, we only see the final output once the ping command is complete.

The os.popen function waits for the completion of a command before providing the full output.

Very soon we will look at the difference between the Popen function of the OS module and the Popen function of the subprocess module.

Read, Readline and Readlines Methods Applied to the OS.Popen Output

We have seen that:

  • os.popen() returns an open file object.
  • we can read the content of the object using the read() method.

In this section we will compare the behavior of the read(), readline() and readlines() methods applied to the file object returned by os.popen.

We know already that the read method returns the output of the command as soon as the command execution is complete.

Let’s see what happens with the readline method:

>>> output = os.popen('ping -c 5 localhost')
>>> output.readline()
'PING localhost (127.0.0.1): 56 data bytes\n'
>>> output.readline()
'64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.047 ms\n'
>>> output.readline()
'64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.067 ms\n'
>>> output.readline()
'64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.055 ms\n'
>>> output.readline()
'64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.103 ms\n'
>>> output.readline()
'64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.058 ms\n'
>>> output.readline()
'\n'
>>> output.readline()
'--- localhost ping statistics ---\n'
>>> output.readline()
'5 packets transmitted, 5 packets received, 0.0% packet loss\n'
>>> output.readline()
'round-trip min/avg/max/stddev = 0.047/0.066/0.103/0.020 ms\n'
>>> output.readline()
''
>>> output.readline()
''         

With the readline method we can print the output of the command one line at the time until we reach the end of the open file object.

Here is how you can use the readline method with a while loop, to print the full output of the command:

import os

output = os.popen('ping -c 5 localhost')

while True:
    line = output.readline()
 
    if line:
        print(line, end='')
    else:
        break

 output.close()

On the other side, the readlines method waits for the command to complete and it returns a Python list:

>>> output = os.popen('ping -c 5 localhost')
>>> output.readlines()
['PING localhost (127.0.0.1): 56 data bytes\n', '64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.044 ms\n', '64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.095 ms\n', '64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.057 ms\n', '64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.078 ms\n', '64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.094 ms\n', '\n', '--- localhost ping statistics ---\n', '5 packets transmitted, 5 packets received, 0.0% packet loss\n', 'round-trip min/avg/max/stddev = 0.044/0.074/0.095/0.020 ms\n']         

And with a simple for loop we can print the full output of the command by going through all the elements in the list returned by the readlines() method:

import os

output = os.popen('ping -c 5 localhost')

for line in output.readlines():
    print(line, end='')

All clear? 🙂

Run Shell Commands in Python with Subprocess.Run

In the previous section we have seen how to run the date command using os.system and os.popen.

Now, you will learn how to use the subprocess module to run the same command.

There are few options to run commands using subprocess and I will start with the recommended one if you are using Python 3.5 or later: subprocess.run.

Let’s pass the date command to subprocess.run():

>>> import subprocess
>>> subprocess.run('date')
Sun Feb 21 21:44:53 GMT 2021
CompletedProcess(args='date', returncode=0) 

As you can see, the command returns an object of type CompletedProcess (it’s actually subprocess.CompletedProcess).

Let’s see what happens if I also pass the +%a flag to the date command (it should show the day of the week):

import subprocess
   
subprocess.run('date +%a') 

We see the following error:

$ python subprocess_example.py 
Traceback (most recent call last):
  File "subprocess_example.py", line 3, in <module>
    subprocess.run('date +%a')
  File "/Users/codefather/opt/anaconda3/lib/python3.7/subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/Users/codefather/opt/anaconda3/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/Users/codefather/opt/anaconda3/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'date +%a': 'date +%a' 

One way to make this command work is by passing the shell=True parameter to subprocess.run():

import subprocess
   
subprocess.run('date +%a', shell=True) 

Give it a try and confirm that the command works as epxected.

Passing the parameter shell=True the command gets invoked through the shell.

Note: Be aware of security considerations related to the use of the shell parameter.

When you execute the command, the run() function waits for the command to complete. I will explain you more about this in one of the next sections.

If we want to run the “date +%a” command without passing shell=True we have to pass date and its flags as separate elements of an array.

import subprocess
   
subprocess.run(['date', '+%a'])

[output]
Sun
CompletedProcess(args=['date', '+%a'], returncode=0) 

Capture the Command Output with Subprocess.run

So far we have printed the output of the command in the shell.

But, what if we want to store the output of the command in a variable?

Could we simply add a variable to the left side of the subprocess.run() call?

Let’s find out…

import subprocess

process_output = subprocess.run(['date', '+%a'])
print(process_output)

[output]
Sun
CompletedProcess(args=['date', '+%a'], returncode=0)

We still see the output of the command in the shell and the print statement shows that the variable process_output is a CompletedProcess object.

Let’s find out the attributes of the object…

To see the namespace associated to this Python object we can use the __dict__ method.

print(process_output.__dict__)

[output]
{'args': ['date', '+%a'], 'returncode': 0, 'stdout': None, 'stderr': None}

You can see the attributes in which args, return code, standard output and standard error are stored.

The return code for the last command we have executed is zero. Once again. the return code for a successful command is zero.

Let’s see what the return code is if we introduce a syntax error in the command:

process_output = subprocess.run(['date', '%a'])

This is the error we see after passing an incorrect flag to the date command:

$ python subprocess_example.py 
date: illegal time format
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] …
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
{'args': ['date', '%a'], 'returncode': 1, 'stdout': None, 'stderr': None} 

The return code is 1 (non-zero return codes indicate failure).

Also, the stdout is None because the output of the command is sent to the terminal.

How can we capture the stdout in a variable?

In the official subprocess documentation I can see the following:

shell command in Python - subprocess.run

So, let’s find out what happens if we set capture_output to True…

process_output = subprocess.run(['date', '+%a'], capture_output=True)

Run this command, you will not see the output of the command printed in the shell unless you use a print statement to show the value of the variable process_output:

>>> import subprocess
>>> process_output = subprocess.run(['date', '+%a'], capture_output=True)
>>> print(process_output)
CompletedProcess(args=['date', '+%a'], returncode=0, stdout=b'Sun\n', stderr=b'')

This time you can see that the value of stdout and stderr is not None anymore:

  • The standard output contains the output of the command.
  • The standard error is an empty string because the date command has been executed successfully.

Let’s also confirm that stderr is not empty in case of error:

>>> import subprocess
>>> process_output = subprocess.run(['date', '%a'], capture_output=True)
>>> print(process_output)
CompletedProcess(args=['date', '%a'], returncode=1, stdout=b'', stderr=b'date: illegal time format\nusage: date [-jnRu] [-d dst] [-r seconds] [-t west] [ v[+|-]val[ymwdHMS]] ... \n            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]\n') 

The error is stored in process_output.stderr.

The Format of Standard Output and Standard Error of a Command

In the last command we have seen that stdout and stderr have a format that is not very readable.

That’s because they are both captured as bytes (notice all the new line characters in the values of stdout and stderr).

What if we want to see them in the same format of the output of a command in the shell?

We can pass the additional parameter text to the subprocess.run method:

>>> import subprocess
>>> process_output = subprocess.run(['date', '+%a'], capture_output=True, text=True)
>>> print(process_output.stdout)
Sun
 

Note: the text parameter was introduced in Python 3.7 as a more understandable alternative to the parameter universal_newlines.

As an alternative you can also convert the bytes into a string using the decode method:

>>> import subprocess
>>> process_output = subprocess.run(['date', '+%a'], capture_output=True)
>>> print(process_output.stdout)
b'Sun\n' 
>>> print(process_output.stdout.decode())
Sun

Do you see the difference in the format of the stdout with and without decode?

Before, in the definition of the capture_output parameter we have seen that passing it, it’s the same as passing stdout=PIPE and stderr=PIPE.

Let’s try to use those instead to confirm the output is the same…

>>> import subprocess
>>> process_output = subprocess.run(['date', '+%a'], stdout=PIPE, stderr=PIPE, text=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'PIPE' is not defined

We have got the error “name ‘PIPE’ is not defined“. Why?

As you can see from the definition below, coming from the official subprocess documentation, PIPE is part of the subprocess module. This mean we have to use subprocess.PIPE in our program.

shell command in Python - subprocess.pipe

>>> import subprocess
>>> process_output = subprocess.run(['date', '+%a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
>>> print(process_output.stdout)
Sun
 

Looks better now 🙂

How to Capture Standard Output and Standard Error in One Single Stream

To capture standard output and standard error in a single stream we have to set stdout to subprocess.PIPE and stderr to subprocess.STDOUT:

>>> process_output = subprocess.run(['date', '+%a'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)

The output is:

>> print(process_output.__dict__)
{'args': ['date', '+%a'], 'returncode': 0, 'stdout': 'Sun\n', 'stderr': None}         

The stdout contains the output and the value of the stderr is None.

And, what if there is an error in the execution of the command?

>>> process_output = subprocess.run(['date', '%a'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
>>> print(process_output.__dict__)
{'args': ['date', '%a'], 'returncode': 1, 'stdout': 'date: illegal time format\nusage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] … \n            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]\n', 'stderr': None}         

As expected the error is part of the stdout stream. The value of the stderr attribute is still None.

Writing the Output of a Command to a File in Python

You can also write the output of a command to a file.

Let’s see how using the Python with statement

with open('command.out', 'w') as stdout_file:
    process_output = subprocess.run(['date', '+%a'], stdout=stdout_file, stderr=subprocess.PIPE, text=True)
    print(process_output.__dict__)

Notice how this time the value of stdout is None considering that we are sending the stdout to a file.

$ python subprocess_example.py 
{'args': ['date', '+%a'], 'returncode': 0, 'stdout': None, 'stderr': ''}
$ ls -ltr
total 16
-rw-r--r--  1 myuser  mygroup  208 Feb 21 23:45 subprocess_example.py
-rw-r--r--  1 myuser  mygroup    4 Feb 21 23:46 command.out
$ cat command.out
Sun

Using the ls and cat commands we confirm that the command.out file has been created and that it contains the output of the command executed in our Python program.

What about writing also the standard error to a file?

To do that we can open two files using the Python with statement.

with open('command.out', 'w') as stdout_file, open('command.err', 'w') as stderr_file:
    process_output = subprocess.run(['date', '+%a'], stdout=stdout_file, stderr=stderr_file, text=True)
    print(process_output.__dict__)

This time both stdout and stderr are set to None and the two files gets created when we invoke the command (the command.err file is empty because the command is executed successfully).

$ python subprocess_example.py
{'args': ['date', '+%a'], 'returncode': 0, 'stdout': None, 'stderr': None}
$ ls -ltr
total 16
-rw-r--r--  1 myuser  mygroup  245 Feb 21 23:53 subprocess_example.py
-rw-r--r--  1 myuser  mygroup    0 Feb 21 23:55 command.err
-rw-r--r--  1 myuser  mygroup    4 Feb 21 23:55 command.out

Before continuing try to exeucte a command with an incorrect syntax and confirm that the error is written to the command.err file.

Redirect Command Output to /dev/null

You might have the requirement to redirect the command output to /dev/null.

To do that we can use a special value provided by the subprocess module: DEVNULL.

process_output = subprocess.run(['date', '%a'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, text=True)
print(process_output)

The object returned by subprocess.run doesn’t include the stdout and stderr attributes:

$ python subprocess_example.py
CompletedProcess(args=['date', '%a'], returncode=1)

How to Throw a Python Exception when a Shell Command Fails

In one of the previous examples we have seen what happens if we run a command with incorrect syntax:

>>> process_output = subprocess.run(['date', '%a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

The error gets stored in the stderr stream but Python doesn’t raise any exceptions.

To be able to catch these errors we can pass the parameter check=True to subprocess.run.

>>> process_output = subprocess.run(['date', '%a'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=True)
Traceback (most recent call last):
  File "", line 1, in 
  File "/Users/codefather/opt/anaconda3/lib/python3.7/subprocess.py", line 487, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['date', '%a']' returned non-zero exit status 1.         

Python raises a subprocess.CalledProcessError exception that we can catch as part of a try and except block.

import subprocess

try:
    process_output = subprocess.run(['date', '%a'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=True)
except subprocess.CalledProcessError:
    print("Error detected while executing the command")

Now we can handle errors in a better way:

$ python subprocess_example.py
Error detected while executing the command

Nice one 🙂

How to Run Multiple Commands with Subprocess

It’s very common in Linux to use the pipe to send the output of a command as input of another command.

We will see how it’s possible to do the same in Python with subprocess.

We will execute the first command in the same way we have done before and then execute a second command that receives the additional paramer input.

The value of input will be set to the stdout of the first command.

It’s easier to show it with an example…

I have created a file that has six lines:

$ cat test_file
line1
line2
line3
line4
line5
line6

And I want to run the following command in Python:

$ wc -l test_file | awk '{print $1}'
6

We will have to take the output of the wc command and pass it as input of the awk command.

import subprocess

wc_cmd = subprocess.run(['wc', '-l', 'test_file'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("wc_cmd object: {}".format(wc_cmd.__dict__))

awk_cmd = subprocess.run(['awk', '{print $1}'], input=wc_cmd.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("awk_cmd object: {}".format(awk_cmd.__dict__))

print("The ouput of the command is: {}".format(awk_cmd.stdout.decode()))

You can see the two commands executed using subprocess.run.

We are also passing the input parameter to the second command (awk) execution and its value is set to the stdout of the first command (wc).

The final output is:

$ python subprocess_example.py
wc_cmd object: {'args': ['wc', '-l', 'test_file'], 'returncode': 0, 'stdout': b'       6 test_file\n', 'stderr': b''}
awk_cmd object: {'args': ['awk', '{print $1}'], 'returncode': 0, 'stdout': b'6\n', 'stderr': b''}
The ouput of the command is: 6

We could also execute the command with a single subprocess.run call passing shell=True:

>>> import subprocess
>>> wc_awk_cmd = subprocess.run("wc -l test_file | awk '{print $1}'", shell=True)
6         

Shlex.split and the Subprocess Module

So far, we have seen that to run a command using subprocess.run we have to pass a list where the first element is the command and the other elements are flags you would normally pass in the shell separated by space.

For a long command it can be tedious having to create this list manually. A solution for this is the shlex module, specifically the split function.

Let’s take as an example the wc command we have used in the previous section:

wc -l test_file

Here is what happens when you apply shlex.split to this string:

>>> import shlex
>>> shlex.split('wc -l test_file')
['wc', '-l', 'test_file'] 

That’s exactly the format of the argument we need to pass to subprocess.run.

It’s time to run our command using shlex.split:

import subprocess, shlex
   
cmd = 'wc -l test_file'
wc_cmd = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(wc_cmd.__dict__)

[output]
{'args': ['wc', '-l', 'test_file'], 'returncode': 0, 'stdout': b'       6 test_file\n', 'stderr': b''}  

Print Shell Environment Variables in Python

You might want to use shell environment variables in your Python program.

Let’s find out how to do that…

>>> import subprocess
>>> echo_cmd = subprocess.run(['echo', '$SHELL'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> print(echo_cmd.__dict__)
{'args': ['echo', '$SHELL'], 'returncode': 0, 'stdout': b'$SHELL\n', 'stderr': b''} 

When I try to execute “echo $SHELL” using subprocess.run the stdout is simply the string $SHELL.

Our program is not resolving the value of the environment variable $SHELL. To do that we have to use os.path.expandvars(“$SHELL”).

>>> import os
>>> echo_cmd = subprocess.run(['echo', os.path.expandvars("$SHELL")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> print(echo_cmd.__dict__)
{'args': ['echo', '/bin/bash'], 'returncode': 0, 'stdout': b'/bin/bash\n', 'stderr': b''} 

Using Subprocess with SSH

You can also use subprocess to execute commands on a remote system via SSH.

Here’s how:

import subprocess, shlex
   
cmd = "ssh -i ~/.ssh/id_rsa youruser@yourhost"
ssh_cmd = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
ssh_cmd.stdin.write("date")
ssh_cmd.stdin.close()
print(ssh_cmd.stdout.read()) 

Have a look at how we use the standard input to invoke the date command via SSH.

And here is the script output:

$ python subprocess_example.py 
Mon 22 Feb 11:58:50 UTC 2021

Subprocess.run vs Subprocess.call

In versions of Python before 3.5 subprocess.run() is not present. You can use subprocess.call() instead.

Here is what the official documentation says about the call function…

shell command in Python - subprocess.call

Let’s use subprocess.call to run the ping command we have seen before in this tutorial. For a moment I’m assuming that I can run the command using subprocess.call using the same syntax as subprocess.run.

Let’s see if it’s true…

import subprocess, shlex
   
cmd = 'ping -c 5 localhost'
ping_cmd = subprocess.call(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(ping_cmd) 

But I get an error back:

$ python subprocess_example.py 
Traceback (most recent call last):
  File "subprocess_example.py", line 5, in <module>
    print(ping_cmd.__dict__)
AttributeError: 'int' object has no attribute '__dict__' 

That’s because from subprocess.call we don’t get back an object but just the integer for the return code:

>>> import subprocess, shlex
>>> cmd = 'ping -c 5 localhost'
>>> ping_cmd = subprocess.call(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> print(ping_cmd)
0 

Looking at the subprocess.call documentation I notice the following message:

Python subprocess - stdout=PIPE or stderr=PIPE

How do we retrieve the output of subprocess.call then?

The official documentation suggests that if you need to capture stdout or stderr you should use subprocess.run() instead.

Before closing this section I wanted to give a quick try to subprocess.check_call that is also present in the documentation.

But then I realised that also in this case the documentation suggests to use run().

Subprocess.run vs Subprocess.Popen

In the last section of this tutorial we will test an alternative to subprocess.run: subprocess.Popen.

The reason I want to show you this it’s because there is something quite interesting in the behaviour of subprocess.Popen.

Let’s start by running the ping command we have used for other examples before, using subprocess.run:

>>> import subprocess, shlex
>>> cmd = 'ping -c 5 localhost'
>>> ping_cmd = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> print(ping_cmd.__dict__)
{'args': ['ping', '-c', '5', 'localhost'], 'returncode': 0, 'stdout': b'PING localhost (127.0.0.1): 56 data bytes\n64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.075 ms\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.056 ms\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.158 ms\n64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.065 ms\n64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.074 ms\n\n--- localhost ping statistics ---\n5 packets transmitted, 5 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 0.056/0.086/0.158/0.037 ms\n', 'stderr': b''} 

Subprocess.run waits for the command to complete when you press ENTER to execute the line calling subprocess.run in the Python shell (I suggest to run this on your machine to see this behaviour).

Now, let’s run the same command using subprocess.Popen…

>>> ping_cmd = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> print(ping_cmd.__dict__)
{'_waitpid_lock': <unlocked _thread.lock object at 0x102e60f30>, '_input': None, '_communication_started': False, 'args': ['ping', '-c', '5', 'localhost'], 'stdin': None, 'stdout': <_io.BufferedReader name=3>, 'stderr': <_io.BufferedReader name=5>, 'pid': 35340, 'returncode': None, 'encoding': None, 'errors': None, 'text_mode': None, '_sigint_wait_secs': 0.25, '_closed_child_pipe_fds': True, '_child_created': True} 

Subprocess.Popen returns immediately when you press ENTER in the Python shell. Also the object returned is very different from the subprocess.run one.

To get standard output and standard error we have to use the communicate() function that returns a tuple in which the first element is the stdout and the second element is the stderr.

>>> stdout, stderr = ping_cmd.communicate()
>>> print(stdout)
b'PING localhost (127.0.0.1): 56 data bytes\n64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.060 ms\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.061 ms\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.059 ms\n64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.103 ms\n64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.119 ms\n\n--- localhost ping statistics ---\n5 packets transmitted, 5 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 0.059/0.080/0.119/0.025 ms\n'
>>> print(stderr)
b'' 

Let’s go back to the fact that subprocess.Popen was executed immediately (in a non-blocking way) in the Python shell even if the ping command did not complete immediately.

With subprocess.Popen we can poll the status of a long running command, here’s how:

import subprocess, shlex, time
   
cmd = 'ping -c 5 localhost'
ping_cmd = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

while True:
    return_code = ping_cmd.poll()
    print("Return code: {}".format(return_code))

    if return_code is not None:
        break
    else:
        time.sleep(1)
        print("Command in progress...\n") 

print("Command completed with return code: {}".format(return_code))
print("Command output: {}".format(ping_cmd.stdout.read()))

The poll() function returns None while the command is executed.

We can use this to exit from the while loop only when the execution of the command is complete based on the fact that the return code is not None.

$ python subprocess_example.py 
Return code: None
Command in progress... 

Return code: None
Command in progress... 

Return code: None
Command in progress... 

Return code: None
Command in progress...

Return code: None
Command in progress... 

Return code: 0
Command completed with return code: 0
Command output: b'PING localhost (127.0.0.1): 56 data bytes\n64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.068 ms\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.066 ms\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms\n64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.095 ms\n64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.071 ms\n\n--- localhost ping statistics ---\n5 packets transmitted, 5 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 0.066/0.078/0.095/0.012 ms\n' 

Makes sense?

Conclusion

We have seen lots of different ways to execute a shell command in Python.

Well done for completing this tutorial!

The recommended way to invoke shell commands is definitely subprocess.run unless you are not using Python 3.5+. In that case you can use subprocess.Popen.

It takes practice to get used to the syntax of the subprocess module, so make sure you try the examples we have covered in this tutorial on your own machine.

Happy coding! 😀

Claudio Sabato is an IT expert with over 15 years of professional experience in Python programming, Linux Systems Administration, Bash programming, and IT Systems Design. He is a professional certified by the Linux Professional Institute.

With a Master’s degree in Computer Science, he has a strong foundation in Software Engineering and a passion for helping others become Software Engineers.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Можно ли скачивать windows 7
  • В операционной системе windows имя файла может содержать не более 8 символов
  • Windows 10 медленный отклик
  • Как включить hdr в windows 10 для игр
  • Темы для windows 7 максимальная