如何使用getopt将bash getopts参数传递给Python脚本



我有一个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[@]}"

相关内容

  • 没有找到相关文章

最新更新