shell脚本编程基础第二篇
 read命令
 使用read来把输入的值非配给一个或者多个shell变量,可以提示用户输入一些参数等,此时我们可以使用read命令来完成此功能
 read [选项] [名称]
 read -p 指定要显示的提示信息
 read -t 声明超时
 注意:1 当我们写完一个脚本后,需要对脚本进行语法检查,如果发现语法不对,我们可以进行修改,
 语法检测命令:bash -n /path/to/some_scripts
     2  完成语法测试后,还可以进行功能测试,可以说是调试,也可以加上执行权限后运行,可以通过bash所提供的调试功能来进行运行测试
     运行调试命令:bash -x /path/to/some_scripts
    
 read 从标准输入中读取值,给每一个单词分配一个变量,所有剩余的单词都被分配给最后一个变量
 read -p "who ar you?:" file

   
 流程控制
 过程式编程语言:
               顺序执行   按照顺序一条一条的语句执行
               选择执行   按照条件进行选择执行
               循环执行   按照给定的循环条件进行循环执行
 其中的顺序执行不需要特定的控制,只需要按照语句依次执行即可;
 选择执行,则需要特定的控制语句 例如 if、case 来判断选择执行;
 循环执行,则需要特定的循环控制体来控制 例如 for、while
 
 条件选择if语句     if语句可以嵌套
        选择执行:
           单分支:if 判断条件;then      语句开头
                      条件为真的分支代码
                   fi                    语句结尾
           双分支:if 判断条件;then      语句开头
                      条件为真的分支代码
                   else
                       条件为假的分支代码
                   fi                    语句结尾
       多分支结构:if 命令1;then         语句开头
                      if-true  
                   elif 命令2;then
                      if-true
                   elif 命令3;then
                      if-true
                   else
                       all-false
                    fi                    语句结尾
           逐条件进行判断,第一次遇到为真条件时,执其他分支,而后结束真个if语句
 

条件判断:case语句
           case 变量引用 in
           模式1)
                分支1 命令1
                ;;
           模式2)
                分支2 命令2
                ;;
           *) 
                默认分支
                ;;                          从上到下的进行判断条件
            esac   
           ease 支持 glob风格的通配符
                 *    任意长度任意的字符
                 ?   任意单个字符
                 []   指定范围内的任意单个字符
                 a|b  a或b
   
      
                        shell 脚本 循环
                    
 循环执行   for , while , until
        就是程序按照一定的条件反复进行执行相关操作,知道不在满足循环条件是结束,这里面的重点就是这个循环体
        循环体包括两部分,循环的进入条件和循环的退出条件,两个部分必须同时存在 否则将无法进入循环内部,或者循环无法结束,导致系统崩溃
        重复运行多少次:
                      循环次数事先已知
                      循环次数事先未知
 for循环
        for 变量名 in 列表;do
            循环体
        done
   例如:
        #!/bin/bash
        #user:Compro
        for i in 1 2 3 4;do       
           echo "$i"
        done
        编辑脚本,i是定义的变量名称,1234 是变量的值,然后循环打印输出                       
                                         
执行机制:一次将列表中的元素赋值给“变量名”;每次赋值后即执行一次循环体;知道列表中的元素好近,循环才结束。
列表生成的方式:
              1直接给出列表
              2整数列表:
                       {start...end}  例如:{1..10}
                        seq start step end 例如:$(seq 1 2 10)
              3返回列表的命令:
                            $(命令) 例如:$(ls /var)
位置变量参数:在脚本中用于引用传递给脚本的参数
             $1,$2,,${10},,
    特殊变量:
            $? 保存上一条命令的执行结果成功与否的状态,用数字来表示,0-255; 0表示成功,其他则为失败
            $0 在脚本中用于引用传递脚本名称本身
      $# 保存传递给当前脚本的参数的个数
            $* 保存传递给当前脚本的所有参数
            $@ 保存传递给当前脚本的所有参数    两个在不同的地方用会产生不同的效果
           
 练习
[root@localhost ~]# vim forrc.d.sh
#!/bin/bash
#user:Compro
#  /etc/rc.d/rc3.d 目录下分别有多个以 K 开头和以 S 开头的
# 文件;分别读取每个文件,以 K 开头的文件输出为文件加 stop
# ,以 S 开头的文件输出为文件名加 start ;
for i in `ls /etc/rc.d/rc3.d`     循环定义i为变量名,in之后跟变量的值,也就是ls /etc/rc.d/rc3.d  查看目录的命令
do
        filef1=`echo $i |cut -c1`       定义变量名= 引用上面的变量名i 抽取内容开头第1列
        case $filef1 in                      条件判断,case语句,调用上面的变量filef1
        K)                                          匹配大写K 然后才执行引用的变量值
        echo -e "$i\tstop"                输出引用变量后的结果 后缀加上tstop
        ;;  
        S)                                         匹配大写S 然后才执行引用的变量值
        echo -e "$i\tstart"               输出引用变量后的结果 后缀加上tstart
        ;;
        *)                                         任意长度任意字符
        echo "unkown file"             
        ;;
        esac
