Bash:处理群众争论
Bash: handling mass arguments
我希望能够处理给定标志的多个参数,无论标志的顺序是什么。大家觉得这样可以接受吗?有什么改进吗?
所以:
$ ./script -c opt1 opt2 opt3 -b foo
opt1 opt2 opt3
foo
代码:
echo_args () {
echo "$@"
}
while (( $# > 0 )); do
case "" in
-b)
echo
;;
-c|--create)
c_args=()
# start looping from this flag
for arg in ${@:2}; do
[ "${arg:0:1}" == "-" ] && break
c_args+=("$arg")
done
echo_args "${c_args[@]}"
;;
*)
echo "huh?"
;;
esac
shift 1
done
getopts 实用程序应从参数列表中检索选项和选项参数。
$ cat script.sh
cflag=
bflag=
while getopts c:b: name
do
case $name in
b) bflag=1
bval="$OPTARG";;
c) cflag=1
cval="$OPTARG";;
?) printf "Usage: %s: [-c value] [-b value] args\n" [=10=]
exit 2;;
esac
done
if [ ! -z "$bflag" ]; then
printf 'Option -b "%s" specified\n' "$bval"
fi
if [ ! -z "$cflag" ]; then
printf 'Option -c "%s" specified\n' "$cval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
注意准则 8:
当指定多个选项参数跟在一个选项之后时,它们应该作为单个参数显示,在该参数中使用逗号或在该参数中使用 分隔它们。
$ ./script.sh -c "opt1 opt2 opt3" -b foo
Option -b "foo" specified
Option -c "opt1 opt2 opt3" specified
Remaining arguments are:
标准链接如下:
我在评论中注意到您不想使用其中任何一个。您可以做的是将所有参数设置为一个字符串,然后使用循环对它们进行排序,取出您想要设置为已切换的参数并使用 if 语句对它们进行排序。虽然有点野蛮,但是可以做到。
#!/bin/bash
#set all of the arguments as a variable
ARGUMENTS=$@
# Look at each argument and determine what to do with it.
for i in $ARGUMENTS; do
# If the previous loop was -b then grab the value of this argument
if [[ "$bgrab" == "1" ]]; then
#adds the value of -b to the b string
bval="$bval $i"
bgrab="0"
else
# If this argument is -b, prepare to grab the next argument and assign it
if [[ "$i" == "-b" ]]; then
bgrab="1"
else
#Collect the remaining arguments into one list per your example
RemainingArgs="$RemainingArgs $i"
fi
fi
done
echo "Arguments: $RemainingArgs"
echo "B Value: $bval"
我在我的很多脚本中都使用了类似的东西,因为有大量的参数可以输入其中的一些,脚本需要查看每个参数以确定要做什么。它们可能出现故障或根本不存在,但代码仍然必须有效。
我希望能够处理给定标志的多个参数,无论标志的顺序是什么。大家觉得这样可以接受吗?有什么改进吗?
所以:
$ ./script -c opt1 opt2 opt3 -b foo
opt1 opt2 opt3
foo
代码:
echo_args () {
echo "$@"
}
while (( $# > 0 )); do
case "" in
-b)
echo
;;
-c|--create)
c_args=()
# start looping from this flag
for arg in ${@:2}; do
[ "${arg:0:1}" == "-" ] && break
c_args+=("$arg")
done
echo_args "${c_args[@]}"
;;
*)
echo "huh?"
;;
esac
shift 1
done
getopts 实用程序应从参数列表中检索选项和选项参数。
$ cat script.sh
cflag=
bflag=
while getopts c:b: name
do
case $name in
b) bflag=1
bval="$OPTARG";;
c) cflag=1
cval="$OPTARG";;
?) printf "Usage: %s: [-c value] [-b value] args\n" [=10=]
exit 2;;
esac
done
if [ ! -z "$bflag" ]; then
printf 'Option -b "%s" specified\n' "$bval"
fi
if [ ! -z "$cflag" ]; then
printf 'Option -c "%s" specified\n' "$cval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
注意准则 8:
当指定多个选项参数跟在一个选项之后时,它们应该作为单个参数显示,在该参数中使用逗号或在该参数中使用
$ ./script.sh -c "opt1 opt2 opt3" -b foo
Option -b "foo" specified
Option -c "opt1 opt2 opt3" specified
Remaining arguments are:
标准链接如下:
我在评论中注意到您不想使用其中任何一个。您可以做的是将所有参数设置为一个字符串,然后使用循环对它们进行排序,取出您想要设置为已切换的参数并使用 if 语句对它们进行排序。虽然有点野蛮,但是可以做到。
#!/bin/bash
#set all of the arguments as a variable
ARGUMENTS=$@
# Look at each argument and determine what to do with it.
for i in $ARGUMENTS; do
# If the previous loop was -b then grab the value of this argument
if [[ "$bgrab" == "1" ]]; then
#adds the value of -b to the b string
bval="$bval $i"
bgrab="0"
else
# If this argument is -b, prepare to grab the next argument and assign it
if [[ "$i" == "-b" ]]; then
bgrab="1"
else
#Collect the remaining arguments into one list per your example
RemainingArgs="$RemainingArgs $i"
fi
fi
done
echo "Arguments: $RemainingArgs"
echo "B Value: $bval"
我在我的很多脚本中都使用了类似的东西,因为有大量的参数可以输入其中的一些,脚本需要查看每个参数以确定要做什么。它们可能出现故障或根本不存在,但代码仍然必须有效。