• 流程控制 -- while for 循环


    shell基础while循环

    img

    一:while循环

    while <条件表达式>  #此处可以是(())、[]、[[]]和前面条件表达式判断一样
    do
        指令..
    done
    while循环主要是
    1.重复执行一组命令,常常用于守护进程或无限循环的程序(要加sleep和usleep控制频率)。
    2.适用于频率小于1分钟的循环处理,其他的都可以用crond功能代替
    注:
    sleep 1  # 休息一秒
    usleep 1000000  # 休息1000000微秒,即休息一秒
    
    #while 循环擅长判断条件
    #start stop命令行之后,通常设置sleep n,然后再判断状态 
    

    例一:

    #!/bin/bash
    while [ 1 ]   #[ 1 ]和true :一样,只是前面两边需要有空格
    do
            uptime >>/tmp/uptime.log  
            sleep 2
    done
    
    #uptime用于查看系统负载,具体可参见http://os.51cto.com/art/201312/420840.htm
    

    例二:计算1+2...100的和

    方式一:
    #!/bib/sh
    SUM=0
    I=1
    while [ $I -le 100 ]  #[]中需要变量取值符号"$",而且大于小于只能用"-le"
    do
            ((SUM+=I))
            let I++
    done
    echo $SUM
    -------------------------------------------------------------------------------------------------
    方式二:
    #!/bib/sh
    SUM=0
    I=1
    while ((I<=100)) #(())中可以不要变量取值符号,大于小于是可以直接用
    do
            ((SUM+=I))
            ((I++))
    done
    echo $SUM
    -------------------------------------------------------------------------------------------------
    方式三:
    #!/bib/sh
    SUM=0
    I=100
    ((SUM=I*(I+1)/2))
    echo $SUM
    

    例三

    计数器

    #!/bin/bash
    num=1
    while [ $num -lt 10 ];do
            命令1
            ((num++))
            #expr $num + 1
    done
    
    #!/bin/bash
    num=1
    until [ ! $num -lt 10 ];do
            命令1
            ((num++))
    done
    
    #!/bin/bash
    num=1
    until [ $num -eq 10 ];do
            命令1
            ((num++))
    done
    

    实战一

    手机充值10元,每发一次短信花费1角5分,当余额低于1角5分时就不能在发短信,并且提示"余额不足,请充值",用while实现

    简单版一
    #!/bin/bash
    sum=1000
    fee=15
    while [ $sum -gt $fee ]
    do
            echo "send message successfully"
            ((sum-=fee))
            echo "left $sum"
    done
    echo "余额不足,请充值"
    --------------------------------------------------------------------------------------------
    专业版二:
    #!/bin/bash
    export LANG="zh_CN.UTF-8" #定义中文字符防止乱码
    
    sum=15             #总钱数
    msg_fee=15             #每条短信的钱数
    
    function menu(){
    cat <<END
    当前余额${sum},每条短信需要${msg_fee}
    ==============
    1.充值余额
    2.发送短信
    3.退出
    ==============
    END
    }
    #充钱
    function recharge(){
            read -p "请输入充值金额:" money
            expr $money + 1 &>/dev/null
            if [ $? -ne 0 ];then
                    echo "must be int"
            else
                    ((sum+=money))
                    echo "您的余额为$sum"
            fi
    }
    #发信息
    function sendInfo(){
            if ((sum < nsg_fee));then  #先判断钱够不够
                    echo "您的余额不足,请充值"
            else
                    while true
                    do
                            read -p "请输入内容(不要带空格):" message
                            echo "$message 已发送"
                            ((sum-=msg_fee))
                            return 0   #此处发送完成后,要去菜单选择,而不是一直发短信
                            if [ $sum -lt $msg_fee ];then
                                    printf "温馨提示:您的余额不足"
                                    return 1
                            fi
                    done
            fi
    }
    function main(){
            while true  #一直显示菜单,若想退出数字"3",即可退出
            do
                 menu
                 read -p "请输入一个数字:" NUM
                case "$NUM" in 
                  1)
                         recharge
                           ;;
                  2)
                         sendInfo
                           ;;
                  3)
                     exit 0
                       ;;
                  *)
                          echo "must be {1|2|3}"
                 esac
            done
    }
    main
    

    效果如图所示:

    [centos@mycentos iphone_fee]$ sh 2.sh 
    当前余额15,每条短信需要15
    ==============
    1.充值余额
    2.发送短信
    3.退出
    ==============
    请输入一个数字:1
    请输入充值金额:100
    您的余额为115
    当前余额115,每条短信需要15
    ==============
    1.充值余额
    2.发送短信
    3.退出
    ==============
    请输入一个数字:2
    请输入内容(不要带空格):hello
    hello 已发送
    当前余额100,每条短信需要15
    ==============
    1.充值余额
    2.发送短信
    3.退出
    ==============
    请输入一个数字:3
    [centos@mycentos iphone_fee]$
    注:case常用于服务启动脚本中,常用cat的here文档的方式打印菜单
    

    实战二:邮箱报警

    用while守护进程的方式去监控网站,每10秒确定一次是否正常,若不正常,就发邮箱通知
    预备知识:

    curl -I www.qq.com  : 显示响应头部信息
    curl -o 1.txt www.qq.com : 将网页下载到1.txt文件中
    
    #curl网站的状态码
    curl -o /dev/null -s -w %{http_code} http://zys.8800.org/
    -o参数,是把下载的所有内容都重定向到/dev/null,
    -s命令,是屏蔽了curl本身的输出,
    -w参数,是根据我们自己的需要,自定义了curl的输出格式。
    --connect-timeout,指定一次ping的超时时间
    用上面的命令采集页面的状态码,返回200表示页面正常,其他返回码则是异常。
    
    代码如下:
    #!/bin/bash
    if [ $# -ne 1 ];then
            echo $"usage:$0 url"
            exit 1
    fi
    while true  #守护进程
    do 
            #取回页面的状态码
            if [ $( curl -o /dev/null  --connect-timeout 3 -s -w "%{http_code}" $1 | egrep -w "200|301|302" | wc -l) -ne 1 ];then
                    echo "$1 is error"|mail -s "$1 is error" 111111@qq.com
            else
                    echo "$1 is ok"
            fi
            sleep 10
    done
    

    实战三: 用户登录脚本

    #!/bin/bash
    db_username=syy
    db_password=123
    user=`who am i|awk '{print $1}'`
    hostname=`hostname`
    count=0
    lj="/root"
    while true;do
            read -p "请输入用户账号: " username
            read -p "请输入用户密码: " password
            ((count++))
            if [ $count -eq 3 ];then
                            echo "超出输入次数,程序退出!!!"
                            break 1
            fi
            if [ "${username}" = ${db_username} -a "${password}" = ${db_password} ];then
                    while true;do
                            read -p "[${user}@${hostname} ${lj}]# " ml
                            if [ "$ml" = "exit" -o "$ml" = "q" -o "$ml" = "bash" ];then
                                    break 2
                            else
                                    $ml
                                    lj=`pwd`
                            fi
                    done
            else
                    echo "账号密码错误,请重新输入!!!"
            fi
    done
    

    实战四:动态监测系统状态

    #!/bin/bash
    while :
    do
            free
            sleep 0.5
            clear
    done
    

    知识点补充:

    1、当运行脚本时,若突然中断,肯定会导致数据的丢失,则需要防止中断的方式
    1.使用"sh shell.sh &"命令 ,即使用&在后台运行
    2.使用"nohup shell.sh &"命令,即使用nohup 加&在后台运行脚本
    3.利用screen保持会话,然后再执行脚本,即使用screen保持当前会话
    
    后台运行的知识:
    sh shell.sh &        脚本shell.sh 放在后台执行
    Ctrl+c           停止执行当前脚本或任务
    Ctrl+z           暂停执行当前脚本
    jobs             查看当前执行的脚本或任务
    
    bg           将当前脚本或任务放到后台执行
    kill             关闭当前脚本任务,即以"kill %号码"的形式关闭进程,任务号通过jobs获得
    fg           将当前的脚本或任务放到前台执行,若有多任务,则"fg 号码"调出相应的任务编号
    
    [centos@mycentos shell]$ sh 2.sh &  #后台运行
    [1] 2988
    [centos@mycentos shell]$ jobs       #查看任务数
    [1]+  Running                 sh 2.sh &
    [centos@mycentos shell]$ kill %1    #关闭进程为1的进程
    [centos@mycentos shell]$ jobs       
    [1]+  Terminated              sh 2.sh #程序已经被关闭
    
    2.while按行读取文件的几种方式
    1).
    exec <FILE
    sum=0
    while read line
    do
        cmd
    done
    ---------------------------------------------------------------------------------------------------
    2).
    cat file | while read line
    do
        cmd
    done
    -------------------------------------------------------------------------------------------------
    3).while read line
    do
        cmd
    done <file
    

    例如:开发一个shell脚本实现cat读文件的基本功能

    #!/bin/bash
    while read line
    do
            echo $line
    done<$1
    

    二:for循环

    for 变量名 in 变量取值列表
    do
        指令
    done
    
    C语言版循环
    for ((exp1;exp2;exp3))
    do
        指令。。。
    done
    
    for ((i=0;i<=3;i++))
    do
        echo $i
    done
    
    注:"in 变量取值列表" 可以省略,省略时相当于in "$@",即for i 就等于 for i in "$@"
    #for 循环擅长取值
    #读取取值列表时默认以空格分割
    

    例一:打印5、4、3、2、1这五个数字

    方式一:
    #!/bin/bash
    #直接列出变量列表,打印5、4、3、2、1 以空格为分隔符
    for NUM in 5 4 3 2 1  
    do
            echo $NUM
    done
    -------------------------------------------------------------------------------------------------
    方式二:
    #!/bin/sh
    #用{}号实现
    for NUM in {5..1}
    do
            echo $NUM
    done
    -------------------------------------------------------------------------------------------------
    方式三:
    #!/bin/bash
    #5是起始数字 -1是步长,即每次减一 1是结束数字
    for NUM in $(seq 5 -1 1)
    do
            echo $NUM
    done
    

    例二:使用for循环修改文件名

    还可以拷贝,删除,备份,移动

    for i in "ls /opt"
    do
    	mv $i ${i/txt/sh}
    done
    

    例三:使用for循环查看网段内可用ip

    for i in {1..255}
    do
    	ping -c1 10.0.0.$i &> /dev/null
    	[ $? -eq 0 ] && echo "10.0.0.${i}是可用的"
    done
    

    例四:显示主目录下以 .bash 开头的文件:

    #!/bin/bash
    for FILE in $HOME/.bash*
    do   
    	echo $FILE
    done
    

    实战三:修改文件名,脚本

    将目录下以".txt"结尾的全部变成".gif"

    思路:先处理一个,再批量处理
    [centos@mycentos test]$ ll
    total 0
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 1.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 2.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 3.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 4.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 5.txt
    
    #1.先处理一个:
    [centos@mycentos test]$ file=1.txt
    [centos@mycentos test]$ echo $file
    1.txt
    [centos@mycentos test]$ echo $file | cut -d '.' -f1
    1
    [centos@mycentos test]$ echo $(echo $file | cut -d '.' -f1).gif  #得到要变成的样子
    1.gif
    [centos@mycentos test]$ mv $file $(echo $file | cut -d '.' -f1).gif     
    [centos@mycentos test]$ ll
    total 0
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 1.gif
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 2.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 3.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 4.txt
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 5.txt
    
    #2.脚本批量处理:
    #!/bin/bash
    for file in $(ls | grep "txt$")
    do
            mv ${file} $(echo $file | cut -d . -f1).gif
    done
    结果:
    total 0
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 1.gif
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 2.gif
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 3.gif
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 4.gif
    -rw-rw-r--. 1 centos centos 0 Nov 13 13:58 5.gif
    

    实战四:修改文件名,脚本、awk、rename

    在linux下批量修改文件名,将下列文件名中"_finished"去掉
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:31 sku_102999_1_finished.jpg
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:31 sku_102999_2_finished.jpg
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:31 sku_102999_3_finished.jpg
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:31 sku_102999_4_finished.jpg
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:31 sku_102999_5_finished.jpg
    
    方法一:
    先处理一个后批量处理
    #!/bin/sh
    for list in $(ls *.jpg)
    do
            mv $list  $(echo $list |sed 's/_finished//g')
        	#mv $list ${list/_finished/}
    done
    ---------------------------------------------------------------------------------------------
    方法二:(awk)
    [centos@mycentos old]$ ls  | awk -F '.' '{print $0,$1,$2}' #$0为本身
    ch.sh ch sh
    sku_102999_1.jpg sku_102999_1 jpg
    sku_102999_2.jpg sku_102999_2 jpg
    sku_102999_3.jpg sku_102999_3 jpg
    sku_102999_4.jpg sku_102999_4 jpg
    sku_102999_5.jpg sku_102999_5 jpg
    [centos@mycentos old]$ ls  | awk -F '.' '{print $0,$1"_finished."$2}' #进行拼接
    ch.sh ch_finished.sh
    sku_102999_1.jpg sku_102999_1_finished.jpg
    sku_102999_2.jpg sku_102999_2_finished.jpg
    sku_102999_3.jpg sku_102999_3_finished.jpg
    sku_102999_4.jpg sku_102999_4_finished.jpg
    sku_102999_5.jpg sku_102999_5_finished.jpg
    [centos@mycentos old]$ ls  | awk -F '.' '{print "mv", $0,$1"_finished."$2}'
    mv ch.sh ch_finished.sh
    mv sku_102999_1.jpg sku_102999_1_finished.jpg
    mv sku_102999_2.jpg sku_102999_2_finished.jpg
    mv sku_102999_3.jpg sku_102999_3_finished.jpg
    mv sku_102999_4.jpg sku_102999_4_finished.jpg
    mv sku_102999_5.jpg sku_102999_5_finished.jpg
    [centos@mycentos old]$ ls  | awk -F '.' '{print "mv", $0,$1"_finished."$2}' | bash #将字符交给bash处理
    [centos@mycentos old]$ ll
    total 4
    -rw-rw-r--. 1 centos centos 93 Nov 13 14:37 ch_finished.sh
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_1_finished.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_2_finished.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_3_finished.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_4_finished.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_5_finished.jpg
    -------------------------------------------------------------------------------------------------
    方法三:
    [centos@mycentos old]$ rename "_finished" "" *jpg  #不要忘了"" ,空格代表去除
    [centos@mycentos old]$ ll
    total 4
    -rw-rw-r--. 1 centos centos 93 Nov 13 14:37 ch_finished.sh
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_1.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_2.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_3.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_4.jpg
    -rw-rw-r--. 1 centos centos  0 Nov 13 14:31 sku_102999_5.jpg
    
    rename 例子补充:

    批量去掉文件名中的"bd"

    [centos@mycentos db]$ ll
    total 0
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 bd02.html
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 bd03.html
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 bd04.html
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 bd05.html
    rename方式:
    [centos@mycentos db]$ rename "bd" "" *.html  
    [centos@mycentos db]$ ll
    total 0
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 02.html
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 03.html
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 04.html
    -rw-rw-r--. 1 centos centos 0 Nov 13 14:51 05.html
    
    注:
    先去掉一个,后批量去除也可
    

    实战五:C6服务开机自启动

    通过脚本实现仅仅sshd,network,crond,sysstat,rsyslog服务在开机时自启动,chkconfig --list是查看所有服务开机时的情况。

    方式一:
    先统一关闭,后开启特定的
    for old in $(chkconfig --list | grep "3:on" | awk '{print $1}' )
    do
        chkconfig --level 3 $old off
    done
    
    for old in crond network rsyslog sysstat sshd
    do
        chkconfig --level 3 $old on
    done
    -------------------------------------------------------------------------------------------------
    方式二:
    因为默认情况下开机需要保留的服务都是开启,所以将其他的关闭就好
    for old in $(chkconfig --list | grep "3:on" |awk '{print $1}' | egrep -v "crond|network|rsyslog|sshd|sysstat")
    do
        chkconfig --level 3 $old off
    done
    -------------------------------------------------------------------------------------------------
    方式三:
    awk的拼接
    chkconfig --list | egrep -v " sshd|crond|rsyslog|sysstat|network" |awk '{print "chkconfig", $1, "off"}'  |bash
    
    步骤分解:
    [root@mycentos ~]# chkconfig --list | egrep -v " sshd|crond|rsyslog|sysstat|network" |awk '{print "chkconfig", $1, "off"}'  #awk中的","变成显示后的空格进行分割
    chkconfig wdaemon off
    chkconfig winbind off
    chkconfig wpa_supplicant off
    chkconfig xinetd off
    chkconfig ypbind off
    .....
    chkconfig --list | egrep -v " sshd|crond|rsyslog|sysstat|network" |awk '{print "chkconfig", $1, "off"}'  | bash #将上面的当做命令传输到bash运行
    可以简化成:
    chkconfig | egrep -v " sshd|crond|rsyslog|sysstat|network" |awk '{print "chkconfig", $1, "off"}'  | bash
    

    实战六:打印九九乘法表

    #!/bin/sh
    COLOR='E[47;30m'
    RES='e[0m'
    
    for line in $(seq 9)
    do
            for col in $(seq ${line})
                    do
                            if (((line*col)>9));then  #此处用来控制输出格式,当是大于9时后面是一个空格,小于等于9时就是2个空格
    
                                    echo -en "${COLOR}${col}*${line}=$((line*col))${RES} " #一个空格 -e用来显示文字,-n为了不换行
                            else
                                    echo -en "${COLOR}${col}*${line}=$((line*col))${RES}  " #2个空格
                            fi
                    done
            echo ' '  #一行完成后换行
    done
    

    效果如图:

    img

    实战七:批量创建用户

    批量创建10个系统账号(oldboy01-oldboy10),并且设置密码(密码是随机数,要求是字符和数字的混合)
    思路:
    1.创建账号
    seq -w 10	#-w 表示 01-10 :格式对齐
    或者
    echo {01..10}
    2.创建账户,设置无交互密码
    useradd oldboy 
    echo 111111 | passwd --stdin oldboy
    3.随机八位密码(字母数字混合)
    
    小插曲:
        #生成随机数的方式
            1.利用RANDOM(范围是0-32767)随机生成数字,然后利用md5进行加密,取5到12为字符
                [root@mycentos ~]# echo $RANDOM |md5sum | cut -c 5-12
                1684ebbf
               若只有RANDOM,则安全性不高,$RANDOM前面加上自己定制的秘钥,安全就会增加
               echo "oldboy$RANDOM" 此时的就无法破解,企业常用
            2.利用OpenSSL生成随机数
              [root@mycentos shell]# openssl rand -base64 8
              FAQco/00NL0=
              [root@mycentos shell]# openssl rand -base64 80
              s0KqTLEA6fIueDcsJkPaqzd3owXNVUcN+d+9FyiMn1sXYShjmsDgbzrndvrn9o8i
              ZbjkSZzahr1ZMMbLcqJ/DvCfMAhEcZyG/hIvKMzkr8c=
            3.利用/dev/urandom ,这里记录系统此时状态,转换成数字
            [root@mycentos shell]# head /dev/urandom | cksum
            434988922 2930
            [root@mycentos shell]# head /dev/urandom | cksum
            3283962471 2161
            4.通过日期生成随机数;
            [root@mycentos shell]# date +%s%N
            1542160944683910406
            
    #以上的随机数长短不一,通过md5sum进行统一格式
    1.echo "test$RANDOM" |md5sum|cut -c 2-9
    2.openssl rand -base64 80 | md5sum|cut -c 2-9
    3.date +%s%N |md5sum|cut -c 2-9
    4.head /dev/urandom | md5sum |cut -c 2-9
    
    方式一:
    #!/bin/bash
    user="oldboy"
    passfile="/tmp/user1.log"
    
    for num in $(seq -w 10)
    do
            useradd $user$num   #创建用户
            pass="$(echo "test$RANDOM" |md5sum|cut -c 3-11)"    #先用秘钥加密后取得密码,用变量保存
    
            echo "$pass"|passwd --stdin $user$num &>/dev/null   #将密码赋值给用户
            echo -e "user:$user$num	passwd:$pass">>$passfile   #将用户信息放到固定文件中,-e参数处理特殊字符,此处将"	"处理成tab效果,而不是直接输出"	"
    done
    echo "------------------------------------------------------"
    cat $passfile
    
    特别注意:RANDOM是一个随机数,每次都不一样,因此如果需要用到2次,就一定要先用变量保存
    ------------------------------------------------------------------------------------------------
    方式二:
    用chpasswd批量创建密码
    批量创建密码:用命令chpasswd
    [root@mycentos shell]# useradd old
    [root@mycentos shell]# echo "old:123456"|chpasswd		#1
    [root@mycentos shell]# echo 123456 |passwd --stdin old	#2
    [root@mycentos shell]# su - oldgirl  #root切换成普通用户不需要密码
    [oldgirl@mycentos ~]$ su - old
    Password: 
    [old@mycentos ~]$ whoami
    old
    
    给多个用户设置密码:
    chpasswd < 密码文件
    其中密码文件格式:
    用户名1:口令1
    用户名2:口令2
    前提:用户必须存在
    
    #!/bin/bash
    . /etc/init.d/functions
    user="xiaoming"
    passfile="/tmp/user.log"
    num=10
    for num in $(seq -w $num)  #批量创建用户和密码
    do
            pass="$(echo "test$RANDOM" |md5sum|cut -c 3-11)"
            useradd ${user}${num} &>/dev/null && 
            echo -e "${user}${num}:$pass" >> $passfile 
            if [ $? -eq 0 ];then
                    action "${user}${num} is ok" /bin/true
            else
                    action "${user}${num} is fail" /bin/false
            fi
    done
    echo "-------------------------------------------------"
    
    chpasswd < $passfile  #chpasswdd 用于批量给用户设置密码,此处将上面批量设置的用户和密码一一对应
    cat $passfile && > $passfile
    

    实战八:菜单

    打印选择菜单,按照选项意见按照不同的web服务

    [root@mycentos select]# sh [menu.sh](http://menu.sh/)
    1.[install lamp]
    2.[install lanp]
    3.exit
    input the num you want:工作中所用的lamp
    
    要求:
    1.当用户输入1时,输出"start installing lamp"提示,然后执行/server/scripts/lamp.sh,输出"lamp is installed",并且退出脚本,此为工作中所用的lamp一键安装脚本
    2.当用户输入2时,输出"start installing lnmp" 提示,然后执行/server/scripts/lnmp.sh,输出"lnmp is installed",并退出脚本,此为工作中的lnmp一键安装脚本
    3.当输入3时,退出当前菜单及脚本提示
    4.当输入任何其他字符时,给出"Input error"后退出脚本
    5.对执行脚本进行相关的条件判断,例如:脚本文件是否存在,是否可执行等的判断。
    
    [root@mycentos select]# echo "lanp is installed" > /server/scripts/lanp.sh
    [root@mycentos select]# echo "lamp is installed" > /server/scripts/lamp.sh
    #!/bin/sh
    path=/server/scripts #设置脚本文件的路径
    [ ! -d "$path" ] && mkdir -p $path  #判断是否存在,不存在就创建
    
    function menu(){ #菜单栏
    cat <<END
            1.[install lamp]
            2.[install lanp]
            3.exit
            input the num you want:
    END
    }
    function main(){ #主函数
    menu #显示菜单
    read num #用户选项
    expr $num + 1 &> /dev/null # 判断用户输入是否是整数
    if [ $? -ne 0 ];then
            echo "must input {1|2|3}"
            exit 1
    fi
    case "$num" in 
      1)
            echo "start installing lamp"
            sleep 2 
            if [ -x "$path/lamp.sh" ];then #判断脚本是否可执行
                     source  $path/lamp.sh  #加载其他脚本
                     exit $?
            else
                     echo "$path/lamp.sh does not exist or can not be exec"
                     exit 1
            fi
            ;;
      2)
            echo "start installing lanp"
            sleep 2
            if [ -x "$path/lanp.sh" ];then
                    source $path/lanp.sh
                    exit $?
            else
                     echo "$path/lamp.sh does not exist or can not be exec"
                     exit 1
            fi
            ;;
      3)
            echo "bye"
            exit 3
            ;;
      *)
            echo "you must input {1|2|3}"
    esac
    }
    main
    
    注:
    1.此处用的是cat用法,还可以用select,但是常用的是cat 的here文档
    
    type <CTRL-D> to terminate
    enter your most liked film: Sound of Music
    Yeah! great film the Sound of Music
    

    三:until循环

    until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。一般while循环优于until循环,但在某些时候,也只是极少数情况下,until 循环更加有用。

    until 循环格式为:

    until command
    do
       Statement(s) to be executed until command is true
    done
    

    command 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

    例如,使用 until 命令输出 0 ~ 9 的数字:

    #!/bin/bash
    a=0
    until [ ! $a -lt 10 ]
    do   
    	echo $a   
    	a=`expr $a + 1`
    done
    
    #!/bin/bash
    a=0
    until [ $a -eq 10 ]
    do   
    	echo $a   
    	a=`expr $a + 1`
    done
    

    运行结果:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
  • 相关阅读:
    考研408大纲梳理(持续更新)
    学习就是把抽象变具体,模糊变清楚,组合件拆单件的过程。
    20210402学习笔记---眼看这是要浪费一下午?(要放假了心里跟长草似的 浮躁啥自己也不知道 假期不还是学习么)不行,赶紧学。
    20210401学习笔记--概念必须都弄懂,你可能很熟悉,但你却不知道他的定义、为什么用它不用别的,这个不清楚学习就很难。(另外学习要把握重点,已经会的都不需要记)
    20210401日记
    20210331日记
    20210330学习笔记--第1天目标是刷完HadoopDay1 Day2(计划40天学完大数据)
    20210330日记
    这个老的大数据视频,用的工具还是Eclipse,不照着视频做,就各种报错出问题,也不知道咋解决。还是买个新点的视频看。
    20210329学习笔记--看来得找个更新的视频课了(用IDEA),一步一步跟着做了,而且每天要定量,必须完成多少。目前进度完全不行。
  • 原文地址:https://www.cnblogs.com/syy1757528181/p/13603798.html
Copyright © 2020-2023  润新知