done
         

 

[root@localhost ~]# vim shuzizonghe.sh
#!/bin/bash
#user:Compro
#提示输入正整数n的值,计算1+2+3+4+...n的总和
read -p 'please input the number:' n    说明信息,提示信息, 请输入数字
num=`echo $n |grep "^[[:digit:]]\+$"`    定义变量名num = 调用$n的变量,查询开头是数字, \+匹配前面字符至少一次$行尾锚定
if "$num";then                                        判断条件调用上面变量
        if [ $num -eq 0 ];then                     变量值是否等于0
        echo "the umber is 0"                   输入数字为0 则提示这数字为0
        exit                                                  并且退出,不再往下面条件判断
        fi
else
        echo "the number is negative"       如果输入的是负数就提示这条信息
fi
string=0                                                 字符串=0
for i in `seq $n`;do                                定义变量名i 后面列表的seq调后$n的值
        sum=$[$sum+$i]                           定义变量名sum =调后变量 总计 + $i 的数值
        string=$string+$1                         字符串 = 输入的字符串 + 变量1
done
echo "$string=$sum"                           输出结果 为 输出的变量字符串=数值在原有的基础上相加

 

[root@localhost ~]# vim forip.sh
#!/bin/bash
#user:Compro
# 写一个脚本,提示请输入网络地址,如 192.168.0.0 ,判断输入的网段中主机在>线状态
#255.255.255.0
echo -n "IP:"    提示输入IP
read IP          说明信息IP
ipdizi=`echo $IP | cut -d. -f1-3 `.      定义变量名称=调用$IP获取的值 抽取 以.为分隔符 1-3的字符
#
if echo $IP | egrep '\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>' &>/dev/null
then                                                   ip地址扩展表达式
    for i in `seq 200 210`                                    定义变量名i 列表内容为 seq 200 100 之间的数字
    do
        if ping -c 1 -W 1 $ipdizi$i &> /dev/null    调用$ipdizi $i 的值 重定向到文件 不显示出来
        then
            echo -e "$ipdizi$i\tonline"                    显示在线的IP
        else
            echo -e "$ipdizi$i\toffline"                    显示不在线的IP
        fi


[root@localhost ~]# vim for99.sh
#!/bin/bash
#uesr:Compro
#打印99乘法表
for i in `seq 9`              定义变量名i 列表内容为seq 9  生成1-9的数字的行
do
        for o in `seq 1 $i`   定义变量名o 列表内容为 seq 1 $i   1循环到 $i变量值  第1行就打印1遍,第2行就打印2遍,,,
        do
                echo -ne "$i*$o=$(($i*$o))\t"     $i的值*$o的值= $变量中的结果   ~]# echo -ne "5*5=$((5*5))\t"   结果是25   \t 是在每一行 空白符隔开
        done
        echo
done

 

while 循环          
while CONDITION;do    condition状态就是判断式
     循环体          do是循环的开始
done                  done是循环的结束

~]# i=1;while [ $i -le 9 ];do echo $i;let i++;done
当变量i的值1于等于9  循环打印,在原有的1上面做运算++。直到9为止
condition 循环控制条件;进入循环之前,先做一次判断,每一次循环之后会再次做判断;条件为‘true’  (真)则执行一次循环,知道条件测试状态为‘false’ (假)终止循环
因此:condition 一般应该有循环控制变量,而此变量的值会在循环体不断的被修正
进入条件 condition 为true 真 。  退出条件:condition为false 假  


[root@localhost ~]# vim while100.sh
#!/bin/bash
#
#user:Compro
#求100以内所有正整数之和
i=1                                                    定义变量i的值=1   
sum=0                                              sum=0
while [ $i -le 100 ];do                      $i 小于等于 100 就执行循环,
        sum=$(expr $sum + $i)          $ 运算$sum + $i的值  定义为变量sum
        let i++                                       i++ 递增运算         然后循环判断,直到判断i是否小于至等于100
done
        echo $sum


