我有一个脚本,我向其中传递了许多标志。该脚本中仅使用了其中一些标志,我想使用“while getopts”循环它们。然而,似乎这个循环仅在指定所有标志时才有效。但是,某些标志不适用于此脚本,而是传递给另一个脚本,因此我想在这里忽略它们。
while getopts ":W:" flag ; do
case "${flag}" in
"W")
_TASK=${OPTARG}
;;
esac
done
if [ "${_TASK}" == "OK" ] ; then
./other_script.sh "$@"
fi
此代码仅在我像这样运行时才有效:
myscript.sh -W OK -f otherflag1 -g otherflag2 etc...
但如果我运行则不会:
myscript.sh -f otherflag -W OK
因为现在,它不会在循环中找到“-W”标志。因此,传递标志现在取决于顺序,我觉得这很丑陋。 (另外,与此相关:如何从“$@”中删除“-W OK”?)
最佳答案
你可以这样做,但它有点难看,并且有几个警告:
您需要知道如何解析您将传递的标志。例如,如果
-f
标志接受参数,则-fWOK
需要按原样传递(或作为-f WOK
) ,但如果不是,则-fWOK
是-f -W OK
的缩写,您需要应用并删除-W OK
部分并且仅传递-f
。这意味着其他程序的标志必须采用与 getopts 兼容的格式。这意味着可能没有长选项(例如
--exclude=foo
)(嗯,大部分),并且没有像 gnused
的-i
那样奇怪的东西> 标志(它需要一个参数,但它必须直接附加,因此sed -i.bak
可以工作,但是sed -i .bak
没有)。这也意味着标志必须位于位置参数之前。或者至少是适用于您的脚本的那些。例如,
ls -l somefile.txt
可以,但ls somefile.txt -l
则不行。
考虑到这些注意事项,这里有一种使用 getopts
来实现的方法。在此示例中,-W
是脚本的一个标志并带有一个参数; -a
、-b
、-c
和 -d
是其他程序的标志不要接受争论; -e
、-f
和 -g
是其他程序确实接受参数的标志:
#!/bin/bash
pass_on=() # We'll accumulate flags to pass on here
while getopts ":W:abcde:f:g:" flag ; do
case "${flag}" in
W )
echo "got -W '$OPTARG' option" >&2
_TASK=${OPTARG} ;;
a|b|c|d ) # pass-on flags that DON'T take arguments
pass_on+=("-${flag}") ;;
e|f|g ) # pass-on flags that DO take arguments
pass_on+=("-${flag}${OPTARG}") ;;
\? )
echo "Invalid option: -${OPTARG}" >&2
exit 1 ;;
: )
echo "Missing argument to option -${OPTARG}" >&2
exit 1 ;;
esac
done
shift $((OPTIND-1)) # Remove the flags we've processed from the arg list
echo "Passed-on flags and arguments:"
printf " '%s'\n" "${pass_on[@]}" "$@"
关于bash - 如何使 getopts 忽略未指定的标志(bash),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57977984/