I am writing a script in unix, which will take options as parameter as shown:
我在unix中编写一个脚本,它将选项作为参数显示如下:
./command -pers
The options allowed are p
, e
, r
, s
and can be in any order and are optional also. Example, these are correct syntax: ./command -e
, ./command -sr
, ./command -pes
, but this one is incorrect ./command -pep
, ./command -ssr
. Repetition of option is not allowed, but atleast one option is required.
允许的选项是p,e,r,s,可以是任何顺序,也是可选的。例如,这些是正确的语法:./ command-e,。/ command -sr,。/ command -pes,但这个不正确./command -pep,。/ command -ssr。不允许重复选项,但至少需要一个选项。
For the same I have used regular expression, but it is not avoiding repetition.
对于同样的我使用正则表达式,但它不是避免重复。
But it is allowing repetition. Please tell what is wring with the expression.
但它允许重复。请告诉我们表达的内容是什么。
[[ $1 =~ ^-[p{0,1}r{0,1}s{0,1}e{0,1}]{1,4}$ ]] || { echo "$MSG_INCORRECT_USAGE"; }
3 个解决方案
#1
1
You can use a script opt.sh
like this to avoid processing each passed option more than once:
您可以像这样使用脚本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
Testing:
测试:
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
1
#!/bin/bash
while getopts "pers" OPTION; do
echo $OPTION
done
Results:
结果:
$ bash test.sh -pers
p
e
r
s
Replace echo $OPTION
with a case
statement and report errors if an option appears twice. Example:
将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
#3
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…
If you need to process the options in the sequence they're given, then you need to record the order in which they arrive. Use an array:
如果您需要按顺序处理选项,则需要记录它们到达的顺序。使用数组:
flags=()
before the loop, and
在循环之前,和
flags+=("$arg")
after the esac
. The processing can then process each element of the $flags
in sequence.
在esac之后。然后,处理可以按顺序处理$标志的每个元素。
for flag in "${flags[@]}"
do
…processing for the particular flag…
done
#1
1
You can use a script opt.sh
like this to avoid processing each passed option more than once:
您可以像这样使用脚本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
Testing:
测试:
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
1
#!/bin/bash
while getopts "pers" OPTION; do
echo $OPTION
done
Results:
结果:
$ bash test.sh -pers
p
e
r
s
Replace echo $OPTION
with a case
statement and report errors if an option appears twice. Example:
将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
#3
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…
If you need to process the options in the sequence they're given, then you need to record the order in which they arrive. Use an array:
如果您需要按顺序处理选项,则需要记录它们到达的顺序。使用数组:
flags=()
before the loop, and
在循环之前,和
flags+=("$arg")
after the esac
. The processing can then process each element of the $flags
in sequence.
在esac之后。然后,处理可以按顺序处理$标志的每个元素。
for flag in "${flags[@]}"
do
…processing for the particular flag…
done