Key words 命令行参数、    特殊的参数变量   、获取用户输入: read  
 
我们编写的脚本有时候需要与运行脚本的人进行互交,bash shell提供了三种不同的办法来获取用输入的数据: 命令行参数(添加在命令后面的数据值)、 命令行选项(修改命令行为的单字符值)和 直接读取键盘输入
一、命令行参数
1 、读取参数
       bash shell 将在命令行中输入的所有参数赋值给一些特殊变量,这些变量叫位置参数。位置参数通过标准数字表示,其中 $0 为程序名称, $1 为第一个参数, $2 为第二个参数,以此类推,一直到第九个参数。如果脚本需要的命令行参数多于 9 个,后面的变量名要用这种写法: $ 10
例: 读取参数
[root@localhost ~]# cat test
#!/bin/bash
total=$[ $1 + $2 ]
echo the first paramerer is $1
echo the second paramerer is $2
echo the result is $total
 
[root@localhost ~]# ./test 1 5
the first paramerer is 1
the second paramerer is 5
the result is 6
[root@localhost ~]# cat test     
#!/bin/bash
total=$[ ${10} + ${12} ]
echo the first paramerer is $1
echo the second paramerer is $2
echo the result is $total
如果某个变量内容有字符,需要用单引号把变量内容括起来
[root@localhost ~]# ./test 'New York' 2 3 4 5 6 7 8 9 10 11 12
the first paramerer is New York
the second paramerer is 2
the result is 22
 
读取程序名称:
[root@localhost ~]# cat test                  
#!/bin/bash
echo "the filename is $0 "                  默认读取的是程序的完整路径而不仅是程序的文件名
[root@localhost ~]# ./test
the filename is ./test
[root@localhost ~]# /root/test
the filename is /root/test
使用basename命令可以实现只返回程序名称,这样就可以编写基于脚本名称来执行不同功能的脚本
[root@localhost ~]# cat test
#!/bin/bash
name=`basename $0`             后引号
if [ $name = "wzp" ]
then
 total=$[ $1 + $2 ]
elif [ $name = "wlt" ];then
 total=$[ $1 * $2 ]
fi
echo "the result is $total"
[root@localhost ~]# cp test wlt
[root@localhost ~]# ln -s test wzp
[root@localhost ~]# ./wlt 4 5
the result is 20
[root@localhost ~]# ./wzp 4 5
the result is 9
 
二、特殊的参数变量
bash shell 中有一些特殊的变量可以跟踪命令行参数,例如参数计数、获取所有数据
1、参数计数  $#
如上例,在脚本中添加命令 $# 就可以算出输入了多少个参数
[root@localhost ~]# cat test
#!/bin/bash
echo there were $# parameters supplied
name=`basename $0`
if [ $name = "wzp" ]
then
 total=$[ $1 + $2 ]
elif [ $name = "wlt" ];then
 total=$[ $1 * $2 ]
