Bash脚本:要求每个选项参数最多出现一次

时间:2015-07-10 06:45:28

标签: regex unix duplicates

我在unix中编写一个脚本,它将选项作为参数显示:

./command -pers

允许的选项包括pers,也可以是任意顺序,也是可选的。例如,这些是正确的语法:./command -e./command -sr./command -pes,但这一个不正确./command -pep./command -ssr。不允许重复选项,但至少需要一个选项。

对于同样的我使用正则表达式,但它不是避免重复。

但它允许重复。请告诉我们表达的内容是什么。

[[ $1 =~ ^-[p{0,1}r{0,1}s{0,1}e{0,1}]{1,4}$ ]] || { echo "$MSG_INCORRECT_USAGE"; }

3 个答案:

答案 0 :(得分:1)

#!/bin/bash

while getopts "pers" OPTION; do
        echo $OPTION
done

结果:

$ bash test.sh -pers
p
e
r
s

echo $OPTION替换为case语句,如果选项出现两次,则报告错误。例如:

#!/bin/bash

unset OPT_P OPT_E OPT_R OPT_S

while getopts "pers" OPTION; do
    case $OPTION in
    p)
        if [ $OPT_P ]; then
            echo "-p appeared twice"
            exit 64
        else
            OPT_P="true"
        fi
        ;;
    #... and so on ...
    \?)
        echo "Unrecognized option $OPTION"
        exit 64
        ;;
done

答案 1 :(得分:1)

您可以使用这样的脚本opt.sh 避免多次处理每个传递的选项

#!/bin/bash

while getopts "pers" opt; do
  [[ -n ${!opt} ]] && { echo "Error: $opt already processed"; exit 1; } || declare $opt=1

  case $opt in
    p) echo "processing p!" ;;
    e) echo "processing e!" ;;
    r) echo "processing r!" ;;
    s) echo "processing s!" ;;
    \?) echo "Invalid option: -$OPTARG" ;;
  esac
done

<强>测试

bash ./opt.sh -srr
processing s!
processing r!
Error: r already processed

bash ./opt.sh -pep
processing p!
processing e!
Error: p already processed

bash ./opt.sh -pers
processing p!
processing e!
processing r!
processing s!

答案 2 :(得分:0)

arg0=$(basename $0 .sh)
error() { echo "$arg0: $*" >&2; exit 1; }
usage() { echo "Usage: $arg0 [-pers]" >&2; exit 1; }

p_flag=
e_flag=
r_flag=
s_flag=

while getopts pers arg
do
    case "$arg" in
    (e) [ -z "$e_flag" ] || error "-e flag repeated"
        e_flag=1;;
    (p) [ -z "$p_flag" ] || error "-p flag repeated"
        p_flag=1;;
    (r) [ -z "$r_flag" ] || error "-r flag repeated"
        r_flag=1;;
    (s) [ -z "$s_flag" ] || error "-s flag repeated"
        s_flag=1;;
    (*) usage;;
    esac
done

shift $(($OPTIND - 1))

[ -z "$e_flag$p_flag$r_flag$s_flag" ] && error "You must specify one of -e, -p, -r, -s"
[ $# = 0 ] || error "You may not specify any non-option arguments"

…process the code for each option that was set…

如果您需要按照给出的顺序处理选项,则需要记录它们到达的顺序。使用数组:

flags=()

在循环之前,

flags+=("$arg")
esac之后

。然后,处理可以按顺序处理$flags的每个元素。

for flag in "${flags[@]}"
do
    …processing for the particular flag…
done