如何使用 getopt 将 bash getopts 参数传递给 Python 脚本
how to pass bash getopts argument to Python script with getopt
我有一个 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
您需要进行三处更改:
declare -a MY_DATETIME_PARAM
...
MY_DATETIME_PARAM=(--my-date "${OPTARG}")
...
python my_python_script.py "${MY_DATETIME_PARAM[@]}"
问题是您在调用 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 个字符串,第一个 echo 也会产生 6 个不包含空格的单独字符串。第二个回声给出了正确的结果。 3 个字符串,一些包含空格。
我有一个 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
您需要进行三处更改:
declare -a MY_DATETIME_PARAM
...
MY_DATETIME_PARAM=(--my-date "${OPTARG}")
...
python my_python_script.py "${MY_DATETIME_PARAM[@]}"
问题是您在调用 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 个字符串,第一个 echo 也会产生 6 个不包含空格的单独字符串。第二个回声给出了正确的结果。 3 个字符串,一些包含空格。