[root@localhost ~]# vim whileping.sh
#!/bin/bash
#
#user:Compro
#ping范围内的所有主机在线状态,统计在线主机和离线主机个多少个
a="10.1.252."                                定义变量值,ip范围
b=1                                                 最小1开始的值
c=0
d=0
while [ $b -le 10 ];do                    判断循环条件 $b 是否小于等于 10 从1循环到10
        ping -c1 -W1 $a$b &> /dev/null         ping的结果导入到别的文件中 不显示出来
        if [ $? -eq 0 ];then                 调用上面的值 判断是否等于0
        echo "$a$b is yes"              如果成功,则打印yes
        let c++                                   c++  递增运算  判断上面的结果随之递增
        else
        echo "$a$b is no"               如果上面的失败,判断为no
        let d++                                 d++ 递增运算  判断上面的结果随之递增
        fi
        let b++                                  递增运算循环 , 不加这个就了死循环,
done
echo "yes users is $c"              调用c的变量结果 统计了yes的次数
echo "no users is $d"               调用d的变量结果 统计了no的次数
    
    

[root@localhost ~]# vim whil99.sh 
#!/bin/bash
#
#uesr:Compro
#打印99乘法表
s=1                                              定义变量s=1 s可以理解竖
while [ $s -le 9 ];do                     判断条件循环,$s 小于等9
        h=1                                      定义变量名h=1 可以理解行
        while [ $h -le $s ];do           判断条i安,$h小于等于#s
        shuzi=$[$s*$h]                    数值=$s*$h的结果
        echo -ne "$s*$h=$shuzi\t"      输出显示上面的结果 \t 空格隔开
        let h++                                递增运算 $h 的结果 执行9遍
        done
        echo
        let s++                                递增运算 $s 的结果 执行9遍
done
    
    

 
    
[root@localhost ~]# vim xiangqi.sh
#!/bin/bash 
#
#Compro
#打印国际象棋棋盘
i=1                                                  定义变量值
while [ $i -le 8 ];do                         判断循环,$i 小于等于8
        j=1
        while [ $j -le 8 ];do                 判断循环,$j 小于等于8
                sum=`expr $i + $j`        定义变量=运算 $i + $j
                z=`expr $sum % 2`         上面结果的取模,取余,  每一行每一列进行相加1+1=2 %2=0 1+2=3 %2=1
                [ $z -eq 0 ] && echo -ne "\033[41;1m  \033[0m"||echo -ne "\033[43;1m  \033[0m"   变量z 小于等于0 就打印红色, 其它则打印×××
                let j++                                递增运算  循环
        done
        echo
        let i++                                         递增运算  循环
done
  
 
 
until 循环
until codition;do    
       循环体
done
    
这种方式,跟while循环 恰恰相反,这个说的是当condition 条件成立时,就终止循环,
进入条件: codition 为 false (假)    退出条件:condition 为 frue (真)

    
    
循环控制语句 continue ; break
 用于循环体中     退出当此的循环
例如
#/bin/bash
i=1
unntil [ $i -gt 10 ];do      条件判断循环 变量i 是否大于 10    
        echo $i
        let i++              在原有的值上面递增运算
        [ $i -eq 5 ] && continue         条件判断,$i 是否等于5  , 执行退出此次循环命令  ,而不是全部退出循环,只是退出匹配条件的循环
         echo sss                显示sss分隔符。  当循环到5的时候停止。 在次从5开始又一次的循环
done

             
例如
#/bin/bash        打断,中断,停止此次循环。
i=1
unntil [ $i -gt 10 ];do       条件判断循环 变量i 是否大于 10 
        echo $i
        let i++                在原有的值上面递增运算
        [ $i -eq 5 ] && break        条件判断,$i 是否等于5 ,当等于5的时候 ,停止退出此次循环。
         echo sss               显示sss分隔符。  当循环到5的时候停止。
done
     echo sss   这个不再循环体之内的字符, 是可以输出显示出来的。             
             
             
 
             
[root@localhost ~]# vim caicai.sh
#!/bin/bash
#
#user:Compro
#随机生成10以内的数字,实现猜数字游戏,提示提大会或者小,相等则退出
sj=$[$RANDOM%10+1]                 定义变量名称=取模随机数10之内的
read -p "请输入数字:" sr                交互提示用户信息, sr是下面准备用的变量
until [ $sj -eq $sr ];do                      判断循环,$sj随机变量 等于 输入$sr变量, until条件成立时,就终止循环
#结果提示
 [ $sr -lt $sj ] && echo "x"                输入的小于随机  则提示小。
 [ $sr -gt $sj ] && echo "d"             输入的大于随机  则提示大。
read -p "请输入数字:" sr               只要是没输入跟随机相等的数字,则一直提示输入
done
echo "game over!"                         当上面条件结束时 ,则提示游戏结束
             
运行脚本  [root@localhost ~]# bash caicai.sh
请输入数字:1          输入1
x                     提示小
请输入数字:5          输入5
d                     提示大
请输入数字:3          输入3
game over!            游戏结束   证明脚本生成的随机数是3,相等则退出