Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python subprocess calling bash script - need to print the quotes out too

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.

like image 794
Chasester Avatar asked Jan 25 '11 20:01

Chasester


2 Answers

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.

like image 155
Ken Kinder Avatar answered Nov 15 '22 00:11

Ken Kinder


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])
like image 45
Dave Avatar answered Nov 14 '22 23:11

Dave