Bash 脚本:要求每个选项参数最多出现一次
Bash script: require each option parameter to occur at most once
我正在 unix 中编写一个脚本,它将采用选项作为参数,如下所示:
./command -pers
允许的选项有p
、e
、r
、s
,可以是任意顺序,也是可选的。例如,这些是正确的语法:./command -e
、./command -sr
、./command -pes
,但这个是不正确的 ./command -pep
、./command -ssr
。不允许重复选项,但至少需要一个选项。
同样我使用了正则表达式,但并没有避免重复。
但它允许重复。请说出这个表达式是什么意思
[[ =~ ^-[p{0,1}r{0,1}s{0,1}e{0,1}]{1,4}$ ]] || { echo "$MSG_INCORRECT_USAGE"; }
#!/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
您可以使用这样的脚本 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!
arg0=$(basename [=10=] .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
我正在 unix 中编写一个脚本,它将采用选项作为参数,如下所示:
./command -pers
允许的选项有p
、e
、r
、s
,可以是任意顺序,也是可选的。例如,这些是正确的语法:./command -e
、./command -sr
、./command -pes
,但这个是不正确的 ./command -pep
、./command -ssr
。不允许重复选项,但至少需要一个选项。
同样我使用了正则表达式,但并没有避免重复。
但它允许重复。请说出这个表达式是什么意思
[[ =~ ^-[p{0,1}r{0,1}s{0,1}e{0,1}]{1,4}$ ]] || { echo "$MSG_INCORRECT_USAGE"; }
#!/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
您可以使用这样的脚本 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!
arg0=$(basename [=10=] .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