While you got 2 answers that show how to use subprocess
with an iterable for the arguments and I would recommend going one of those ways, for completeness you can use a string containing the full command if you specify shell=True
, but then you're responsible for all the quoting and everything like that for arguments.
Process=subprocess.Popen('./copyImage.sh %s' % shlex.quote("myPic.jpg"), shell=True)
Note that in addition to adding shell=True
I pass the argument through shlex.quote
to let it handle escaping any special characters to make it a bit safer if the filename came from a user input, otherwise it could include a ;
and another command to run, for example. Input like myPic.jpg; rm -rf ~
would otherwise cause bad things to happen when executed.
If you don't specify shell=True
the subrpocess module will actually be looking for an executable named copyImage.sh myPic.jpg
with the space and both words as the name of the executable to run.
Two further notes, for python 2 instead of shlex.quote
use pipes.quote
. Also, the shell script above does not quote its arguments, so will not work with names with spaces or other special characters. It should be modified to quote its variables (which is always a good idea):
#!/bin/sh
cp /home/pi/project/"$1" /home/pi/project/newImage.jpg
With a slightly different script:
#!/bin/bash
printf 'Arg 1 is: %s\n' "$1"
we can see this work as follows:
subprocess.check_call("./demoScript.sh %s" % shlex.quote("This has ; bad stuff"), shell=True)
which produces the following output on stdout
Arg 1 is: This has ; bad stuff