开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
在编写bash脚本的时候,通过选项传入参数往往可以令我们使用脚本显得更加轻松、简明。下面就介绍一下利用getopt、shift以及case语句解决bash脚本传参的问题。
一、getopt函数
getopt命令是一个在处理命令行选项和参数时非常方便的工具。它能够识别命令行参数,从而在脚本中解析它时更方便。
1.命令的格式
getopt命令可以接受一系列任意形式的命令行选项和参数,并自动将它们转换成适当的格。它的命令格式:
getopt optstring parameters
opstring是这个过程的关键所在。它定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值。
2.下面是最常用的getopt解析方式。
getopt -o SHORT_OPTIONS -l LONG_OPTIONS -n "@"
其中:
-o:SHORT_OPTIONS
--options SHORT_OPTIONS
getopt通过"-o"选项收集命令行传递的短选项和它们对应的参数。
-l LOGN_OPTIONS
--longoptions LONG_OPTIONS
getopt通过-l选项收集命令行传递的长选项和它们对应的参数。可能从的脚本中经常看到--long,是等价的,这个是长选项,长选项只要不产生歧义,是可以进行缩写的。
-n NAME
getopt在解析命令行时,如果解析出错,getopt将使用该NAME作为报错的脚本名称。
--"$@"
其中 -- 表示getopt命令自身的选项到此结束,后面的元素都是要被getopt解析的命令行参数。
3.getopt如何解析选项和参数。
getopt使用"-o"或"-l"解析短、长选项和参数时,将会对每个解析到的选项、参数进行输出,然后不断放进一个字符串中。这个字符串的内容就是完整的、规范化的选项和参数。
getopt使用"-o"选项解析短选项时:
多个短选项可以连在一起
如果某个要解析的选项需要一个参数,则在选项名后面跟一个冒号
如果某个要解析的选项的参数可选,则在选项后面跟两个冒号
例如,getopt -o ab:c::中,将解析为:-a -b arg_b -c [arg_c],arg_b是-b选项必须的,arg_c是-c选项可选的参数,"-a"选项无需参数
getopt使用"-l"选项解析长选项时(同短选项)
二、移动变量shift
在使用shift命令时,默认情况下它会将每个参数变量向左移动一个位置。所以,变量2,变量1,而变量0,也就是程序名,不会改变)
#/bin/bash
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ count + 1 ]
shift
done
bash test.sh 1 2 3 4 5
1)查找选项:
通过case语句以及shift,我们可以实现选项的查找。
#/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) echo "Found the -b option";;
-c) echo "Found the -c option";;
*) echo "$1 is not an option";;
esac
shift
done
bash test.sh -a -b -c
2)参数和选项
遇到shell脚本中同时使用选项和脚本的情况。Linux中处理这个问题的标准方式是用特殊字符将二者分开,该字符会告诉脚本何时选项结束以及普通参数何时开始。
对Linux来说,这个特殊字符就是双破折线(--)。shell会用双破折线来表明选项列表结束。在双破折线之后,脚本就可以放心地将剩下的命令行参数当作参数,而不是选项来处理了。要检查双破折线,只要在case中加上一项就行了。
#/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) echo "Found the -b option";;
-c) echo "Found the -c option";;
--) shift
break;;
*) echo "$1 is not an option";;
esac
shift
done
count=1
for param in $@
do
echo "Parameter #@count:$param"
count=$[ $count + 1 ]
done
bash test.sh -a -b -c -- 1 2 3
3)运用getopt
bash的getopt命令经常用在shell脚本内部或函数内部,用来解析脚本执行或函数执行时传递的选项、参数。
getopt解析选项时要做的许多事情之一是重新排列参数,以便非选项参数排在最后,并且组合的空头选项被拆分。
这种效果反映在您的代码中,其中选项处理循环假定所有选项参数(包括选项的参数)首先出现,然后分别出现,最后是非选项参数。因此,TEMP包含重新排列、引用、拆分的选项,并使用eval set使它们成为脚本参数。
至于shift,它会做它一直做的事情:删除第一个参数,并移动所有参数(因此1)。这消除了已处理的参数,因此,在此循环之后,只剩下非选项参数,您可以方便地使用$@而不必担心选项。
set -e
ARGS=`getopt -o b:c:a: -n '1.sh' -- "$@" `
if [ $? != 0 ];then
echo "Terminating..."
exit 1
fi
#echo $ARGS
#gui fan hua ming ling hang can shu
eval set -- "${ARGS}"
while true
do
case "$1" in
-a)
echo "Option a ,argument $2";
shift 2
;;
-b)
echo "Option b,argument $2";
b=$2
shift 2
;;
-c)
case "$1" in
"")
echo "Option c,no argument";
shift 2
;;
*)
echo "Option c,argument $2";
shift 2
;;
esac
;;
--)
shift
break
;;
*)
echo "Internal error!!!"
exit 1
;;
esac
done
bash test.sh -a 1 -b 2 -c 3