zoukankan      html  css  js  c++  java
  • Shell流程语句

    1. shell流程控制

      流程控制是改变程序运行顺序的指令。linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。

    2. if语句

      格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi

    2.1  单分支

      if 条件表达式; then

      命令

      fi

    [root@localhost ~]# vim test.sh
    #!/bin/bash
    if [ 1 -eq 1 ];then
            echo "yes"
    fi
    [root@localhost ~]# bash test.sh
    yes

    2.2 双分支 

      if 条件表达式; then

      命令

      else

      命令

      fi

    #!/bin/bash
    if [ 1 -eq 2 ];then
            echo "yes"
    else
            echo "no"
    fi
    [root@localhost ~]# bash -x test.sh                     #-x,调试
    + '[' 1 -eq 2 ']'
    + echo no
    no
    #判断crond进程是否正在运行
    [root@localhost ~]# ps aux | grep "grep"
    root      11941  0.0  0.0 112648   956 pts/3    S+   20:30   0:00 grep --color=auto
    [root@localhost ~]#vim cron_d.sh
    #!/bin/bash
    NAME=crond
    NUM=$(ps aux | grep $NAME | grep -vc grep)
    if [ $NUM -eq 1 ]; then
    echo "$NAME running."
    else
    echo "$NAME is not running!"
    fi
    #检查主机是否在线
    #!/bin/bash
    if ping -c 1 192.168.1.1 &>/dev/null; then        #if可以直接对命令进行判断
    echo "OK."
    else
    echo "NO!"
    fi

     

    2.3 多分支

      if 条件表达式; then

      命令

      elif 条件表达式; then

      命令

      else

      命令

      fi

    #!/bin/bash
    N=$1                                               # 接收用户输入参数
    if [ $N -eq 3 ]; then
    echo "eq 3"
    elif [ $N -eq 5 ]; then
    echo "eq 5"
    elif [ $N -eq 8 ]; then
    echo "eq 8"
    else
    echo "no"
    fi


    如果第一个条件符合就不再向下匹配。

    在写脚本时先在命令测试,无误后再写入脚本

    if语句实例:编写一个计算器,实现简单的加减乘除

      要求:

      请输入一个数字: 7

      请输入运算符:+

      请输入第二个数字:7

      7+7=14

    [root@localhost ~]# vim count.sh
    #!/bin/bash
    read -p "请输入第一个数字:" num1
    read -p "请输入运算符:" cha
    read -p "请输入第二个数字:" num2
    count (){
            echo "${num1}${cha}${num2}=$((${num1}${cha}${num2}))"
    }
    error () {
            echo "Usage:$0 {+|-|*|/|0-9}"
    }
    if  [ -n '$num1' -a -n '$hca' -a -n '$num2' ];then
            if [ "$cha" == "+" ];then
            count
            elif [ "$cha" == "-" ];then
            count
            elif [ "$cha" == "*" ];then
            count
            elif [ "$cha" == "/" ];then
            count
            else
            error
            fi
    else
            echo '输入内容不能为空'
    fi
    :wq
    [root@localhost ~]# bash count.sh
    请输入第一个数字:8
    请输入运算符:+
    请输入第二个数字:2
    8+2=10
    [root@localhost ~]# bash count.sh
    请输入第一个数字:8
    请输入运算符:*
    请输入第二个数字:10
    8*10=80
    [root@localhost ~]# bash count.sh
    请输入第一个数字:l
    请输入运算符:l
    请输入第二个数字:l
    Usage:count.sh {+|-|*|/|0-9}

    3. for 语句

      用于批量化部署

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

        for 变量名 in 取值列表; do

        命令

        done
      
      或者

         for 变量名 in 取值列表

          do

          命令

          done

    [root@localhost ~]# vim for_test.sh
    #!/bin/bash
    for i in {1..5}
    do
            echo $i
            sleep 1                    #沉睡1秒,即1秒打印一个
    done
    :wq
    [root@localhost ~]# bash for_test.sh
    1
    2
    3
    4
    5
    #实现100以内的偶数/奇数和

    [root@localhost ~]#vim count_ou.sh #
    !/bin/bash sum=0 for i in `seq 0 2 100` #偶数和 do let sum+=$i done echo $sum :wq [root@localhost ~]# bash count_ou.sh 2550 [root@localhost ~]# vim count_ji.sh #!/bin/bash sum=0 for i in `seq 1 2 100` #奇数和 do let sum+=$i done echo $sum :wq [root@localhost ~]# bash count_ji.sh 2500
    #批量检查当前教室192.168.16.(1-10)网段主机是否在线
    [root@localhost ~]# vim check_ip.sh
    #!/bin/bash
    . /etc/init.d/functions                             #引用文件
    ip=192.168.16.
    for i in {1..10}
    do
            if ping -c 1 -w 1 $ip$i &>/dev/null;then    #返回执行结果0或1,其他文件导入黑洞文件
                    echo -n "$ip$i"                     #-n,不换行
                    success                             #相应function函数
                    echo ""                             #输出空格
            else
                    echo -n "$ip$i"
                    failure
                    echo “ ”
            fi
    done
    [root@localhost ~]# bash check_ip.sh
    192.168.16.1                                               [  OK  ]
    192.168.16.2                                               [  OK  ]
    192.168.16.3                                               [FAILED]
    192.168.16.4                                               [FAILED]
    192.168.16.5                                               [FAILED]
    192.168.16.6                                               [FAILED]
    192.168.16.7                                               [FAILED]
    192.168.16.8                                               [FAILED]
    192.168.16.9                                               [FAILED]
    192.168.16.10                                              [FAILED]

    4. while语句用于监控

      条件为真就进入死循环;条件为假就退出循环

        格式:while list; do list; done

      while 条件表达式; do

            命令

      done

    [root@localhost ~]# vim while_.sh
    #!/bin/bash
    n=0
    while [ $n -lt 5 ]
    do
            echo "$n"
            let n++
    done
    :wq
    [root@localhost ~]# bash  while_.sh
    0
    1
    2
    3
    4

      当条件表达式为 false 时,终止循环。

      条件表达式为 true,将会产生死循环。

      死循环有什么作用那?

      可以用来后台运行检测脚本,如下是是一个检测脑裂的脚本

      我们只需要在命令行中输入 nohup bash naolie.sh & 即可在后台持续运行该脚本

    #检测终端数量
    [root@localhost ~]# vim check_zh.sh=
    #!/bin/bash
    while true
    do
            num=`who | wc -l`
            echo"当前终端数量为$num"
            sleep 1
    done
    :wq
    [root@localhost ~]# bash check_zh.sh
    当前终端数量为5
    当前终端数量为5
    当前终端数量为6
    当前终端数量为6
    ^C   
    

    #关掉该终端后停止检测 #将检测文件写入文件并放在后台执行 [root@localhost
    ~]# vim check_zh.sh #!/bin/bash while true do num=`who | wc -l` echo "当前终端数量为$num" >> /root/check_zh sleep 1 done :wq [root@localhost ~]# bash check_zh.sh & #&表示放在后台 [1] 12336 [root@localhost ~]# tail -f check_zh 当前终端数量为3 当前终端数量为3 …..
    #关闭写入检测文件的该终端,监测终端停止 #若想关闭终端继续检测,将该监测文件挂起 [root@localhost
    ~]# nohup bash check_zh.sh & [1] 16949 [root@localhost ~]# nohup: ignoring input and appending output to ‘nohup.out’[root@localhost ~]# ls nohup.out #生成nohup.out文件 在监测则在该终端关闭后无影响 [root@localhost ~]# tail -f check_zh 当前终端数量为3 当前终端数量为3 当前终端数量为2 当前终端数量为2 …….
    #若要关掉该监测2关掉运行的进程即可 [root@localhost
    ~]# ps aux | grep check_zh root 13519 0.0 0.1 113124 1448 ? S 22:19 0:00 bash check_zh.sh root 16949 0.0 0.1 113124 1432 pts/0 S 22:28 0:00 bash check_zh.sh root 18476 0.0 0.0 112648 960 pts/0 R+ 22:31 0:00 grep --color=auto check_zh [root@localhost ~]# kill -9 13519 [root@localhost ~]# kill -9 16949
    #逐行读取passwd文件
    [root@localhost ~]# vim read.sh
    #!/bin/bash
    cat /etc/passwd | while read line
    do
            echo "$line"
            sleep 1
    done
    :wq
    [root@localhost ~]# bash read.sh
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin

    5. break和continue语句

      break 是终止循环。

      continue 是跳出当前循环。

    [root@localhost ~]# vim test_break.sh
    #!/bin/bash
    sum=0
    while true
    do
            if [ $sum -eq 5 ];then
                    break
            fi
            let sum++
            echo "$sum"
    done
    :wq
    [root@localhost ~]# bash test_break.sh
    1
    2
    3
    4
    5
    [root@localhost ~]# vim test_continue.sh
    #!/bin/bash
    sum=0
    while true
    do
            let sum++
    if [ $sum -eq 5 ];then
                    continue
            fi
            echo "$sum"
            sleep 1
    done
    :wq
    [root@localhost ~]# bash test_continue.sh
    1
    2
    3
    4                                            #跳过了5,仅跳出来此次循环
    6
    7
    8
    ^C

     

    6. case语句(sentos6常用)

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

      case 模式名    in

      模式 1)

        命令

        ;;

      模式 2)

        命令

        ;;

      *)

         不符合以上模式执行的命令

      esac

      每个模式必须以右括号结束,命令结尾以双分号结束,最后一个模式不需要添加;;。

    [root@localhost ~]# vim test_case.sh
    
    #!/bin/bash
    case $1 in
    [0-9])
            echo "数字"
    ;;
    [a-z])
            echo "a-z"
    ;;
    [A-Z])
            a=`tr $1 a-z`                 #大写转化成小写
            echo "$a"
    ;;
    *)
            echo "结束"
    esac
    :wq
    [root@localhost ~]# bash test_case.sh 1
    数字
    [root@localhost ~]# bash test_case.sh a
    a-z
    [root@localhost ~]# bash test_case.sh A
    a-z
    #内存不足报警
    
    #查看内存
    [root@localhost
    ~]# free total used free shared buff/cache available Mem: 999936 119616 613732 6856 266588 698092 Swap: 0 0 0 [root@localhost ~]# free -h total used free shared buff/cache available Mem: 976M 116M 599M 6.7M 260M 681M Swap: 0B 0B 0B [root@localhost ~]# free -h | grep M Mem: 976M 116M 599M 6.7M 260M 681M [root@localhost ~]# free -h | grep M | cut -d'M' -f4 599 [root@localhost ~]# free -h | grep M | cut -d'M' -f4 | tr -d ' ' 598 [root@localhost ~]# vim mem_warning.sh #!/bin/bash while true do mem=`free -h | grep M | cut -d'M' -f4 | tr -d ' '` if [ $mem -lt 500 ];then echo '当前内存不足,请及时处理' break #警告一次即可 fi done :wq

    7. 实训 

    1> 写一个脚本: 实现自动化一键部署NFS服务器端和客户端

    #服务端:192.168.16.5;客户端:192.168.16.6
    .5
    [root@localhost ~]# vim nfs_auto_client.sh
    #!/bin/bash
    mount /dev/cdrom /mnt &>/dev/null
    yum install rpcbind nfs-utils -y &>/dev/null
    mkdir /zxj &>/dev/null
    mount -t nfs 192.168.16.6:/zxj /zxj
    df -h
    [root@localhost
    ~]# vim nfs_auto_server.sh #!/bin/bash #desc: This shell is for auto deploy nfs #date: 2019-05-04 #author: zxj #服务端配置 pack_num=`ls /mnt | wc -l` if [ $pack_num -eq 0 ];then mount /dev/cdrom /mnt &>/dev/null #检测是否挂载 fi yum install rpcbind nfs-utils -y &>/dev/null if [ $? -ne 0 ];then exit fi mkdir /zxj &>/dev/null chown -R nsfnabody: /zxj echo "/zxj 192.168.16.6(rw)" > /etc/exports systemctl restart rpcbind nfs &>/dev/null #客户端配置 scp ./nfs_auto_client.sh 192.168.16.5:/root ssh 192.168.16.6 bash /root/nfs_auto_client.sh [root@localhost ~]# bash nfs_auto_server.sh


    2> 第二个脚本:实现批量化检测当前教室主机在线状况,在线主机保存至一个文件中
     

    [root@localhost ~]# vim check_online.sh
    #!/bin/bash
    touch online
    echo "在线ip:" > online
    ip=192.168.16.
    for i in {5..20}
    do
            if ping -c 1 -w 1 $ip$i &>/dev/null;then
            echo "$ip$i在线"
            echo "$ip$i" >> online
            else
            echo "$ip$i不在线"
            fi
    done
    cat online
    :wq
    
    [root@localhost ~]# bash check_online.sh
    192.168.16.5在线
    192.168.16.6在线
    192.168.16.7不在线
    192.168.16.8不在线
    192.168.16.9不在线
    192.168.16.10不在线
    192.168.16.11不在线
    192.168.16.12不在线
    192.168.16.13不在线
    192.168.16.14不在线
    192.168.16.15不在线
    192.168.16.16在线
    192.168.16.17不在线
    192.168.16.18不在线
    192.168.16.19不在线
    192.168.16.20不在线
    在线ip:
    192.168.16.5
    192.168.16.6
    192.168.16.16
    
     
    #或者
    [root@localhost ~]# vim check_online.sh
    #!/bin/bash
    touch online
    echo "在线ip:" > online
    ip=192.168.16.
    . /etc/init.d/functions
    for i in {5..20}
    do
            if ping -c 1 -w 1 $ip$i &>/dev/null;then
            echo -n  "$ip$i"
            success
            echo ""
            echo "$ip$i" >> online
            else
            echo -n "$ip$i"
            failure
            echo ""
            fi
    done
    cat online
    [root@localhost ~]# bash check_online.sh
    192.168.16.5                                               [  OK  ]
    192.168.16.6                                               [  OK  ]
    192.168.16.7                                               [FAILED]
    192.168.16.8                                               [FAILED]
    192.168.16.9                                               [FAILED]
    192.168.16.10                                              [FAILED]
    192.168.16.11                                              [FAILED]
    192.168.16.12                                              [FAILED]
    192.168.16.13                                              [FAILED]
    192.168.16.14                                              [FAILED]
    192.168.16.15                                              [FAILED]
    192.168.16.16                                              [  OK  ]
    192.168.16.17                                              [FAILED]
    192.168.16.18                                              [FAILED]
    192.168.16.19                                              [FAILED]
    192.168.16.20                                              [FAILED]
    在线ip:
    192.168.16.5
    192.168.16.6
    192.168.16.16

    3> 第三个脚本:实现批量化创建100个用户,并创建8位随机密码,且可登陆

    #!/bin/bash
    for i in {1..100}
    do
            useradd user$i
            passwd=`echo $RANDOM | md5sum | cut -c 1-8`
            echo $passwd | passwd --stdin user$i
            echo -e "账户:user$ 
    密码:$passwd"
    done

    4> 第四个脚本:找出系统中含有某个关键词的文件,并输出到终端,关键词用户输入指定

    [root@localhost ~]# vim find_key.sh
    #!/bin/bash
    read -p "Please input your keyword:" key
    for file in `find / -type f``
    do
            if grep "$key" $file &>/dev/null;then
                    echo "$file"
            fi
    done
    :wq
    [root@localhost ~]# bash find_key.sh
    Please input your keyword:anaconda  
    /boot/grub2/device.map
    ……

    5> 第五个脚本:批量判断当前目录下所有文件类型 

    [root@localhost ~]# vim type.sh
    #!/bin/bash
    for file in `ls /root`
    do
            type=`ls -ld $file | cut -c 1`
            if [ "$type" == "-" ];then
                    echo "$type------->$file=====普通文件"
            elif [ "$type" == "d" ];then
                    echo "$type------->$file=====目录文件" 
            elif [ "$type" == "l" ];then
                    echo "$type------->$file=====链接文件"
            else
                    echo "$type------->$file=====未知文件"
            fi
    done
    :wq
    [root@localhost ~]# bash type.sh
    -------->anaconda-ks.cfg=====普通文件
    -------->find_key.sh=====普通文件
    -------->type.sh=====普通文件

    6> 找到以.sh结尾的文件,计算文件大小总和,以KB为单位 

    #方法一: 用cut分割
    [root@localhost ~]# vim sum_sh.sh
    #!/bin/bash
    sum=0
    for file in `find / -name "*.sh"`
    do
            size=`ls -l $file | cut -d " " -f 5`
            let sum+=$size
    done
    echo "$(($sum/1024))KB"
    [root@localhost ~]# bash sum_sh.sh
    623KB
    
    # 方法二:用awk分割
    [root@localhost ~]# vim sum_sh1.sh
    #!/bin/bash
    sum=0
    for file in `find / -name "*.sh"`
    do
            size=`ls -l $file | awk -F " +" '{printf $5}'`
            let sum+=$size
    done
    echo "$(($sum/1024))KB"
    :wq
    [root@localhost ~]# bash sum_sh1.sh
    623KB
  • 相关阅读:
    新购服务器流程
    nginx代理证书使用方法
    一键部署lnmp脚本
    mysql主从库配置读写分离以及备份
    Linux入门教程(更新完毕)
    Git 工作流程
    Git远程操作
    常用Git命令
    js数组去重
    Sublime Text设置快捷键让html文件在浏览器打开
  • 原文地址:https://www.cnblogs.com/ajunyu/p/10887003.html
Copyright © 2011-2022 走看看