Bash脚本中的可选参数



我正试图编写一个具有可选参数的函数,使可选参数后面跟着类似-x的东西,例如

my_function man_arg1 man_arg2 -n opt_arg1 -o opt_arg2 -x opt_arg3

我希望这也能支持像这样的呼叫

my_function man_arg1 man_arg2 -x opt_arg

在其他问题中,我看到有人建议使用getopts,但在这些答案中,似乎在调用函数时必须指定所有可选参数?此外,我还不清楚如何使用getopts。

我不确定我是否正确理解了这个问题,如果我没有回答,很抱歉…

您可以使用(例如(getopt(1),如下所示,这将允许-x选项位于任何位置。请注意,可选参数(man_arg*(也可以在任何位置。

#! /usr/bin/bash
# CMD is the shell-script name without directory (basename)
CMD="${0##*/}"
my_function() {
# Some comments added per OP request
# below variable is used by getopt's "-o" option (short options).
# each letter is a possible option; colon following a letter means this
# option will take a parameter. See getopt(1) for more details.
SOPTS="n:o:x:"
# output of getopt is assigned to TMP. For example, when calling :
# my_function -n n1 a b -o o1 -x x1 c d
# TMP will contain: "-n 'n1' -o 'o1' -x 'x1' -- 'a' 'b' 'c' 'd'"
TMP=$(getopt -o "$SOPTS" -n "$CMD" -- "$@") || exit 1
# assign TMP to positional parameters $1, $2, etc...
eval set -- "$TMP"
unset TMP
while true; do
case "$1" in
-n|-o)
printf "[%s] argument: %sn" "$1" "$2"
shift
;;
-x)
printf "[-x] argument: %sn" "$2"
shift
;;
--)                                       # end of options
shift
break
;;
esac
shift
done
nargs=$#
printf "remaining %d args :n" "$nargs"
for ((i=0; i<nargs; ++i)); do
printf "%d: %sn" $((i + 1)) "$1"
shift
done
}
my_function "$@"

示例:

br@lorien:~$ ./test-getopt.bash man_arg1 man_arg2 -n opt_arg1 -o opt_arg2 -x opt_arg3
[-n] argument: opt_arg1
[-o] argument: opt_arg2
[-x] argument: opt_arg3
remaining 2 args :
1: man_arg1
2: man_arg2
br@lorien:~$ ./test-getopt.bash man_arg1 man_arg2 -n opt_arg1 -o opt_arg2 -x opt_arg3 man_arg3 man_arg4
[-n] argument: opt_arg1
[-o] argument: opt_arg2
[-x] argument: opt_arg3
remaining 4 args :
1: man_arg1
2: man_arg2
3: man_arg3
4: man_arg4
br@lorien:~$ ./test-getopt.bash man_arg1 man_arg2 -x opt_arg
[-x] argument: opt_arg
remaining 2 args :
1: man_arg1
2: man_arg2
br@lorien:~$ ./test-getopt.bash -x opt_arg4 man_arg2 -n opt_arg1 -x opt_arg3 man_arg3 man_arg4
[-x] argument: opt_arg4
[-n] argument: opt_arg1
[-x] argument: opt_arg3
remaining 3 args :
1: man_arg2
2: man_arg3
3: man_arg4

编辑:根据问题将代码重新编写为函数。

POSIX约定是命令的非选项参数必须在所有选项和选项参数之后。POSIXgetopts实用程序是围绕这个约定设计的,因此如果您不想坚持传统的参数顺序,那么getopts就不太适合。在这种情况下,getopts仍然有可能工作,但我不会这么做

如果您愿意依赖getopt实用程序的GNU版本(不要与getoptss混淆(,那么它可以满足您的需要。默认情况下,它可以识别命令行中任何位置的选项,包括非选项参数之后的选项。看起来可能是这样的:

args=$(getopt --name "$0" --options n:o:x: -- "$@")
eval set -- "$args"
while [[ $# -gt 0 ]]; do
case "$1" in
-n) n_argument=$2; shift 2;;
-o) o_argument=$2; shift 2;;
-x) x_argument=$2; shift 2;;
*)
# Handle non-option argument $1 ...
shift
;;
esac
done

但请注意,在没有getopt的情况下,您也可以执行相同的操作。getopt(或getopts(为您做的是:

  • 规范化成组选项(-abc等效于-a -b -c;仅适用于不需要参数的选项(
  • 规范化选项/参数分隔(当选项x采用参数时,-xfoo等效于-x foo(
  • 认识到并适应自变量--的重要性,指出后面只有非选项自变量
  • 认识到自变量中的错误,尤其是在需要选项自变量的地方遗漏了选项自变量
  • 类似于上述GNU风格的长选项(仅限GNUgetopt(

如果你对这些都不感兴趣,或者如果你愿意为你想要的人推出自己的,或者如果不能依赖GNU版本的getopt,那么你可以使用类似于上面的循环,而不需要首先使用getopt来处理参数列表,也不需要涉及getopts

相关内容

  • 没有找到相关文章

最新更新