./script.sh -abc hello
我该如何编写脚本以使用“-abc”作为选项,且将“hello”作为该选项的值?
我应该能够将此值传递给脚本中的所有函数。假设我有两个函数:
X
和Y
。在您的脚本中使用以下代码:
[[ $1 == -abc ]] && value="$2" || echo invalid option
|| echo ...
部分,value
将为空。[[ $1 == -abc ]] && [[ $2 != "" ]] && value="$2" || echo invalid option
使用if else循环可以完全控制这个过程:
if [[ $1 == -abc ]]; then
#if first option is valid then do something here
if [[ $2 != "" ]]; then
value="$2"
else
#if second option is not given then do something here
echo invalid option
fi
else
echo invalid option
#if first option is invalid then do something here
fi
if [[ $1 == -abc && $1 != "" ]]; then
#!/bin/bash
opts=( "$@" )
#if no argument is passed this for loop will be skipped
for ((i=0;i<$#;i++));do
case "${opts[$i]}" in
-abc)
# "${opts[$((i+1))]}" is the immediately follwing option
[[ "${opts[$((i+1))]}" != "" ]] &&
value="${opts[$((i+1))]}"
echo "$value"
((i++))
#skips the nex adjacent argument as it is already taken
;;
-h)
#dummy help option
echo "Options are [-abc value], -h"
;;
*)
#other unknown options
echo invalid option
break
;;
esac
done
-abc value
和 -h
。bash
没有用于处理长参数的内置命令。为了在shell脚本中解析长选项,您需要自己迭代参数列表。
这是一种方法:
#!/bin/sh
is_option_arg () {
case $1 in
-*)
return 1
;;
*)
return 0
;;
esac
}
usage () {
echo "$(basename "$0") -abc ARG -def ARG -verbose"
}
OPT_ABC=
OPT_DEF=
OPT_VERBOSE=false
while [ "$#" -gt 0 ]; do
case $1 in
-abc)
shift
{ [ "$#" -ne 0 ] && is_option_arg "$1"; } || { usage >&2; exit 1; }
OPT_ABC=$1
;;
-def)
shift
{ [ "$#" -ne 0 ] && is_option_arg "$1"; } || { usage >&2; exit 1; }
OPT_DEF=$1
;;
-verbose)
OPT_VERBOSE=true
;;
*)
break
;;
esac
shift
done
echo "OPT_ABC=$OPT_ABC"
echo "OPT_DEF=$OPT_DEF"
echo "OPT_VERBOSE=$OPT_VERBOSE"
if [ "$#" -gt 0 ]; then
echo "Remaining args:"
for arg in "$@"; do
echo "$arg"
done
fi
你几乎必须手动实现它。以下是一种方法:
abc=
while [[ "$1" == -* ]]; do
opt=$1
shift
case "$opt" in
-abc)
if (( ! $# )); then
echo >&2 "$0: option $opt requires an argument."
exit 1
fi
abc="$1"
shift
;;
*)
echo >&2 "$0: unrecognized option $opt."
exit 2
;;
esac
done
echo "abc is '$abc', remaining args: $*"
(0)$ ./script.sh
abc is '', remaining args:
(0)$ ./script.sh hello
abc is '', remaining args: hello
(0)$ ./script.sh -abc hello
abc is 'hello', remaining args:
(0)$ ./script.sh -abc hello there
abc is 'hello', remaining args: there
(0)$ ./script.sh -abc
./script.sh: option -abc requires an argument.
(1)$ ./script.sh -bcd
./script.sh: unrecognized option -bcd.
(2)$
getopt
和getopts
都只能处理单字符选项。你需要通过循环"$@"
来自己解析它。 - Mark Reedgetopt(1)
支持长选项,但要安全使用它需要知道你是否有 util-linux 版本(或者它不支持带空格的选项)。 - Etan Reisner