如何处理 shell 脚本中的开关?

use*_*394 21 shell options shell-script getopts

是否有一些内置工具可以识别-x--xxxx作为开关,而不是参数,或者您是否必须遍历所有输入变量,测试破折号,然后解析参数?

gle*_*man 23

我假设您正在使用 bash 或类似的。一个例子:

all=false
long=false

while getopts ":hal" option; do
  case $option in
    h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;;
    a) all=true ;;
    l) long=true ;;
    ?) echo "error: option -$OPTARG is not implemented"; exit ;;
  esac
done

# remove the options from the positional parameters
shift $(( OPTIND - 1 ))

ls_opts=()
$all && ls_opts+=( -a )
$long && ls_opts+=( -l )

# now, do it
ls "${ls_opts[@]}" "$@"
Run Code Online (Sandbox Code Playgroud)


jw0*_*013 19

使用getopts.

它在 POSIX 规范中相当便携。不幸的是,它不支持长选项。

另请参阅bash-hackers wiki 提供的本getopts 教程以及来自 stackoverflow 的这个问题

如果您只需要简短的选项,getopts(使用非静默错误报告)的典型使用模式是:

# process arguments "$1", "$2", ... (i.e. "$@")
while getopts "ab:" opt; do
    case $opt in
    a) aflag=true ;; # Handle -a
    b) barg=$OPTARG ;; # Handle -b argument
    \?) ;; # Handle error: unknown option or missing required argument.
    esac
done
Run Code Online (Sandbox Code Playgroud)

  • 应该提到的是,在使用 `getopt` 之前,应该始终将其验证为 GNU getopt,但无论如何你都不应该使用它,因为无论如何 `getopts` 更便携(而且通常更好)。如果您*确实*出于某种原因需要调用它,请以特定于 GNU 的方式调用它,并确保 `GETOPT_COMPATIBLE` 不在环境中。 (3认同)
  • @ user394 选项字母后面的 `:` 表示它需要一个参数。`:` 作为第一个字符意味着抑制错误消息。 (2认同)

and*_*coz 8

你必须写一个循环来解析参数。实际上,您可以使用getopts命令轻松完成。

这是getopts手册页中的一个简单示例:

aflag=
bflag=
while getopts ab: name
do
    case $name in
    a)    aflag=1;;
    b)    bflag=1
          bval="$OPTARG";;
    ?)    printf "Usage: %s: [-a] [-b value] args\n" $0
          exit 2;;
    esac
done
if [ ! -z "$aflag" ]; then
    printf "Option -a specified\n"
fi
if [ ! -z "$bflag" ]; then
    printf 'Option -b "%s" specified\n' "$bval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
Run Code Online (Sandbox Code Playgroud)