Chasester
Chasester

Reputation: 704

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.

Upvotes: 5

Views: 25428

Answers (3)

Jade
Jade

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

Ken Kinder
Ken Kinder

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

Thomas K
Thomas K

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

Related Questions