5

I have a bash script which reads variable from environment and then passes it to the python script like this

#!/usr/bin/env bash

if [ -n "${my_param}" ]
then
    my_param_str="--my_param ${my_param}"
fi

python -u my_script.py ${my_param_str}

Corresponding python script look like this

parser = argparse.ArgumentParser(description='My script')
parser.add_argument('--my_param',
                    type=str,
                    default='')

parsed_args = parser.parse_args()
print(parsed_args.description)

I want to provide string with dash characters "Some -- string" as an argument, but it doesn't work via bash script, but calling directly through command line works ok.

export my_param="Some -- string"
./launch_my_script.sh

gives an error unrecognized arguments: -- string and python my_script.py --my_param "Some -- string" works well. I've tried to play with nargs and escape my_param_str="--my_param '${my_param}'" this way, but both solutions didn't work. Any workaround for this case? Or different approach how to handle this?

3
  • -- marks the end of arguments for a command in the normal case. Commented May 19, 2016 at 7:47
  • 1
    You should always double-quote Bash parameter expansions unless you explicitly want Bash to perform word splitting... and you probably don't really want word splitting. :) See the BashGuide and ShellCheck. Commented May 19, 2016 at 7:51
  • Look at sys.argv to see what bash is giving your script. argparse can only parse the strings in that list. Commented May 19, 2016 at 18:55

3 Answers 3

6

Your bash needs to look like this:

if [ -n "${my_param}" ]
then
    my_param_str="--my_param \"${my_param}\""
fi

echo ${my_param_str}|xargs python -u my_script.py

Otherwise, the quotes around the parameter string will not be preserved, and "Some", "--" and "thing" will be passed as three separate arguments.

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

1 Comment

Really nice xargs-fu! Works perfectly with python argparse.
2

For the limited example you can basically get the same behavior just using

arg = os.environ.get('my_param', '')

where the first argument to get is the variable name and the second is the default value used should the var not be in the environment.

1 Comment

Thanks, but I tied to bash passing case
0

The quotes you write around the string do not get preserved when you assign a Bash string variable:

$ export my_param="Some -- string"
$ echo $my_param
Some -- string

You need to place the quotes around the variable again when you use it to create the my_param_str:

my_param_str="--my_param \"${my_param}\""

2 Comments

That's not right. That would turn my_param_str into a single argument of the form --my_param Some -- string. The quotes should be around Some -- string.
@Rawing In that case they would have to be written in this line: my_param_str="--my_param \"${my_param}\""

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.