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}\""

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.