How to 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.

- 1,817
- 4
- 22
- 38

- 72,339
- 21
- 134
- 141
-
14Note: it's preferable to pass subprocess.call() a list rather than a string (see command to Hugo24 below for the example and reasons). – Jim Dennis Sep 23 '10 at 11:30
-
1The link to the tutorial is broken. – Kshitij Saraogi Mar 29 '17 at 09:37
-
6This gives: OSError: [Errno 13] Permission denied. my script does not required to run with sudo. @Manoj Govindan – alper Apr 19 '17 at 12:04
-
11With arguments: subprocess.call(['./test.sh', 'param1', 'param2']) – Henry Feb 15 '18 at 04:38
-
2@alper go the folder where you have placed the script and run the command, `chmod +x script.sh`. Note: script.sh is a placeholder for your script, replace it accordingly. – Tom J Muthirenthi May 08 '19 at 09:26
-
4The subprocess api has changed in python 3.5. The new method is .run(args) instead of call – Kévin Sanchez Lacroix May 04 '20 at 17:46
-
1I believe you need to add `subprocess.call(['sh', './test.sh'])` Otherwise it raises exec format error as discussed in here https://stackoverflow.com/questions/26807937/subprocess-popen-oserror-errno-8-exec-format-error-in-python – anilbey Jul 29 '20 at 09:27
-
Otherwise we are assuming that `test.sh` always starts with the shebang specifying which interpreter to use. Better to do it in Python imo. Explicit over implicit. – anilbey Jul 29 '20 at 09:32
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.

- 4,851
- 4
- 8
- 30

- 53,067
- 18
- 70
- 114
-
3why isn't this the most upvoted answer? Isn't not having to import a module the better solution? Must be some drawback here? – boulder_ruby Jan 18 '16 at 20:07
-
15With `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. – Michał Niklas Jan 19 '16 at 12:55
-
4To quote from that link: `The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*` – Maximilian Aug 16 '17 at 04:48
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

- 77,520
- 72
- 342
- 501
-
1
-
-
1@keerthi007 `subprocess.call(shlex.split(f"./test.sh param1 {your_python_var} param3"))` – TDk Aug 06 '20 at 15:50
import os
import sys
Assuming test.sh is the shell script that you would want to execute
os.system("sh test.sh")

- 27,828
- 29
- 136
- 207

- 558
- 6
- 15
Use the subprocess module as mentioned above.
I use it like this:
subprocess.call(["notepad"])

- 1,089
- 13
- 21
-
17Note: calling subprocess with a list is safer since it doesn't necessitate passing the (potentially unsanitized) string through a shell for parsing/interpretation. The first item in the list will be the executable and all other items will be passed as arguments. – Jim Dennis Sep 23 '10 at 11:29
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 wanna do with the output.
1 - call 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 string. You don't see execution in your terminal unless you print(stdout). Shell=True as 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 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 doc subprocess

- 580
- 7
- 10
-
2**Note** Do not use stdout=PIPE or stderr=PIPE with ```subprocess.call```. The child process will block if it generates enough output to a pipe to fill up the OS pipe buffer as the pipes are not being read from. – Mar 11 '19 at 11:07
I know this is an old question but I stumbled upon this recently and it ended up misguiding me since the Subprocess API as changed since python 3.5.
The new way to execute external scripts is with the run
function, which runs the command described by args. Waits for command to complete, then returns a CompletedProcess instance.
import subprocess
subprocess.run(['./test.sh'])

- 663
- 9
- 13
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"

- 3,884
- 3
- 27
- 49
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.

- 594
- 4
- 16
-
-
-
Hi Ankit. I need some help on this. Assume the example.sh file is in Oracle cloud infrastructure. How can call/run such example.sh file in python? I need to connect to the oracle cloud then, I should use the script you written here. Could you please write the additional code (how to connect an example.sh file which in in OCI)? Thank you. – Sanky Ach Mar 16 '21 at 12:56
If your shell script file does not have execute permissions, do so in the following way.
import subprocess
subprocess.run(['/bin/bash', './test.sh'])

- 161
- 1
- 5
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.

- 27,244
- 10
- 65
- 75
In order to run shell script in python script and to run it from particular path in ubuntu, use below ;
import subprocess
a= subprocess.call(['./dnstest.sh'], cwd = "/home/test")
print(a)
Where CWD is current working directory
Below will not work in Ubuntu ; here we need to remove 'sh'
subprocess.call(['sh' ,'./dnstest.sh'], cwd = "/home/test")

- 29,388
- 11
- 94
- 103

- 319
- 4
- 8
Using @Manoj-Govindan 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 viola! Suddenly it executed.
subprocess.call(['bash', './test.sh'])

- 19
- 3
Please Try the following codes :
Import Execute
Execute("zbx_control.sh")

- 22,203
- 13
- 58
- 75

- 59
- 1