1

I am calling a python script through a bash wrapper, but I'm having trouble dealing with arguments that contain quoted spaces.

I assemble the arguments to the python script into a bash variable, such as

opt="-c start.txt"
opt+="--self 'name Na'"

Then call the python script with something like:

python test_args.py $opt

When printing sys.argv in Python, I get

['test-args.py', '-c', 'start.txt', '--self', "'name", "Na'"]

instead of the expected

['test-args.py', '-c', 'start.txt', '--self', 'name Na']

I tried using an array when calling the script, such as

python test_args.py ${opt[@]}

but then I get

['test-args.py', "-c start.txt --self 'name Na'"]

Any other ideas?

1
  • 1
    Maybe this will help (look at the eval solution). Commented Jan 31, 2013 at 14:54

3 Answers 3

4

Use an array, but store each argument as a separate element in the array:

opt=(-c start.txt)
opt+=(--self 'name Na')

python test_args.py "${opt[@]}"

See BashFAQ #050.

Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I came up with in the end, thanks for writing it up!
0

This is what the shlex module is for.

The shlex class makes it easy to write lexical analyzers for simple syntaxes resembling that of the Unix shell. This will often be useful for writing minilanguages, (for example, in run control files for Python applications) or for parsing quoted strings.

Comments

-1

Your instinct to embed spaces inside the variable's value was good, but when the value is simply expanded during the command line parsing their special meaning is lost as you saw. You need to expand the variable before the command line to your python script is parsed:

set -f
eval python test_args.py $opt
set +f

That will expand to:

python test_args.py -c start.txt --self 'name Na'

Which will then be parsed correctly with the quotes regaining their special meaning.

Edit: I've added set -f/+f (aka -/+o noglob) around the eval to disable file globbing although that wasn't an issue in the OP's example that's not an unheard of issue with eval. (Another, stronger caveat is to never eval user input unless you take extreme care to make sure it won't blow up into something nasty. If you don't control the value being eval-ed, you can't be sure what will happen.)

2 Comments

Please don't use eval, it has a well-deserved reputation for causing bizarre bugs. For example, try this with opt="-c start.txt --self 'name * Na'" and try to explain the result.
I reject your risk assessment in the context of the OP which shows the script controlling the content of the value to be eval-ed, but agree a caveat is called for. Might have been more helpful though if you'd suggested surrounding the eval with set -f ... set +f to disable file globbing. (Which is the problem you're hinting it, of course.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.