我试图创建一个脚本这将有可选选项的标志。使用getopts可以在标志后面指定一个强制参数(使用冒号),但我想保留它为可选。如何创建带有可选参数的bash脚本的一个标志
这将是这样的:
./install.sh -a 3
或
./install.sh -a3
其中 'a' 是标志和 '3' 是个遵循可选参数。
在此先感谢。
我试图创建一个脚本这将有可选选项的标志。使用getopts可以在标志后面指定一个强制参数(使用冒号),但我想保留它为可选。如何创建带有可选参数的bash脚本的一个标志
这将是这样的:
./install.sh -a 3
或
./install.sh -a3
其中 'a' 是标志和 '3' 是个遵循可选参数。
在此先感谢。
getopt
exter nal程序允许选项通过向选项名称添加双冒号来获得单个可选参数。
# Based on a longer example in getopt-parse.bash, included with
# getopt
TEMP=$(getopt -o a:: -- "[email protected]")
eval set -- "$TEMP"
while true ; do
case "$1" in
-a)
case "$2" in
"") echo "Option a, no argument"; shift 2 ;;
*) echo "Option a, argument $2"; shift 2;;
esac ;;
--) shift; break ;;
*) echo "Internal error!"; exit 1 ;;
esac
done
使用getopt的功能。在大多数系统中,man getopt
将产生文档它,甚至在脚本中使用它的例子。从我系统上的手册页:
以下代码片段显示了如何处理参数 以获取可以采用选项-a和-b以及需要参数的选项-o, 的命令。
args=`getopt abo: $*`
# you should not use `getopt abo: "[email protected]"` since that would parse
# the arguments differently from what the set command below does.
if [ $? != 0 ]
then
echo 'Usage: ...'
exit 2
fi
set -- $args
# You cannot use the set command with a backquoted getopt directly,
# since the exit code from getopt would be shadowed by those of set,
# which is zero by definition.
for i
do
case "$i"
in
-a|-b)
echo flag $i set; sflags="${i#-}$sflags";
shift;;
-o)
echo oarg is "'"$2"'"; oarg="$2"; shift;
shift;;
--)
shift; break;;
esac
done
echo single-char flags: "'"$sflags"'"
echo oarg is "'"$oarg"'"
此代码将接受任何以下作为等效的:
cmd -aoarg file file
cmd -a -o arg file file
cmd -oarg -a file file
cmd -a -oarg -- file file
在bash有一些隐变量:
$#: contains number of arguments for a called script/function
$0: contains names of script/function
$1: contains first argument
$2: contains second argument
...
$n: contains n-th argument
例如:
#!/bin/ksh
if [ $# -ne 2 ]
then
echo "Wrong number of argument - expected 2 : $#"
else
echo "Argument list:"
echo "\t$0"
echo "\t$1"
echo "\t$2"
fi
的问题是问如何定义其参数也是可选的选项。 – chepner 2013-03-20 13:36:50
是的,我更愿意向他解释如何去争辩,而不是给他一个完整的答案。有时候它更适合某人自己找到路...顺便说一句,你的答案应该得到-1,因为你的“虽然是真的”...... – 2013-03-20 13:38:44
@binogure'while true'本身没有错 - 需要是一个终止条件,但这可以是一个'休息'。 – 2013-03-20 13:57:02
我的解决办法:
#!/bin/bash
count=0
skip=0
flag="no flag"
list=([email protected]) #put args in array
for arg in [email protected] ; do #iterate over array
count=$(($count+1)) #update counter
if [ $skip -eq 1 ]; then #check if we have to skip this args
skip=0
continue
fi
opt=${arg:0:2} #get only first 2 chars as option
if [ $opt == "-a" ]; then #check if option equals "-a"
if [ $opt == $arg ] ; then #check if this is only the option or has a flag
if [ ${list[$count]:0:1} != "-" ]; then #check if next arg is an option
skip=1 #skip next arg
flag=${list[$count]} #use next arg as flag
fi
else
flag=${arg:2} #use chars after "-a" as flag
fi
fi
done
echo $flag
以下是没有getopt
,它需要一个可选的参数与-a标志:
for WORD; do
case $WORD in
-a?) echo "single arg Option"
SEP=${WORD:2:1}
echo $SEP
shift ;;
-a) echo "split arg Option"
if [[ ${2:0:1} != "-" && ${2:0:1} != ""]] ; then
SEP=$2
shift 2
echo "arg present"
echo $SEP
else
echo "optional arg omitted"
fi ;;
-a*) echo "arg Option"
SEP=${WORD:2}
echo $SEP
shift ;;
-*) echo "Unrecognized Short Option"
echo "Unrecognized argument"
;;
esac
done
其他选项/标志也可以很容易地添加。
执行:'./install.sh -a 3'给出了“选项a,没有argment”但参数是“3” – Alepac 2013-03-20 14:00:39
'getopt'似乎没有以允许选项和其可选参数之间的空格。 – chepner 2013-03-20 14:44:07
从'man getopt':“如果选项有可选参数,则必须在选项字符后面直接写入(如果存在)。” – l0b0 2013-03-20 16:46:20