Reputation: 704
I'm having a problem with subprocess and printing quotes.
My Python script takes user input, mashes it around a bit - and I need it to send it's results to a bash script in this manner.
myscript.sh 'var1 == a var2 == b; othervar == c' /path/to/other/files
Where I'm getting hung up on is the single quotes. Python tries to rip them out.
I used this for my test.
subprocess.Popen([myscript.sh 'var=11; ignore all' /path/to/files], shell=True, executable="/bin/bash")
which returns an invalid syntax pointing at the 2nd single quote. I've also tried the above without the brackets and using single quotes outside and double quotes inside, etc.
Other - would-like.
As I was saying above the 'var == a var == b; othervar == c' is derived from the python script (in string format) - and I'll need to call that in the subprocess like this.
subprocess.Popen([myscript.sh myvariables /path/to/files], shell=True, executable="/bin/bash")
I just have to put the single quotes around the value of myvariables like the first example.
Any pointers as to where I'm going off the correct method?
Thank you.
Upvotes: 5
Views: 25428
Reputation: 784
I haven't checked why this works, but it does and without the need for shell=True.
subprocess.Popen(["/bin/bash", "myscript.sh", '""' + string_to_be_quoted + '""', path_to_files])
Upvotes: 2
Reputation: 13140
When shell=True is passed to Popen, you pass whatever you would send on the command line. That means your list should only have one element. So for example:
subprocess.Popen(['myscript.sh "var=11; ignore all" /path/to/files'], shell=True, executable="/bin/bash")
Or if /path/to/files is a variable in your Python environment:
subprocess.Popen(['myscript.sh "var=11; ignore all" %s' % path_to_files], shell=True, executable="/bin/bash")
Having said that I STRONGLY encourage you not to use the shell argument. The reason is fragility. You'll get a much more robust way of doing it like this:
subprocess.Popen(["/bin/bash", "myscript.sh", "var=11; ignore all", path_to_files])
Note that "var=11; ignore all" is passed as one argument to your script. If those are separate arguments, make them separate list elements.
Upvotes: 11
Reputation: 40340
That's a list, those are strings in it, so they need quotes:
["myscript.sh", "var=11; ignore all", "/path/to/files"]
That should work. If your script really somehow relies on quotes, then try this (I don't know the details of how subprocess works):
["myscript.sh", "'var=11; ignore all'", "/path/to/files"]
Upvotes: 0