fi
echo "the result is $total"
[root@localhost ~]# ./wzp 1 2 3 4 5 6 7 8 9 11 12 13          wzp test 的软连接
there were 12 parameters supplied
the result is 3
如果想获取最后一个参数,可以用 ${!#}
把上个例子红色那行改为    the last parameteris ${!#}
结果会变成:
[root@localhost ~]# ./wzp 1 2 3 4 5 6 7 8 9 11 12 13
the last parameteris 13
the result is 3
 
三、获取用户输入
read 命令接受标准输入(键盘)或其他文件描述符的输入,得到输入后 read 将数据放入设定的标准变量中。
1 基本读取:
例:
[root@localhost ~]# cat test
#!/bin/bash
echo -n "please enter your age:"
read age
days=$[ $age * 365 ]
echo "that makes you over $days days old!"
[root@localhost ~]# ./test
please enter your age:22
that makes you over 8030 days old!
-n 表示允许脚本用户在字符串后面直接输入数据而不用在下一行输入,保持脚本整齐。
echo -n "please enter your age:"
read age          
  这两句可以用一句代替: read -p    "please enter your age:"  age
有两个以上的变量,并且变量变量值存在空格怎么办呢?下面这个例子是错误示范:
[root@localhost ~]# cat test
#!/bin/bash
read -p "please enter your name and age:" name age
days=$[ $age * 365 ]
echo "hei,$name ,you are $age years old"
echo "that makes you over $days days old!"
[root@localhost ~]# ./test
please enter your name and age:"liting wen" 22
./test: line 3: wen" 22 * 365 : syntax error: invalid arithmetic operator (error token is "" 22 * 365 ")
hei,"liting ,you are wen" 22 years old
that makes you over days old!
read 以空格作为变量值的分隔符,上面那个例子应该这样写:
[root@localhost ~]# cat test
#!/bin/bash
read -p "please enter your name:" name
read -p "please enter your age:" age
days=$[ $age * 365 ]
echo "hei,$name ,you are $age years old"
echo "that makes you over $days days old!"
[root@localhost ~]# ./test
please enter your name:liting wen
please enter your age:22
hei,liting wen ,you are 22 years old
that makes you over 8030 days old!
如果read命令行不指定变量,read命令会将接收到的数据放在环境变量ENPLY中
 
2、计时: -t
read默认一直等待用户输入数据,如果无论是否输入数据脚本都必须继续运行时可以使用 -t 选项来指定
一个计时器。
例:
[root@localhost ~]# cat test
#!/bin/bash
if read -t 5 -p "please enter your name:" name ;then
read -p "please enter your age:" age
days=$[ $age * 365 ]
echo "hei,$name ,you are $age years old"
echo "that makes you over $days days old!"
else  echo "sorry,too slow!"
fi
过了 5 秒没有输入数据就会自动跳过:
[root@localhost ~]# ./test
please enter your name:sorry,too slow!
 
3、计算字符    -n
read命令可以计算输入的字符,当输入的字符数目达到预定数目时,自动退出,并将输入的数据赋值给变量
[root@localhost ~]# cat test
#!/bin/bash
read -n1 -p "do you want to continue?[Y/N]" answer
case $answer in
Y | y) echo
    echo "fine continue on"
   if read -t 10 -p "please enter your name:" name ;then
   read -p "please enter your age:" age
   days=$[ $age * 365 ]
   echo "hei,$name ,you are $age years old"
   echo "that makes you over $days days old!"
   else echo "sorry,too slow!"
   fi ;;
N | n ) echo
      echo OK, goodbye
      exit;;
esac
例子中使用了 -n 选项,后接数字 1 表示 read 命令只要接收到一个字符就退出,并将其传给变量,无需按回车键。
[root@localhost ~]# ./test        
do you want to continue?[Y/N]y
fine continue on
please enter your name:liting wen
please enter your age:11
hei,liting wen ,you are 11 years old
that makes you over 4015 days old!
[root@localhost ~]# ./test
do you want to continue?[Y/N]n
OK, goodbye
 
4、默读 -s
即用户输入的数值不会显示出来,典型的例子是密码的输入
例:
[root@localhost ~]# cat test
#!/bin/bash
read -s -p "enter your password:" passwd
if [ $passwd = 123456 ];then
echo
echo "welcome!"
else
 echo
 echo "sorry,password incorrect"
fi
[root@localhost ~]# ./test
enter your password:
sorry,password incorrect
[root@localhost ~]# ./test
enter your password:
welcome!
 
5、读取文件
例子中while命令使用read命令不断读取文件中的每一行,直到read命令以非零状态退出
[root@localhost ~]# cat test
#! /bin/bash
count=1
cat aa | while read line
do
 echo "Line $count: $line"
 count=$[ $count + 1 ]
done
[root@localhost ~]# cat aa
line 1
line 2
line 3
 
[root@localhost ~]# ./test
Line 1: line 1
Line 2: line 2
Line 3: line 3
Line 4:
[root@localhost ~]#