How To Run Bash Commands In Python
Below commands are useful for following version.
python --version
Python 3.7.4
There are different ways to run bash commands in Python. Lets start with os.system command.
How to use os.system to run Bash Command
import os
Once we have imported the os. We can use os.system and pass it bash command. Lets try ls -ld /home command
os.system("ls -ld /home")
0
The command is executed. We can't capture the output with os.system
How to use subprocess.check_output to run Bash Commands
To see the output of executed command. There is another way. We need to import Python package subprocess.
import subprocess
subprocess.check_output('ls -ld /home',shell=True, universal_newlines=True):
'drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home\n'
How to use subprocess.run to run Bash Commands
To capture the output in a variable use the run method.
subprocess.run(['ls','-ld','/home'],check=True, stdout=subprocess.PIPE, universal_newlines=True):
CompletedProcess(args=['ls', '-ld', '/home'], returncode=0, stdout='drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home\n')
We can also capture the output in a variable
output = subprocess.run(['ls','-ld','/home'],check=True, stdout=subprocess.PIPE, universal_newlines=True)
output can be printed using following command.
output.stdout
'drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home\n'
We can also printout the errors using following command.
output.stderr
check=True options throw an error if underlying option throws an error. Lets try again.
subprocess.run(['ls','-ld','/home1'],check=True, stdout=subprocess.PIPE, universal_newlines=True)
CalledProcessError: Command '['ls', '-ld', '/home1']' returned non-zero exit status 2.
Lets try without check=True option
subprocess.run(['ls','-ld','/home1'], stdout=subprocess.PIPE, universal_newlines=True)
CompletedProcess(args=['ls', '-ld', '/home1'], returncode=2, stdout='')
Run Bash commands using Python Popen
Popen is used for complex commands, such as pipe commands in bash. Lets try a simple pipe command first.
p = subprocess.Popen(['ls','-ld','/home'],stderr=subprocess.PIPE, universal_newlines=True,stdout=subprocess.PIPE)
out,err = p.communicate()
print(out,err)
drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home
p is a Python process. We can query it anytime. Also we can close it.
p.stdout.close()
Lets try accessing p again.
out,err = p.communicate()
We got the following error...
ValueError: Invalid file object: <_io.TextIOWrapper name=46 encoding='UTF-8'>
How to pipe commands together using Python Popen
Lets calculate number of files in the home directory.
p1 = subprocess.Popen(['ls','-lrt','/home'],stderr=subprocess.PIPE, universal_newlines=True,stdout=subprocess.PIPE)
p2 = subprocess.Popen(["wc", "-l"], stdin=p1.stdout, stdout=subprocess.PIPE)
Note, how we have to query p1.stdout to find the output.
Now lets look at the output.
output = p2.communicate()
print(output)
(b'23\n', None)
Wrap Up!
I have discussed above 5 ways to run Bash commands in Python. There is another utility called pysh which can be used to run Bash commands.
Related Topics:
check if directory exists bash