I have a problem with the following code:
callBash.py:
import subprocess
print "start"
subprocess.call("sleep.sh")
print "end"
sleep.sh:
sleep 10
I want the "end" to be printed after 10s. (I know that this is a dumb example, I could simply sleep within python, but this simple sleep.sh file was just as a test)
Making sleep.sh executable and adding shell=True
to the parameter list (as suggested in previous answers) works ok. Depending on the search path, you may also need to add ./
or some other appropriate path. (Ie, change "sleep.sh"
to "./sleep.sh"
.)
The shell=True
parameter is not needed (under a Posix system like Linux) if the first line of the bash script is a path to a shell; for example, #!/bin/bash
.
Actually, you just have to add the shell=True
argument:
subprocess.call("sleep.sh", shell=True)
But beware -
Warning Invoking the system shell with shell=True can be a security hazard if combined with untrusted input. See the warning under Frequently Used Arguments for details.
source
If sleep.sh
has the shebang #!/bin/sh
and it has appropriate file permissions -- run chmod u+rx sleep.sh
to make sure and it is in $PATH
then your code should work as is:
import subprocess
rc = subprocess.call("sleep.sh")
If the script is not in the PATH then specify the full path to it e.g., if it is in the current working directory:
from subprocess import call
rc = call("./sleep.sh")
If the script has no shebang then you need to specify shell=True
:
rc = call("./sleep.sh", shell=True)
If the script has no executable permissions and you can't change it e.g., by running os.chmod('sleep.sh', 0o755)
then you could read the script as a text file and pass the string to subprocess
module instead:
with open('sleep.sh', 'rb') as file:
script = file.read()
rc = call(script, shell=True)
Make sure that sleep.sh
has execution permissions, and run it with shell=True
:
#!/usr/bin/python
import subprocess
print "start"
subprocess.call("./sleep.sh", shell=True)
print "end"
If someone looking for calling a script with arguments
import subprocess
val = subprocess.check_call("./script.sh '%s'" % arg, shell=True)
remember to convert the args to string before passing, using str(arg).
This can be used to pass as many arguments as required
subprocess.check_call("./script.ksh %s %s %s" % (agr1, str(arg2), arg3), shell=True)
If chmod not working then you also try
import os
os.system('sh script.sh')
#you can also use bash instead of sh
test by me thanks
Adding an answer because I was directed here after asking how to run a bash script from python. You receive an error OSError: [Errno 2] file not found
if your script takes in parameters. Lets say for instance your script took in a sleep time parameter: subprocess.call("sleep.sh 10")
will not work, you must pass it as an array: subprocess.call(["sleep.sh", 10])