1. 读取和测试命令行参数:
#!/bin/bash if [ -n "$1" ] #必须先测试参数是否读入(即命令行上是否真正传了参数),使用""括起来,参数允许是含有空格的字符串 #如果使用了未读入的参数会报错! then echo Have read it! else echo "Can't identify it!" fi fac=1 for (( n = 1; n <= $1; n++ ))#计算阶乘 do fac=$[ $fac * $n ] done echo $fac其中环境变量$0表示命令名本身,$1 ~ $9表示接下来的1到9个命令行参数
2. 读取多个命令行参数:
#!/bin/bash echo The first parameter is $1 echo The second parameter is $2 echo The conduct is $[ $1 * $2 ] #计算两个参数的乘积
#!/bin/bash #如果参数字符串含有空格,则在输入命令的时候将含有空格的字符串用''或""括起来即可 echo Hello, $1!
#!/bin/bash #超过第9号参数之后的参数引用的时候使用${}形式就行了 #通过这种方法可以读取任意多个参数 echo The tenth parameter is ${10} echo The eleventh parameter is ${11}
#!/bin/bash echo The command entered is: $0 #命令行输入的名称如何输出就是如何 echo The command entered is: `basename $0` #获取文件的基名,可以去掉前面的路径只包含文件名本身
6. 利用环境变量$#获取参数的个数(但是不包括$0):
#!/bin/bash for (( i = 1; i <= $#; i++ )) do echo $i done一个简单的应用:
#!/bin/bash if [ $# -ne 2 ] #如果错误的输入参数则提醒如何正确使用 then echo Usage: test a b else echo $[ $1 + $2 ] #正确输入则输出求和 fi
#!/bin/bash echo ${!#} #获取最后一个参数 a=3 echo ${!a} #获取第三个参数 for (( i = 1; i <= $#; i++ )) #打印所有参数 do echo ${!i} done
8. 迭代命令行参数:
#!/bin/bash echo \$*: $* echo \$@: $@ #这两种方法(即$@和$*不用""括起来) #则迭代时无视用命令输入时的"",即使是""里面的空格也会被当成参数的分隔符 for x in $* do echo $x done echo "*********" for x in $@ do echo $x done #会将整个命令行的所有参数当成一个迭代值 echo "*********" for x in "$*" do echo $x done #将命令行参数逐个迭代,并将""括起来的参数视作一个迭代值(包括""中的空格) #推荐使用!!! echo "*********" for x in "$@" do echo $x done #同上 echo "*********" for (( i = 1; i <= $#; i++ )) do echo ${!i} done
9. 使用shift命令来移动参数:
#!/bin/bash while [ -n "$1" ] do echo $1 shift #不带参数默认将所有参数左移一位,这样$4变成#3,$3变成$2,而$1将被永久丢弃(即被删除,不可恢复),但$0始终不会变,永远都是命令名 done while [ -n "$1" ] do echo $1 shift 2 #一次左移两个参数 done
10. 标准的命令行格式和getopt命令:
标准的命令行格式为:命令名 [-选项1 选项1的参数列表] [-选项2 选项2的参数列表].. -- 参数1 参数2
同时也支持多个选项的合并,比如-abc
getopt命令可以让输入的乱七八糟的命令格式化成标准形式:
#!/bin/bash #首先getopt的第一个参数是一个字符串optstring #其中定义了所有的命令选项,共有abcde这5种选项 #其中:表示选项b后面带一个选项参数,只能是一个,如果输入命令的时候有多个会出问题 #下一个参数就是命令输入时的选项和参数的字符串 echo `getopt ab:cde -ab sdf -cdef dsf "sdfk sdf" 1 23424` #输出为-a -b sdf -c -d -e -- dsf sdfk sdf 1 23424 #--用以分隔选项部分和参数部分
#!/bin/bash set -- `getopt -q ab:cde "$@"` #利用set命令将原始命令行参数的值替换成格式化后的值 #在Linux中如果输入了不存在的选项,则在使用getopt进行格式化时会报错 #提示你使用了不存在的非法选项,但是无论如何getopt命令最终转化后的标准形式 #都是忽略不存在的选项的,因此可以给getopt命令添加一个选项-q使其不输出错误信息 #即set -- `getopt -q ab:cde "$@"` while [ -n "$1" ] do case "$1" in -a) echo Found the -a option;; -b) echo Found the -b option, with parameter $2 shift;; #需要额外shift掉选项参数 -c) echo Found the -c option;; -d) echo Found the -d option;; -e) echo Found the -e option;; --) shift #getopt会化成标准命令行参数形式,以--作为选项和参数的间隔 break;; #表示选项部分已经读取完毕,跳出循环接着读取参数部分 *) echo $1 is not an option;; #getopt会自动忽略不存在的选项,因此这条语句多余,放在这里只是做一个提醒! esac shift done cnt=1 while [ -n "$1" ] do echo Parameter $cnt: $1 cnt=$[ $cnt + 1 ] shift done
$ bash test.sh -afcb 3224 -de sdkjf 234 ssD #output: getopt: illegal option -- f Found the -a option Found the -c option Found the -b option, with parameter 3224 Found the -d option Found the -e option Parameter 1: sdkjf Parameter 2: 234但遗憾的是getopt不擅长处理带空格的参数,比如"sdf sdf"getopt会将其当成sdf和sdf两个参数处理而忽略""的作用
12. 使用while和更高级的getopts命令来j解析命令行参数:
getopts更高级的地方:
1)解析完选项部分之后原始命令行参数字符串的值不会改变;
2)可以识别参数中的空格(参数字符串中含有空格);
3)支持选项和选项参数连起来写;
4)对于不存在的(非法的)选项会解析成一个?符号供程序员判断,而不是自动忽略;
#!/bin/bash #当选项部分全部解析完之后getopts命令会返回非0码农而自动退出循环 #将剩下的参数部分留给你处理 #并且循环过程中不需要shift,这就意味着循环退出后并不会影响原始的命令行参数值 #两个环境变量,$OPTIND表示当前处理到了几号参数,如果选项和选项参数写在一起则会当成一个,分开则会当成两个参数 #getopts命令会将每次解析出来的选项存入自定义的变量opt中,而选项参数则存入环境变量$OPTARG中 #getopts的第一个参数仍然是optstring,意义和getopt命令的optstring参数一样,只不过如果在开头加一个:的效果和getopt的-q选项一样,都表示忽略非法的选项 while getopts :ab:c opt do echo $OPTIND case $opt in a) echo Found the -a option;; #第一个和getopt不一样的地方,解析后会去掉-符号 b) echo Found the -b option, with value $OPTARG;; c) echo Found the -c option;; *) echo Unknown option: $opt;; #对于非法的选项会返回一个符号?并且$OPTIND不做计数 esac done shift $[ $OPTIND - 1 ] #选项解析后$OPTIND停留在选项之后的第一个参数上,所以要左移OPTIND - 1位从而将选项部分去掉 echo "********" for var in "$@" do echo $var done
$ bash test.sh -axbsdf134 -c sdkf 234 sfd iii "45sd xxxx" #这里体现出了getops的三大新亮点 #output: 1 Found the -a option 1 Unknown option: ? #一:对于不存在的(即非法的)选项将返回字符? 2 Found the -b option, with value sdf134 #二:对于选项字母和选项参数写在一起的也能解析 3 Found the -c option #选项部分解析完之后getopts命令能返回大于0的状态码而自动退出while循环 ******** sdkf 234 sfd iii 45sd xxxx #三:参数中多个连续的空格会当成一个空格,这里getopts对空格敏感