shell脚本中如何获取命令的参数(2) ----处理命令参数

时间:2021-08-27 16:26:19


 1    找出选项

    1.1 处理简单选项

            主要可以通过shfit工具对获取的到$1变量对比程序允许的变量值判断;

shell脚本中如何获取命令的参数(2) ----处理命令参数




  1.2  从参数中分离选项

   一般参数可能在后面跟上适当的参数值,例如 sed   -f script  data

所有如何把选项的参数与选项有效的分隔开也是一种很重要的技能,我们可以限制命令后面的规定格式,虽然没有很大的灵活性,但是它却解决了我们的问题,在linux当中用(--)这个特殊字符来表示选项的结束,参数项开始

shell脚本中如何获取命令的参数(2) ----处理命令参数

下面进阶一点,讨论一下如何获取带值的选项

1.3 处理带值的选项

这个步骤主要是让我们脚本能够处理形如:./test   -a test1 -b -c -d test2

这就得要求脚本呢必须能够检测命令行选项合适需要附加参数,并能够进行处理,下面的例子可以很好展示如何解决这类问题;


shell脚本中如何获取命令的参数(2) ----处理命令参数


2 使用命令

getopt命令可以接受任意形式的命令行参数,在处理命令行选项和参数时非常方便

命令格式: getopt options optstring parameters    

其中选项字符串是处理的关键,它定义命令行中有效选项字母,它还定义哪些选项字母需要参数值

首先,在选项字符串中列出将在脚本中用到的每个命令行选项字母。然后,在每个需要参数值的选项字母后面放置一个冒号。getopt命令根据定义的选项字符串解析提供的参数

请看下面的getopt示例:

$ getopt  ab:cd  -a -b test1 -cd test2 test3

 -a -b test1 -c -d -- test2 test3

$

可见经过getopt的处理得到了规整的参数列表,注意它自动的把-cd 分为-c ,-d ,并插入破折号来分隔行中额外的参数

如果提供的参数不在optstring当中,getopt会给予提示出错信息

jiangjian@jiangjian-K42JZ:~/sh$ getopt ab:cd -a -b test1 -e -cd test2 test3
getopt:无效选项 -- e
 -a -b test1 -c -d -- test2 test3
jiangjian@jiangjian-K42JZ:~/sh$


如果希望忽略这个错误信息,可以在命令中使用-q选项

jiangjian@jiangjian-K42JZ:~/sh$ getopt -q ab:cd -a -b test1 -e -cd test2 test3
 -a -b 'test1' -c -d -- 'test2' 'test3'
jiangjian@jiangjian-K42JZ:~/sh$


现在介绍如何在脚本中使用getopt

这里存在一个技巧

set命令的一个选项是双破折号,表示将命令行参数变量替换为set命令的命令行中的值

set  --  `getopt -q ab:cd "$@"`

按照上面的技巧我们试着编写一个:

jiangjian@jiangjian-K42JZ:~/sh$ cat test60.sh
#!/bin/bash
set -- `getopt -q ab:c "$@"`
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) param="$2"
echo "Found the -b option with parameter value $param"
shift ;;
-c) echo "Found the -c option";;
--) shift
break;;
*) echo "$1 is not option "
esac
shift
done

count=1
for param in "$@"
do
echo "Parameter #$count:$param"
count=$[$count + 1]
done
jiangjian@jiangjian-K42JZ:~/sh$ ./test60.sh -a -b test10 -c -d 1 2 3
Found the -a option
Found the -b option with parameter value 'test10'
Found the -c option
Parameter #1:'1'
Parameter #2:'2'
Parameter #3:'3'
jiangjian@jiangjian-K42JZ:~/sh$


getopts命令

不同于getopt,getopts每次获取参数列表当中的一个合法项,当处理完最后的即返回一个大于0 的退出状态

格式:getopts   optstring  variable

optstring和getopt大致相同,主要区别在与禁止输出错误信息,这里直接在optstring前面加一个冒号:


其中每次返回的值存放在variable当中,可以用于for循环当中迭代,getopts当中使用两个环境变量,环境变量OPTARG中包含需要参数值选项要使用的值,环境变量OPTIND 包含的值表示getopts停止处理时在参数列表中的位置,这样,处理完选项后可以继续处理其他命令行参数。


jiangjian@jiangjian-K42JZ:~/sh$ cat test61.sh
#!/bin/bash

while getopts :ab:c opt
do
case "$opt" in
a) echo "Found -a option";;
b) echo "Found -b option,with value $OPTARG";;
c) echo "Found -c option";;
*) echo "$opt is unknown option";;
esac
done
jiangjian@jiangjian-K42JZ:~/sh$ ./test61.sh -a -b test1 -c
Found -a option
Found -b option,with value test1
Found -c option
jiangjian@jiangjian-K42JZ:~/sh$

必须注意上面的case选项中不在包括(-)

getopts会自动处理未定义的参数

jiangjian@jiangjian-K42JZ:~/sh$ ./test61.sh -a -b test1 -c -d
Found -a option
Found -b option,with value test1
Found -c option
? is unknown option

jiangjian@jiangjian-K42JZ:~/sh$


另外getopts知道合适停止处理选项,将参数选项交给您处理。getopts每个处理选项,环境变量OPTIND的值都会增加1,当达到getopts处理的末尾时,可以使用shift命令和OPTIND值进行操作来移动到参数;

实例如下:

jiangjian@jiangjian-K42JZ:~/sh$ cat test62.sh
#!/bin/bash
while getopts :ab:cd opt
do
case "$opt" in
a) echo "Found the -a option";;
b) echo "Found the -b option,with vale $OPTARG";;
c) echo "Found the -c option";;
d)echo "Found the -d option";;
*)echo "$1 is not an option";;
esac
done
shift $[$OPTIND - 1]
count=1
for parameter in $@
do
echo "Patameter #$count:$parameter"
count=$[$count + 1]
done
jiangjian@jiangjian-K42JZ:~/sh$ ./test62.sh -a -b test1 -c -d 1 2 3 4
Found the -a option
Found the -b option,with vale test1
Found the -c option
Found the -d option
Patameter #1:1
Patameter #2:2
Patameter #3:3
Patameter #4:4
jiangjian@jiangjian-K42JZ:~/sh$