How can I call a shell script from Python code?
14 Answers
The subprocess module will help you out.
Blatantly trivial example:
>>> import subprocess
>>> subprocess.call(['sh', './test.sh']) # Thanks @Jim Dennis for suggesting the []
0 
Where test.sh is a simple shell script and 0 is its return value for this run.
8 Comments
chmod +x script.sh. Note: script.sh is a placeholder for your script, replace it accordingly.There are some ways using os.popen() (deprecated) or the whole subprocess module, but this approach
import os
os.system(command)
is one of the easiest.
3 Comments
subprocess you can manage input/output/error pipes. It is also better when you have many arguments -- with os.command() you will have to create whole command line with escaping special characters, with subprocess there is simple list of arguments. But for simple tasks os.command()  may be just sufficient.The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*In case you want to pass some parameters to your shell script, you can use the method shlex.split():
import subprocess
import shlex
subprocess.call(shlex.split('./test.sh param1 param2'))
with test.sh in the same folder:
#!/bin/sh
echo $1
echo $2
exit 0
Outputs:
$ python test.py 
param1
param2
3 Comments
subprocess.call(shlex.split(f"./test.sh param1 {your_python_var} param3"))Use the subprocess module as mentioned above.
I use it like this:
subprocess.call(["notepad"])
1 Comment
I'm running Python 3.5 and subprocess.call(['./test.sh']) doesn't work for me.
I give you three solutions depends on what you want to do with the output.
1 - call the script. You will see output in your terminal. output is a number.
import subprocess
output = subprocess.call(['test.sh'])
2 - call and dump execution and error into a string. You don't see execution in your terminal unless you use print(stdout). Shell=True as the argument in Popen doesn't work for me.
import subprocess
from subprocess import Popen, PIPE
session = subprocess.Popen(['test.sh'], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()
if stderr:
    raise Exception("Error "+str(stderr))
3 - call the script and dump the echo commands of temp.txt in temp_file
import subprocess
temp_file = open("temp.txt",'w')
subprocess.call([executable], stdout=temp_file)
with open("temp.txt",'r') as file:
    output = file.read()
print(output)
Don't forget to take a look at the document of subprocess.
I stumbled upon this recently, and it ended up misguiding me since the Subprocess API has changed since Python 3.5.
The new way to execute external scripts is with the run function, which runs the command described by the arguments. It waits for the command to complete, and then returns a CompletedProcess instance.
import subprocess
subprocess.run(['./test.sh'])
Comments
In case the script is having multiple arguments
#!/usr/bin/python
import subprocess
output = subprocess.call(["./test.sh","xyz","1234"])
print output
Output will give the status code. If script runs successfully it will give 0 otherwise non-zero integer.
podname=xyz  serial=1234
0
Below is the test.sh shell script.
#!/bin/bash
podname=$1
serial=$2
echo "podname=$podname  serial=$serial"
Comments
Subprocess module is a good module to launch subprocesses. You can use it to call shell commands as this:
subprocess.call(["ls","-l"]);
#basic syntax
#subprocess.call(args, *)
You can see its documentation here.
If you have your script written in some .sh file or a long string, then you can use os.system module. It is fairly simple and easy to call:
import os
os.system("your command here")
# or
os.system('sh file.sh')
This command will run the script once, to completion, and block until it exits.
3 Comments
Subprocess is good but some people may like scriptine better. Scriptine has more high-level set of methods like shell.call(args), path.rename(new_name) and path.move(src,dst). Scriptine is based on subprocess and others.
Two drawbacks of scriptine:
- Current documentation level would be more comprehensive even though it is sufficient.
- Unlike subprocess, scriptine package is currently not installed by default.
Comments
Using Manoj Govindan's answer, I found that I could run simple shell scripts from Python, but the script I was desperately trying to run would fail with the error
Syntax error: "(" unexpected
I changed the first argument from 'sh' to 'bash', and voilà! Suddenly it executed.
subprocess.call(['bash', './test.sh'])
2 Comments
In order to run a shell script in a Python script and to run it from a particular path in Ubuntu, use the below;
import subprocess
a = subprocess.call(['./dnstest.sh'], cwd = "/home/test")
print(a)
Where CWD is the current working directory.
The below will not work in Ubuntu; here we need to remove 'sh':
subprocess.call(['sh' ,'./dnstest.sh'], cwd = "/home/test")
















