I have a bash script which takes a getopt argument, builds a Python getopt option and tries to run a Python script passing the created getopt argument. However, this doesn't work.
My bash script
#!/bin/bash
set -x
set -e
while getopts "d:" o; do
case "${o}" in
d)
echo $OPTARG
MY_DATETIME_PARAM="--my-date ${OPTARG}"
;;
esac
done
python my_python_script.py "${MY_DATETIME_PARAM}"
And my_python_script.py
import getopt
import sys
try:
opts, args = getopt.getopt(sys.argv[1:], "d:", ["my-date="])
except getopt.GetoptError as e:
print(e)
sys.exit(1)
for opt, arg in opts:
if opt in ("-d", "--my-date"):
print(arg)
And the result is
$ ./test.sh -d 2012-12-12
set -e
getopts d: o
case "${o}" in
echo 2012-12-12
2012-12-12
MY_DATETIME_PARAM='--my-date 2012-12-12'
getopts d: o
python my_python_script.py '--my-date 2012-12-12'
option --my-date 2012-12-12 not recognized
However, running the python script manually from cmd seems to work nice
$ python my_python_script.py --my-date 2012-12-12
2012-12-12
CodePudding user response:
The problem is that you are quoting ${MY_DATETIME_PARAM}
when calling python, which makes it a single string and a single argument instead of 2 separate arguments.
One way to solve this is to remove the quotes in the last line:
python my_python_script.py ${MY_DATETIME_PARAM}
That should work in this case, but is not very robust. A better way to do this is to store the arguments in an array, and then expand the elements of the array in the last line, like this:
declare -a parameters
while getopts "d:" o; do
case "${o}" in
d)
echo $OPTARG
parameters =( "--my-date" "${OPTARG}" )
;;
esac
done
python my_python_script.py "${parameters[@]}"
You can then easily add parameters by adding to the array.
It is important to note that the array expansion in the last line is quoted. This ensures that spaces in the array elements are handled correctly. The shell interprets the quotation marks as meaning: "Quote each element of the array", rather than "Quote all elements after expansion". For example:
> parameters=( "Hello" "Bon jour" "Auf wiedersehen, Pet" )
> echo ${parameters[@]}
Hello Bon jour Auf wiedersehen, Pet
> echo "${parameters[@]}"
"Hello" "Bon jour" "Auf wiedersehen, Pet"
Even though the array only contains 3 strings, the first echo results in 6 separate strings containing no spaces. The second echo gives the correct result. 3 strings, some containing spaces.
CodePudding user response:
You need three changes :
declare -a MY_DATETIME_PARAM
...
MY_DATETIME_PARAM=(--my-date "${OPTARG}")
...
python my_python_script.py "${MY_DATETIME_PARAM[@]}"