1

I am trying to parse arguments as bash variables when calling a python script.

#!/bin/bash
var="--circular True"
python python_script.py --input input_file "$var"

I got this error:

python_script.py: error: unrecognized arguments: --circular True

However, if I don't use a variable for the --circular flag, the script runs well without errors.

#!/bin/bash
python python_script.py --input input_file --circular True

P.S. I am using the python module argparse

3
  • 1
    Remove the quotes and use ${var} instead Commented Nov 16, 2022 at 21:00
  • @LeshawnRice thanks, removing the quotes solved the problem. Do you know why I cannot use the quotes in this case? Commented Nov 16, 2022 at 21:07
  • 1
    The quotes cause "--circular True" to be passed as a single argument. Argparse was expecting "--circular" followed by another value, not "--circular True" Commented Nov 16, 2022 at 21:14

1 Answer 1

2

"$var" expands the value of variable var to a single shell word. The result is not subject to word splitting in the context in which the epxansion takes place. This is why with ...

var="--circular True"
python python_script.py --input input_file "$var"

... Python sees a single argument --circular True instead of multiple arguments.

In this case, you could just leave out the quotes around the expansion of $var on the python command line, but this is a poor idea in general. The best way to store multiple command-line arguments in a variable in Bash is to use an array:

var=(--circular True)
python python_script.py --input input_file "${var[@]}"

In particular, the form "${var[@]}" expands to all the elements of array var, each element as a separate word. This handles cases that are not handled by using a scalar var and expanding it unquoted does not. For example, with ...

var=(--label 'plausible example')
python python_script.py --input input_file "${var[@]}"

... two arguments are derived from the variable, --label and plausible example. However, with this alternative ...

var="--label 'plausible example'"
python python_script.py --input input_file $var

... the arguments derived from var are --label and 'plausible example' (note the extra quotes), and with this ...

var="--label plausible example"
python python_script.py --input input_file $var

... three arguments are derived from var: --label, plausible, and example.

This becomes even more important when the arguments are derived from user input, so that you do not have the opportunity to tune your usage to the specific data.

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

3 Comments

Wow, thank you so much for the comprehensive explanation!
I don't know why, but the last option did not work for me. It still was recognized as a single argument '--var value'. Only the array expansion worked out for me.
Well, @BramVanroy, the array expansion is the best alternative here, as this answer already explains. That's what you should use. But the others demonstrably work as described. If you think you see different, then what you're doing is meaningfully different. Speculation: if you test with var defined as an array and then attempt to test the last option without redefining var as a flat string, it will not work.

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.