How To Run Shell Command And Get Output In Python

In early python version, the os modules’s system or popen function is usually used to execute operating system commands. However, recently python gradually abandon these functions officially. It recommend to use the built-in subprocess module to execute operating system-related commands. This article will tell you how to use subprocess module and os module’s system, popen function to run shell command.

1. Run Shell Command Use subprocess Module.

  1. First we should import subprocess module.
    >>> import subprocess
  2. Then we should create a child process object use subprocess module’s Popen method and assign it to a variable.
    # the child process will print it's standard output to a pipe line, the pipe line connect the child process and it's parent process.
    
    >>> child = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  3. Then we can get the subprocess execution result output text use child process’s stdout read() method.
    >>> print(child.stdout.read())
  4. Below is another example that run command java -version to get current installed java version.
    >>> import subprocess
    
    >>> child = subprocess.Popen(['java','-version'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
    >>> print(child.stdout.read())
    b'openjdk version "1.8.0_212"\nOpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)\nOpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)\n'

2. Run Shell Command Use os Module system And popen Function.

  1. os.system(command) : Run operating system commands and display the results directly on the standard output device( ie: screen console). But the function’s return value is 0 or -1, and the data displayed on the screen cannot be obtained in source code. command parameter is the command string to be executed.
    >>> import os
    >>> ret = os.system('java -version')
    openjdk version "1.8.0_212"
    OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
    OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
    >>> ret
    0
  2. os.popen(command, [mode, [bufsize]]) : Start a child process to execute the command specified by the command parameter, and establish a pipe line between the parent process and the child process for communication between the parent and child processes.This method return a file object, which can be read or write, depending on the parameter mode‘s value. If the mode parameter’s value is ‘r’, then the file is readonly. If the mode parameter’s value is ‘w’, then the file is write only and it will throw error when you want to get the file object’s content use it’s read() method.In short, popen method can run operating system commands and can return the result of the command through the result file object’s read() method. Below is an example.
    >>> import os 
    
    # invoke os.popen method to run a shell command.
    >>> ret = os.popen('ifconfig')
    
    # get the shell command execution result through the returned file object's read() method.
    >>> ret.read()
    'lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384\n\toptions=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>\n\tinet 127.0.0.1 netmask 0xff000000 \n\tinet6 ::1 prefixlen 128 \n\tinet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 \n\tnd6 options=201<PERFORMNUD,DAD>\ngif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280\nstf0: flags=0<> mtu 1280\nen0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500\n\toptions=50b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV,CHANNEL_IO>\n\tether 10:dd:b1:9b:b0:b9 \n\tnd6 options=201<PERFORMNUD,DAD>\n\tmedia: autoselect (none)\n\tstatus: inactive\nen1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500\n\toptions=400<CHANNEL_IO>\n\tether 4c:8d:79:e1:bc:e2 \n\tinet6 fe80::82a:736f:f606:31f0%en1 prefixlen 64 secured scopeid 0x5 \n\tinet 192.168.31.31 netmask 0xffffff00 broadcast 192.168.31.255\n\tnd6 options=201<PERFORMNUD,DAD>\n\tmedia: autoselect\n\tstatus: active\nen3: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500\n\toptions=460<TSO4,TSO6,CHANNEL_IO>\n\tether 82:0a:57:17:dd:80 \n\tmedia: autoselect <full-duplex>\n\tstatus: inactive\nfw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 4078\n\tlladdr 10:dd:b1:ff:fe:5c:5f:76 \n\tnd6 options=201<PERFORMNUD,DAD>\n\tmedia: autoselect <full-duplex>\n\tstatus: inactive\nbridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500\n\toptions=63<RXCSUM,TXCSUM,TSO4,TSO6>\n\tether 82:0a:57:17:dd:80 \n\tConfiguration:\n\t\tid 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0\n\t\tmaxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200\n\t\troot id 0:0:0:0:0:0 priority 0 ifcost 0 port 0\n\t\tipfilter disabled flags 0x0\n\tmember: en3 flags=3<LEARNING,DISCOVER>\n\t        ifmaxaddr 0 port 6 priority 0 path cost 0\n\tnd6 options=201<PERFORMNUD,DAD>\n\tmedia: <unknown type>\n\tstatus: inactive\np2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304\n\toptions=400<CHANNEL_IO>\n\tether 0e:8d:79:e1:bc:e2 \n\tmedia: autoselect\n\tstatus: inactive\nawdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484\n\toptions=400<CHANNEL_IO>\n\tether 02:c2:69:6d:b3:5e \n\tinet6 fe80::c2:69ff:fe6d:b35e%awdl0 prefixlen 64 scopeid 0xa \n\tnd6 options=201<PERFORMNUD,DAD>\n\tmedia: autoselect\n\tstatus: active\nutun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380\n\tinet6 fe80::a4be:4aed:be5b:253%utun0 prefixlen 64 scopeid 0xb \n\tnd6 options=201<PERFORMNUD,DAD>\nutun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000\n\tinet6 fe80::cfcf:1568:4d94:3b0a%utun1 prefixlen 64 scopeid 0xc \n\tnd6 options=201<PERFORMNUD,DAD>\n'