我有一个bash脚本,它接受一个getopt参数,构建一个Python getopt选项,并尝试运行一个Python脚本,传递创建的getopt参数。但是,这不起作用。
bash脚本
#!/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}"
和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)
结果是
$ ./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
然而,从cmd手动运行python脚本似乎工作得很好
$ python my_python_script.py --my-date 2012-12-12
2012-12-12
问题是您在调用python时引用${MY_DATETIME_PARAM}
,这使其成为单个字符串和单个参数,而不是2个单独的参数。
python my_python_script.py ${MY_DATETIME_PARAM}
在这种情况下应该可以工作,但不是很健壮。更好的方法是将参数存储在数组中,然后在最后一行展开数组的元素,如下所示:
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[@]}"
你可以很容易地添加参数到数组。
需要注意的是,最后一行中的数组展开是加引号的。这确保了数组元素中的空格被正确处理。shell将引号解释为:"引用数组的每个元素",而不是"引用扩展后的所有元素"。例如:
> parameters=( "Hello" "Bon jour" "Auf wiedersehen, Pet" )
> echo ${parameters[@]}
Hello Bon jour Auf wiedersehen, Pet
> echo "${parameters[@]}"
"Hello" "Bon jour" "Auf wiedersehen, Pet"
即使数组只包含3个字符串,第一次回显结果是6个单独的字符串,不包含空格。第二次回声给出了正确的结果。3个字符串,部分包含空格。
你需要做三个改变:
declare -a MY_DATETIME_PARAM
...
MY_DATETIME_PARAM=(--my-date "${OPTARG}")
...
python my_python_script.py "${MY_DATETIME_PARAM[@]}"