知识体系:
#使用命令行参数
#设置选项
#获取用户输入
有时编写的脚本需要能和运行脚本的人员进行交互,bash shell提供了一些方法来从用户处获取数据,这些方法有如下三种:
1- 命令行参数(添加在命令后的参数)
2- 命令行选项(修改命令行为的单字符串)
3- 直接读取键盘输入
1、命令行参数
向shell脚本传递数据最基本的方式就是命令行参数,主要就是说通过一些特殊变量是的bash shell自动把输入的参数赋值给变量才执行脚本。这些变量叫做位置参数,分别有$1为第一个参数、$2为第二个参数、$0为程序名称。。。
1.1、读取参数
如下看个例子就能理解这个位置参数的概念了:
[root@ ~]# chmod u+x 1.1test
[root@ ~]# cat 1.1test
#!/bin/bash
a=1
for (( b=1; b<=$1; b++ ))
do
a=$[ $a * $b ]
done
echo the factorial of $1 is $a
[root@ ~]# ./1.1test 5
the factorial of 5 is 120
[root@ ~]# ./1.1test 4
the factorial of 4 is 24
主要来看./xx后面附带的命令行参数,只有一个参数也即为第一个参数很明显赋值为$1,通过for循环计算出累乘结果,所以你输入的第一个参数值改变了,结果也就随着改变。
如果要输入更多的命令行参数,那么每个命令行参数必须使用空格分隔出来,下面看一个例子:
[root@ ~]# cat 1.1test
#!/bin/bash
total=$[ $1 * $2 ]
echo the first param is $1
echo the second param is $2
echo the total value is $total
[root@ ~]# ./1.1test 2 3
the first param is 2
the second param is 3
the total value is 6
[root@ ~]# ./1.1test 4 7
the first param is 4
the second param is 7
the total value is 28
如上脚本很容易理解,我们看到2/3和4/7都分别被赋值给$1和$2,这里就是通过命令行参数之间的空格分开实现的。当然,数值可以给赋值,对于文本字符串也是可以的,如果要将出现空格的连于一体的参数值可以通过单引号或者双引号括起来,这样bash shell就将其视为一个参数值,先来看个例子:
[root@ ~]# cat 1.1test
#!/bin/bash
echo hello $1,glad to meet you.
[root@ ~]# ./1.1test linuxidc gdin
hello linuxidc,glad to meet you.
[root@ ~]# ./1.1test 'netease corporation'
hello netease corporation,glad to meet you.
对于脚本中没有附带$2变量则把gdin参数忽略了。
还有一点必须说明的:
如果脚本输入的命令参数多于9个,就必须使用大括号把变量括起来,如{10},来看个例子:
[root@ ~]# cat 1.1test
#!/bin/bash
total=$[ ${10} + ${11} ]
echo the tenth param is ${10}
echo the eleventh param is ${11}
echo the total is $total
[root@ ~]# ./1.1test 1 2 3 4 5 6 7 8 9 10 11
the tenth param is 10
the eleventh param is 11
the total is 21
对于这样的结果很好理解,只要注意下{10+}这个东东就行了!
1.2、读取程序名称
一开始我就在上面提到程序名称用$0即可表示,Ok,先看个例子:
[root@ ~]# chmod u+x 1.2test
[root@ ~]# cat 1.2test
#!/bin/bash
echo the name of the program is:$0
[root@ ~]# ./1.2test
the name of the program is:./1.2test
[root@ ~]# /root/1.2test
the name of the program is:/root/1.2test
很明显,得出的结果不是我们要的,我们只要输出1.2test这个结果。它所传递的变量$0的字符串是程序的完整路径,而不是名称,这里我们可以通过basename命令实现只返回程序名称,把脚本修改成如下:
[root@ ~]# cat 1.2test
#!/bin/bash
name=`basename $0`
echo the name of the program is:$name
[root@ ~]# ./1.2test
the name of the program is:1.2test
[root@ ~]# $HOME/1.2test
the name of the program is:1.2test
呵呵,这下通过basename实现我们要的结果,有点注意的是使用反单引号来给name赋值,否则命令无法生效!
通过基于使用脚本的名称可以实现执行不同功能,下面看个例子:
[root@ ~]# cp 1.2test linuxidc
[root@ ~]# ln -s 1.2test netease
[root@ ~]# ls -l 1.2test linuxidc netease
-rwxr--r-- 1 root root 179 02-13 11:21 1.2test
-rwxr--r-- 1 root root 179 02-13 11:22 linuxidc
lrwxrwxrwx 1 root root 7 02-13 11:22 netease -> 1.2test
[root@ ~]# cat 1.2test
#!/bin/bash
name=`basename $0`
if [ $name = "linuxidc" ]
then
echo $name is a great IT community
elif [ $name = "netease" ]
then
echo $name is a great internet-sp corparation
fi
[root@ ~]# ./linuxidc
linuxidc is a great IT community
[root@ ~]# ./netease
netease is a great internet-sp corparation
上面的例子通过脚本名称实现了不同内容的输出,可知basename好用啦!
脚本是先判断basename,然后根据basename执行函数。
1.3、测试参数
在shell脚本中使用命令行参数要小心,如果执行脚本缺少必要的参数,则会出现报错信息,如下:
[root@ ~]# cat 1.1test
#!/bin/bash
total=$[ ${10} + ${11} ]
echo the tenth param is ${10}
echo the elevnth param is ${11}
echo the total is $total
[root@ ~]# ./1.1test
./1.1test: line 2: + : syntax error: operand expected (error token is " ")
the tenth param is
the elevnth param is
the total is
我们不输入任何命令行参数,则脚本无法执行。
所以,我们可以通过-n这个参数进行检测:
[root@ ~]# cat 1.2test
#!/bin/bash
if [ -n "$1" ]
then
echo $1 exists !
else
echo your inputting is wrong
fi
[root@ ~]# ./1.2test twentyfour
twentyfour exists !
[root@ ~]# ./1.2test
your inputting is wrong
由此可见,通过该方法是检测参数是否存在的好方法。