zoukankan      html  css  js  c++  java
  • shell语句

     
    本节内容
     
    1. shell流程控制
    2. for语句
    3. while语句
    4. break和continue语句
    5. case语句
    6. shell编程高级实战
     
    shell流程控制
     
    流程控制是改变程序运行顺序的指令。linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将通过例子介绍下,各个语句使用方法
     
    if语句
     
    格式:
    格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi
     
    1.1 单分支
     
    if 条件表达式; then
    命令

    例.1
    ╭─root@zxw ~
    ╰─➤ cat test1.sh 130 ↵
    #!/bin/bash
    if [ 1 -eq 1 ];then
    echo "true"
    fi
     ╭─root@zxw ~
    ╰─➤ bash test1.sh
    true
    例.2
    ╭─root@zxw ~
    ╰─➤ cat test2.sh
    #!/bin/bash
    systemctl restart network
    if [ $? -eq 0 ];then
    echo "重启网卡成功"
    fi
    ╭─root@zxw ~
    ╰─➤ bash test2.sh
    重启网卡成功
    例.3
    ─root@zxw ~
    ╰─➤ cat test2.sh
    #!/bin/bash
    if systemctl restart network;then
    echo "重启网卡成功"
    fi
    ╭─root@zxw ~
    ╰─➤ bash test2.sh
    重启网卡成功

    例子.4
     ╭─root@zxw ~
    ╰─➤ cat test2.sh
    #!/bin/bash
    if systemctl restart ndfetwork &>/dev/null;then
    echo "重启网卡成功"
    fi
    ╭─root@zxw ~
    ╰─➤ bash test2.sh
    1.2 双分支
     
    if 条件表达式; then
    命令
    else
    命令
    fi
     
    例1:
    ╭─root@zxw ~
    ╰─➤ cat test2.sh
    #!/bin/bash
    systemctl restart network &>/dev/null
    if [ $? -eq 0 ];then
    echo "重启网卡成功"
    else
    echo "由于其他原因重启网卡失败"
    fi
    ╭─root@zxw ~
    ╰─➤ bash test2.sh
    重启网卡成功
    例.2
    ╭─root@zxw ~
    ╰─➤ cat test3.sh
    #!/bin/bash
    mun=$(ps aux | grep "crond" | grep -c -v "grep")
    if [ $mun -eq 1 ] ;then
    echo "计划任务开启"
    else
    echo "计划任务关闭"
    fi
    ╭─root@zxw ~
    ╰─➤ bash test3.sh
    计划任务关闭
     
    实例2:判断crond进程是否正在运行
    -v: 表示取反
    -c: 即count,取代通常的输出,显示行数

     
    实例3:检查主机是否在线
    -c:表示发送几次包
    -w:表示等待时间。当试图检测不可达主机时此选项很有用。
    例.1
    ╭─root@zxw ~
    ╰─➤ cat test4.sh
    #!/bin/bash
    ip=$1
    if ping -c 1 -i 1 $ip &>/dev/null ;then
    echo "$ip在线"
    else
    echo "$ip不在线"
    fi
    例子2
    ╭─root@zxw ~
    ╰─➤ bash test4.sh 192.168.126.6
    192.168.126.6在线
    #!/bin/bash
    ip=$1
    ping -c 1 -i 1 $1 &>/dev/null
    if [ $? -eq 0 ] ;then
    echo "$ip在线"
    else
    echo "$ip不在线"
    fi

    if 语句可以直接对命令状态进行判断,就省去了获取$?这一步!
     
    1.3 多分支
     

    if 条件表达式; then
    命令
    elif 条件表达式; then
    命令
    else
    命令
    fi

    当不确定条件符合哪一个时,就可以把已知条件判断写出来,做相应的处理。
     
    实例1:
    $1:表示接受用户输入参数
    #!/bin/bash
    mun=$RANDOM
    if [ $mun -lt 500 ] ;then
    echo "$mun恭喜中一奖"
    elif [ $mun -ge 500 -a $mun -lt 2000 ];then
    echo "$mun恭喜中二等奖"
    elif [ $mun -ge 2000 -a $mun -lt 10000 ];then
    echo "$mun恭喜中三等奖"
    elif [ $mun -ge 10000 -a $mun -lt 100000 ];then
    echo "$mun恭喜中纪念奖"
    else
    echo "恭喜中特等奖"

    fi
    ╭─root@zxw ~
    ╰─➤ bash test5.sh
    5325恭喜中三等奖

    如果第一个条件符合就不再向下匹配。
     
    shell编程之if语句实战案例
     
    需求:
    1. 完成用户输入文件或者目录的自动复制,并可以实现用户指定复制目标位置。
    2. 用户体验佳。
     

    #!/bin/bash
    read -p "pls enter a file you want to copy:" file
    if [ -f $file -o -d $file ];then
    read -p "do you want to copy the $file?(y/n)" sure
    confirm=$(echo ${sure} | tr A-Z a-z)
    if [ "$confirm" == "y" ];then
    read -p "where do you want to copy?" dire
    if [ -d $dire ];then
    cp -a $file $dire
    echo "the $file copied to $dire"
    else
    echo "the $dire is not exists"
    exit 1
    fi
    elif [ "$confirm" == "n" ];then
    echo "bye"
    else
    echo "pls input y or n"
    fi
    else
    echo "the $file is not exists"
    fi

     
    练习题1:尝试写一个shell简单的计算器,实现加减乘除。
    请输入一个数字: 7
    请输入运算符:+
    请输入第二个数字:7
    7+7=14
     
    #!/bin/bash
    read -p "数字1: " mnu1
    read -p "符号{+|-|*|/}: " mnu2
    read -p "数字2: " mnu3
    if [ -n "$mnu1" -a -n "$mnu2" -a -n "$mnu3" ];then
    if [ "$mnu2" == "+" ];then
    echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"
    elif [ "$mnu2" == "-" ];then
    echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"
    elif [ "$mnu2" == "*" ];then
    echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"
    elif [ "$mnu2" == "/" ];then
    echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"

    else
    echo "请输入一个符号{+|-|*|/}"
    fi

    else
    echo "请输入一个数字!"
    fi

    ─root@zxw ~
    ╰─➤ bash test6.sh
    数字1: 7
    符号{+|-|*|/}: +
    数字2: 7
    7+7=14

    练习题2:输入一个用户,用脚本判断判断该用户是否存在。
     #!/bin/bash
    Read -p “请出入一个用户” user
    If id $user &>/dev/null ;then
    Echo "$user存在"
    Else
    Echo "$user不存在"
    F i
    ╭─root@zxw ~
    ╰─➤ bash test8.sh
    请出入一个用户:z
    z不存在
    ╭─root@zxw ~
    ╰─➤ bash test8.sh
    请出入一个用户:zhao
    zhao存在


    for语句
     
    格式:for name [ [ in [ word ... ] ] ; ] do list ; done

    for 变量名 in 取值列表; do
    命令
    done

    或者
      for 变量名 in 取值列表
      do
    命令
      done

     
    实例1:
    #!/bin/bash
    for i in `seq 10`
    do
    useradd user$i
    pass=`echo $RANDOM | md5sum | cut -c 1-6`
    echo "$pass" | passwd --stdin user$i
    echo -e "用户:user$i 密码:$pass " >> /root/test


    done

     
    实例2:计算100以内偶数和
    ╭─root@zxw ~
    ╰─➤ cat test10.sh
    #!/bin/bash
    sum=0
    for i in `seq 2 2 100`
    do
    let sum+=$i
    done
    echo $sum

    shell编程之for语句实战案例
     
    需求:
    1. 批量检查当前教室主机是否在线
    ╭─root@zxw ~
    ╰─➤ cat test11.sh
    #!/bin/bash
    ip=192.168.126.
    for i in `seq 10`
    do
    if ping -c 1 -w 1 $ip$i &> /dev/null;then
    echo "$ip$i在线"
    sleep 1
    else
    echo "$ip$i不在线"
    sleep 1
    fi

    done

    练习题1:计算100以内的奇数和
    ╭─root@zxw ~
    ╰─➤ cat test12.sh
    #!/bin/bash
    sum=0
    for i in `seq 1 2 100`
    do
    let sum+=$i
    done
    echo "$sum"

    ─root@zxw ~
    ╰─➤ bash test12.sh
    2500

    练习题2:判断/root目录下面的文件类型
    #!/bin/bash
    for i in `ls -ld /root/* | cut -c 1`
    do
    type1=$i
    if [ "$type1" == "-" ];then
    echo "$i 文件"
    elif [ "$type1" == "d" ];then
    echo "$i目录"
    elif [ "$type1" == "l" ];then
    echo "$链接文件"
    else
    echo "无效文件"
    fi
    done
    ~


     
    while语句
     
    条件为真就进入死循环;条件为假就退出循环
    格式:while list; do list; done
    while 条件表达式; do
    命令
    done
     
    实例1:

    #!/bin/bash
    while true
    do
    mun=`free -h | grep Mem | cut -d "G" -f 3 | cut -d "M" -f 3 | tr -d " " `
    echo "$(date "+%F_%T")" $mun >> /root/nohup.out
    sleep 3
    done


    当条件表达式为 false 时,终止循环。
     
    实例2:条件表达式为 true,将会产生死循环
    #!/bin/bash
    while [ 1 -eq 1 ]; do
    echo "yes"
    done
     
    也可以条件表达式直接用 true:
    #!/bin/bash
    while true; do
    echo "yes"
    done
     
    死循环有什么作用那?
    可以用来后台运行检测脚本,如下是是一个检测脑裂的脚本
    我们只需要在命令行中输入 nohup bash naolie.sh & 即可在后台持续运行该脚本
    例子1:检测脑裂

    #!/bin/bash
    while true
    do
    ip=`ip a s eth0 | awk -F " +" 'NR==4{print $3}' | awk -F "/" '{print $1}' | awk -F "." '{print $4}'`1
    ping -c 3 -i 1 -W 1 10.220.5.166 &>/dev/null
    if [ $? -eq 0 ] && [ $ip = 1001 ];then
    echo "happed naolie"
    else
    echo "everything is ok"
    fi
    done

     
    例子2:检测终端数量

    #!/bin/bash
    while true
    do
    num=`who | wc -l`
    echo "当前打开终端数量为:$num"
    sleep 5
    done

     
    要想使用 while 循环逐行读取 a.txt 文件,有三种方式:
     
    方式 1:
    ╭─root@zxw ~
    ╰─➤ cat test16.sh 130 ↵
    #!/bin/bash
    cat /etc/passwd | while read line
    do
    echo "$line"
    sleep 2

    done

    方式2:
    ╰─➤ cat test17.sh
    #!/bin/bash
    while read line
    do
    echo "$line"
    sleep 2
    done < /etc/passwd
    方式3:
    exec < ./a.txt # 读取文件作为标准输出
    while read LINE; do
    echo $LINE
    done
    与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。
     

    #!/bin/bash
    n=0
    until [ $n -eq 5 ]
    do
    let n++
    echo "$n"
    done

     
    break和continue语句
     
    break 是终止循环。
    continue 是跳出当前循环。
    示例 1:在死循环中,满足条件终止循环


    #!/bin/bash
    num=0
    while true
    do
    let num++
    if [ $num -eq 6 ];then
    break
    fi
    echo "$num"
    done
    ~

    里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是跳出本次循环。
     
    示例 2:举例子说明 continue 用法
    #!/bin/bash
    num=1
    while true
    do
    let num++
    if [ $num -eq 6 ];then
    continue
    fi
    echo "$num"
    done
    当变量 N 等于 3 时,continue 跳过了本次循环,没有执行下面的 echo。
    注意:continue 与 break 语句只能循环语句中使用。
     

    [root@ken-node1 ~]# cat test.sh
    #!/bin/bash
    st=0
    while true
    do
    let st++
    if [ $st -eq 5 ];then
    continue
    elif [ $st -eq 10 ];then
    break
    else
    echo "$st"
    fi

    done
    [root@ken-node1 ~]# bash test.sh
    1
    2
    3
    4
    6
    7
    8
    9

     
     
    case语句
     
    case 语句一般用于选择性来执行对应部分块命令。

    case 模式名 in
    模式 1)
    命令
    ;;
    模式 2)
    命令
    ;;
    *)
    不符合以上模式执行的命令
    esac

     
    每个模式必须以右括号结束,命令结尾以双分号结束,最后一个模式不需要添加;;。
     
    示例1:根据位置参数匹配不同的模式

    #!/bin/bash
    case $1 in
    start)
    echo "start."
    ;;
    stop)
    echo "stop."
    ;;
    restart)
    echo "restart."
    ;;
    *)
    echo "Usage: $0 {start|stop|restart}"
    esac
    # bash test.sh
    Usage: test.sh {start|stop|restart}
    # bash test.sh start
    start.
    # bash test.sh stop
    stop.
    # bash test.sh restart
    restart.

     
    实例2:

    #!/bin/bash
    case $1 in
    [0-9])
    echo "match number."
    ;;
    [a-z])
    echo "match letter."
    ;;
    '-h'|'--help')
    echo "help"
    ;;
    *)
    echo "Input error!"
    exit
    esac
    # bash test.sh 1
    match number.
    # bash test.sh a
    match letter.
    # bash test.sh -h
    help
    # bash test.sh --help
    help

    模式支持的正则有:*、?、[ ]、[.-.]、|。后面有章节单独讲解 Shell 正则表达式。
     
    shell编程高级实战
     
    实战1:写一个猜数字的小游戏
    要求:
    1. 猜对退出
    2. 数字随机
    3. 使用体验佳

    #!/bin/bash
    clear
    num=`echo $RANDOM`
    count=0
    while true
    do
    let count++
    read -p "pls enter a num you guess:" guessnum
    if [ $guessnum -lt $num ]; then
    echo "the num is so smaller!"
    elif [ $guessnum -gt $num ];then
    echo "the num is so bigger!"
    elif [ $guessnum -eq $num ];then
    echo "right!wonderful! "
    break
    else
    echo "good bye"
    exit
    fi
    done
    echo -e "33[36myou guess $count times33[0m" #-e允许对下面列出的加反斜线转义的字符进行解释.

     
    实战2:检测当前教室在线IP地址
    要求:
    1.显示美观

    #!/bin/bash
    . /etc/init.d/functions
    ip=172.20.10.
    for i in {1..255}
    do
    if ping -c 1 $ip$i &>/dev/null ;then
    echo -n "$ip$i" #-n表示不输出行尾的换行符
    success
    echo ""
    else
    echo -n "$ip$i"
    failure
    echo ""
    fi
    done

     
    实战3:检查软件包是否安装
    要求:
    1.用户输入软件名即可进行查询


    #!/bin/bash
    read -p "请出入一个软件名:" Y
    if rpm -q $Y ;then
    echo "$Y已安装版本"
    else
    echo "$Y未安装"
    fi
    ~
    ~

     
    实战4:打印九九乘法表
    #!/bin/bash
    for i in `seq 9`
    do
    for l in `seq 9`
    do
    if [ $l -le $i ];then
    echo -n " $l*$i=$(($i*$l))"
    fi
    done
    echo " "
    done

     
    补充练习题
     
    1.实现简单计算器(加减乘除)
     
    #!/bin/bash
    read -p "数字:" A
    read -p "符号(+|-|*|/):" B
    read -p "数字:" C
    if [ -n "$A" -a -n "$B" -a -n "$C" ];then
    if [ "$B" == "+" ] ;then
    echo "$A$B$C=$(($A$B$C))"
    elif [ "$B" == "-" ];then
    echo "$A$B$C=$(($A$B$C))"
    elif [ "$B" == "*" ] ;then
    echo "$A$B$C=$(($A$B$C))"
    elif [ "$B" == "/" ];then
    echo "$A$B$C=$(($A$B$C))"
    else
    echo"请输入有效符号"
    fi


    else
    echo "请输入有效数字"
     
    2. 批量创建100个以数字开头的文件,并每隔一秒钟输出到终端

    #!/bin/bash
    for i in {1..100}
    do
    touch ${i}.txt
    echo "${i}.txt"
    sleep 1
    done

     
    3.动态持续监测本机linux系统内存剩余量(仅显示数值),并在终端输出

    #!/bin/bash
    while true
    do
    mem=`free -h | grep "Mem" | cut -d "M" -f 4 | tr -d " "`
    echo $mem
    sleep 1
    done
    Nohup bash
     
    课后练习题

    写一个脚本: 实现自动化一键部署NFS服务器端和客
    户端
    #!/bin/bash
    pack_num=`ls /mnt | wc -l`
    if [ $pack_num -eq 0 ] ;then
    mount /dev/cdrom /mnt &>/dev/null
    fi
    if yum install nfs-utils rpcbind -y &>/dev/null ;then
    echo "下载成功"
    else
    exit
    fi
    mkdir /test &>/dev/null
    echo "/test *(rw)" >> /etc/exports
    if systemctl restart nfs rpcbind ;then
    echo "重启成功"
    else
    exit
    fi
    Setenforce 0 &>/dev/null
    Systemctl stop firewalld &>/dev/null

    客户端
    #!/bin/bash
    mount /dev/cdrom /mnt &>/dev/null
    yum insatall nfs-utils -y
    mkdir /zxw &>/dev/null
    mount -t nfs 192.168.126.8:/test /zxw
    df -h
    ~


    第二个脚本:实现批量化检测当前教室主机在线状况,在线主机保存至一个文件中
    #!/bin/bash
    . /etc/init.d/functions
    ip=192.168.126.
    for i in `seq 10`
    do
    if ping -c 1 -w 1 $ip$i >>/dev/null;then
    echo -n "$ip$i"
    success
    echo ""
    echo "$ip$i" >>/root/ip
    else

    echo -n "$ip$i"
    failure
    echo ""

    fi

     

    done

     


    第三个脚本:实现批量化创建100个用户,并创建8位随机密码,且可登陆
    #!/bin/bash
    for i in `seq 100`
    do
    useradd yonghu$i
    mima=$(echo $RANDOM | md5sum | cut -c 1-8)
    echo "$mima" | passwd --stdin yonghu$i
    echo -e "用户:yonghu$i 密码:$miman " >>/root/test


    done

     

     

    第四个脚本:找出系统中含有某个关键词的文件,并输出到终端,关键词用户输入指定
    #!/bin/bash
    read -p "请输入关键字 :" X
    for i in `find /etc/ -type "f"`
    do
    if grep $X $i &>/dev/null;then
    echo "$i--$X"
    fi

    done

     


    第五个脚本:批量判断当前目录下所有文件类型
     
    #!/bin/bash
    for i in `ls /var`
    do
    cd /var
    X=`ls -ld $i | cut -c 1`
    if [ "$X" == "-" ];then
    echo " $i------是文件"
    elif [ "$X" == "d" ];then
    echo "$i------目录"
    elif [ "$X" == "l" ];then
    echo "$i------链接文件"
    else
    echo "$i------无效文件"
    fi
    done

    ~
    shell练习题
     
     
     
     
    参考答案:
     1. 每一秒钟输出/root下的文件至屏幕
    #!/bin/bash
    for file in `ls /root`
    do
    echo $file
    sleep 1
    done
     
    2.
    2. 打印出包含某个关键词的文件(关键词执行脚本时接收)小,输出

    #!/bin/bash
    key=$1
    for file in `find / -type f`
    do
    grep "$key" $file &>/dev/null
    if [ $? -eq 0 ];then
    echo $file
    sleep 1
    fi
    done

     
    3.
    3. 统计系统中以.sh结尾的文件总大结果以kb为单位
     

    #!/bin/bash
    sum=0
    for size in `find /root -name "*.sh" -exec ls -l {} ; | cut -d " " -f 5`
    do
    let sum+=$size
    done
    echo "$((sum/1024))kb"

     

     

  • 相关阅读:
    C++开发系列-友元函数 友元类
    C++开发系列-C语言的malloc与C++的new分配空间
    C++开发系列-内联函数
    iOS开发系列-Foundation与CoreFoundation内存管理
    C开发系列-字符串
    C开发系列-数组
    列表 元组 字典
    神奇的print
    while 语句的逻辑
    <Web Crawler><Java><thread-safe queue>
  • 原文地址:https://www.cnblogs.com/itzhao/p/11253423.html
Copyright © 2011-2022 走看看