• Shell 编程练习


    获取传递参数的最后一个参数

    [root@ethanz ~]# ./test.sh a b c d e f
    6
    f
    a
    [root@ethanz ~]# cat test.sh
    #!/bin/bash
    
    args=$#
    lastarg=${!args}
    firstarg=$1
    
    
    echo $args
    echo $lastarg
    echo $firstarg
    

    将后缀名为 .txt 的文件改成 .log

    [root@k8s-master test]# touch localhost_2020-01-{02..26}.txt
    [root@k8s-master test]# ll
    total 0
    -rw-r--r-- 1 root root 0 Aug 27 16:26 localhost_2020-01-02.txt
    -rw-r--r-- 1 root root 0 Aug 27 16:26 localhost_2020-01-03.txt
    -rw-r--r-- 1 root root 0 Aug 27 16:26 localhost_2020-01-04.txt
    
    # 此例中, ${filename//.txt/.log} 或 ${filename/.txt/.log} 都可以,如果变量名中有多个 .txt,前者全部替换,后者只替换第一个
    [root@k8s-master test]# for filename in `ls ./`;do mv $filename ${filename//.txt/.log};done
    [root@k8s-master test]# ll
    total 0
    -rw-r--r-- 1 root root 0 Aug 27 16:26 localhost_2020-01-02.log
    -rw-r--r-- 1 root root 0 Aug 27 16:26 localhost_2020-01-03.log
    -rw-r--r-- 1 root root 0 Aug 27 16:26 localhost_2020-01-04.log
    

    输入一个用户,判断 Linux 系统中是否存在此用户

    [root@k8s-master 827]# cat check_user.sh
    #!/bin/bash
    
    read -p "Check username is or not exist : " username
    
    grep -e  "^$username:" /etc/passwd >/dev/null
    
    if [ $? -eq 0 ];then
        echo "Yes! It's exist!"
    else
        echo "No ! It's not exist"
    fi
    

    猜年龄,年龄是整形数字

    [root@k8s-master 827]# cat guess_age.sh
    #!/bin/bash
    
    correct_age=18
    
    
    # 检查是否输入一个位置参数
    [ $# -ne 1 ] && echo "Please Input One Argument ~~~ "  && exit
    
    # 检查参数是否是数字
    [[ ! $1 =~ ^[0-9]+$ ]] && echo "Argument Must Be Integer ~~~ " && exit
    
    
    # 判断是否正确
    if [ $1 -eq $correct_age ];then
        echo "Congratulation ~~~"
    elif [ $1 -gt $correct_age ];then
        echo "Greater Than Correct Resault !!! "
    elif [ $1 -lt $correct_age ];then
        echo "Less Than Correct Resault !!! "
    fi
    

    监控磁盘和内存的使用情况

    [root@k8s-master 827]# cat monitor.sh
    #!/bin/bash
    
    # 获取磁盘已使用量
    disk_use=`df | grep '/$' | awk '{print $5}' | cut -d% -f1`
    # 获取内存总量,内存空闲
    mem_total=`free -m | grep "Mem" | awk '{print $2}'`
    mem_free=`free -m | grep "Mem" | awk '{print $4}'`
    # 获取内存空闲百分比
    mem_free_percent=$(echo "scale=2;$mem_free/$mem_total" | bc | cut -d. -f2)
    
    
    # 磁盘用量大于 80% 时,发送邮件提醒
    if [ $disk_use -gt 80 ];then
        echo "磁盘使用${disk_use}%,清理下磁盘吧 ~~~" | mail -s "Warning,Check Your Disk Status" xxxx@126.com
    fi
    
    # 内存用量大于 80% 时,发送邮件提醒
    if [ $mem_free_percent -lt 20 ];then
        echo "内存剩余${mem_free_percent}%, 内存不够用了 ~~~" | mail -s "Warning,Check Your Memory Status" xxxx@126.com
    fi
    

    写一个脚本,模拟 Nginx 服务启动等操作

    [root@k8s-master 827]# cat nginx.sh
    #!/bin/bash
    
    
    . /etc/init.d/functions
    
    # 需要定义一个全局变量,位置参数无法传递到函数体内
    arg=$1
    
    # 判断执行命令是否成功,并给出响应结果
    function check(){
        systemctl $1 nginx &>/dev/null
        [ $? -eq 0 ] && action "Nginx $arg is" true || action "Nginx $arg is" false
    }
    
    # 判断是否传入一个位置参数
    [ $# -ne 1 ] && echo -e "Usage: $0 { start | restart | stop | reload | status } " && exit
    
    
    
    # 根据传入的位置参数 选择执行命令
    case $1 in
    "start")
        # 检查是否已经启动
        netstat -an | grep 'LISTEN' | grep '80'  &>/dev/null
        if [ $? -eq 0 ];then
            action "Nginx is already started" true
        else
            check
        fi
        ;;
    "restart")
        check
        ;;
    "status")
        check
        ;;
    "stop")
        check
        ;;
    "reload")
        check
        ;;
    *)
        echo -e "Usage: $0 { start | restart | stop | reload | status } "
    esac
    

    判断数字是否是整型

    [root@k8s-master 826]# cat isint.sh
    #!/bin/bash
    
    # 获取用户终端输入
    read -p "Please Input Your Number:" number
    
    # 判断输入是否是整型
    expr $number + 0 &>/dev/null
    [ $? -eq 0 ] && echo "Type Int!" || echo "SHIT!!"
    

    测试传入的 IP 地址能否 PING 通

    [root@k8s-master 826]# cat ping.sh
    #!/bin/bash
    # 循环获取所有的位置参数
    for i in "$@"
    do
        # 在 子shell 中运行,并放到后台,可以脚本并发执行
        (ping -c 1  $i &>/dev/null ;[ $? == 0 ] && echo "$i : successful" >> ./ping.log || echo "$i : failure" >> ./ping.log) &
    done
    
    [root@k8s-master 826]#./ping.sh baidu.com 172.16.1.151 1.1.1.1 172.16.1.153
    [root@k8s-master 826]# cat ping.log
    172.16.1.151 : successful
    baidu.com : successful
    1.1.1.1 : successful
    172.16.1.153 : failure
    

    普通运算,要求数字可以为整型和浮点型

    [root@k8s-master 826]# cat arithmetic.sh
    #!/bin/bash
    
    # 判断传了几个参数
    [ $# -ne 2 ] && echo "请输入两位数字信息" && exit
    
    
    # 定义变量,方便调用
    a=$1
    b=$2
    
    # 运算
    echo "a-b=$[$a-$b]"
    echo "a+b=$[$a+$b]"
    echo "a*b=$[$a*$b]"
    echo "a%b=$[$a%$b]"
    # 除法运算
    # 判断小数点前是否有数字,如果结果小于 1,bc 运算结果小数点前没有数字
    if [ -z  $(echo "scale=2;$a/$b"| bc | cut -d. -f1 ) ];then
        # 如果结果小于 1,补一个 0(字符),bc 运算结果小于 0 时,会省略 0
        echo "0$(echo "scale=2;$a/$b"| bc )"
    else
        # 如果结果大于 1,正常输出即可
        echo "$(echo "scale=2;$a/$b"| bc )"
    fi
    

    传递两个两位数(整型),做运算,要求除法结果保留两位小数

    #!/bin/bash
    
    # 判断传了几个参数
    [ $# -ne 2 ] && echo "请输入两位数字信息" && exit
    
    # 判断是否是两位的整型数字
    [ ${#1} -ne 2 ] || [[ ! $1 =~  ^[0-9][0-9]$ ]] && echo "只能是两位数且为整型"
    
    [ ${#2} -ne 2 ] || [[ ! $2 =~  ^[0-9][0-9]$ ]] && echo "只能是两位数且为整型"
    
    # 定义变量,方便调用
    a=$1
    b=$2
    
    # 运算
    echo "a-b=$[$a-$b]"
    echo "a+b=$[$a+$b]"
    echo "a*b=$[$a*$b]"
    # 做判断,可以获取 2 个小数位
    if [ -z  $(echo "scale=2;$a/$b"| bc | cut -d. -f1 ) ];then
        echo "0$(echo "scale=2;$a/$b"| bc )"
    else
        echo "$(echo "scale=2;$a/$b"| bc )"
    fi
    echo "a%b=$[$a%$b]"
    

    传入两个参数,对比两个数字的大小,要求数字可以为整型和浮点型

    [root@k8s-master 826]# cat comparenum.sh
    #!/bin/bash
    
    # 判断用户输入了 2 个参数
    if [ $# -ne 2 ];then
        echo "需要输入两个参数啊"
        exit
    fi
    # 判断用户输入的 2 个参数都是数字
    if [[ ! $1 =~ ^[0-9]+$ ]] && [[ ! $1 =~ ^[0-9]+.[0-9]+$ ]];then
        echo "第一个参数得是数字啊"
        exit
    fi
    
    if [[ ! $2 =~ ^[0-9]+$ ]] && [[ ! $2 =~ ^[0-9]+.[0-9]+$ ]];then
        echo "第二个参数得是数字啊"
        exit
    fi
    
    
    # 对比两个参数(数字)大小
    if [[   $1 =~ ^[0-9]+$ ]] && [[   $2 =~ ^[0-9]+$  ]];then
        # 对比整型数字大小
        [[ $1 -eq $2  ]] && echo "$1 = $2"
        [[ $1 -gt $2  ]] && echo "$1 > $2"
        [[ $1 -lt $2  ]] && echo "$1 < $2"
    else
        # 对比浮点型数字大小
        [[ $(echo "$1 == $2" | bc) -eq 1 ]] && echo "$1 = $2"
        [[ $(echo "$1 > $2" | bc) -eq 1 ]] && echo "$1 > $2"
        [[ $(echo "$1 < $2" | bc) -eq 1 ]] && echo "$1 < $2"
    fi
    

    模拟用户登录终端

    #!/bin/bash
    
    
    db_username="root"
    db_password="123"
    counts=0
    
    function tty(){
        while :
        do
            read -p "[root@website $(pwd)]# "  cmd
            $cmd
        done
    }
    
    
    while :
    do
        read -p  "Please Input Your Username : " username
        read -p  "Please Input Your Password : " password
        username=${username:=NULL}
        password=${password:=NULL}
        # 判断登录是否成功
        if [ $username == $db_username -a $password == $db_password ];then
            # 成功,退出循环
            echo "[ Successful ] Login ! "
            break
        else
            # 失败,提示还可以尝试的次数
            [ $counts -ne 2 ] && echo "[ Info ] You have only $[2-counts] times left !"
            # 判断用户名错误还是密码错误。给予提示
            if [ $username != $db_username ];then
                echo "[ Warning ] The Username does't exist ! "
            else
                [ $password != $db_password ] && echo "[ Warning ] Wrong Password ! "
            fi
            [ $counts -eq 2 ] && exit
        fi
        let counts++
    done
    
    
    tty
    

    模仿红绿灯

    [root@abc 901]# cat signal.sh
    #!/bin/bash
    # 清屏
    clear
    #
    count=0
    
    while :
    do
        if [ $(expr $count % 3) -eq 0 ];then
            # 红灯亮时间
            red_time=5
            while :
            do
                echo -e "33[31m 红灯亮   ${red_time} 33[0m"
                sleep 1
                clear
                let red_time--
                [ $red_time -eq -1 ] && break
            done
        elif [ $(expr $count % 3) -eq 1 ];then
            # 绿灯亮时间
            green_time=3
            while :
            do
                echo -e "33[32m 绿灯亮   ${green_time} 33[0m"
                sleep 1
                clear
                let green_time--
                [ $green_time -eq -1 ] && break
            done
        else
            # 黄灯亮时间
            yellow_time=2
            while :
            do
                echo -e "33[33m 黄灯亮   ${yellow_time} 33[0m"
                sleep 1
                clear
                let yellow_time--
                [ $yellow_time -eq -1 ] && break
            done
    
        fi
        let count++
    done
    

    服务器状态监控

    先编写一个可发送邮件的 Python 程序:

    # python 脚本,放在 /usr/bin/ 目录下
    [root@k8s-master01 monitor_mail]# cat /usr/bin/mail
    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    import sys
    import smtplib
    import email.mime.multipart
    import email.mime.text
    
    server = 'smtp.163.com'
    port = '25'
    
    def sendmail(server,port,user,pwd,msg):
        smtp = smtplib.SMTP()
        smtp.connect(server,port)
        smtp.login(user, pwd)
        smtp.sendmail(msg['from'], msg['to'], msg.as_string())
        smtp.quit()
        print('Email has send out !!!~~~')
    
    
    if __name__ == '__main__':
        msg = email.mime.multipart.MIMEMultipart()
        msg['Subject'] = 'Monitor Warning Mail !!!'
        msg['From'] = 'wqh1XXXXX@163.com'
        msg['To'] = 'wqh2XXXXX@126.com'
        user = 'wqh1XXXXX'
        pwd = 'XXXXXXXXXX'
        # 格式处理,专门针对我们的邮件格式
        content='%s
    %s' %('
    '.join(sys.argv[1:4]),' '.join(sys.argv[4:]))  
    
        txt = email.mime.text.MIMEText(content, _charset='utf-8')
        msg.attach(txt)
    
        sendmail(server,port,user,pwd,msg)
    

    监控脚本:

    # bash 脚本,可以用定时任务执行
    [root@k8s-master01 monitor_mail]# cat monitor.sh
    #!/bin/bash
    
    # CPU阈值
    cpu_limit=0
    # 内存阈值
    mem_limit=0
    # 监控的磁盘分区
    disk_name="/dev/sda3"
    # 磁盘容量阈值
    disk_block_limit=0
    # 磁盘Inode阈值
    disk_inode_limit=0
    
    function monitor_cpu() {
        cpu_free=$(vmstat 1 5 | awk 'NR>=3{x=x+$15}END{print x/5}' | cut -d. -f1)
        cpu_used=$(echo "scale=0;100-${cpu_free}" | bc)
        cpu_stat=$cpu_used
        if [ $cpu_stat -gt $cpu_limit ];then
            msg=" DATETIME: $(date +%F_%T)
            HOSTNAME: $(hostname)
            IPADDR: $(hostname -I| awk '{print $1}')
            WARNING:
            CPU usage exceeds the limit,current value is ${cpu_stat}% !!!
            "
        fi
        echo -e $msg
        /usr/bin/mail $msg
    }
    
    function monitor_mem() {
        mem_total=$(free | awk 'NR==2{print $2}')
        mem_used=$(free | awk 'NR==2{print $3}')
        mem_stat=$(echo "scale=2;${mem_used}/${mem_total}" | bc | cut -d. -f2)
        if [ $mem_stat -gt $mem_limit ];then
            msg=" DATETIME: $(date +%F_%T)
            HOSTNAME: $(hostname)
            IPADDR: $(hostname -I| awk '{print $1}')
            WARNING:
            Memory usage exceeds the limit,current value is ${mem_stat}% !!!
            "
        fi
        echo -e $msg
        /usr/bin/mail $msg
    }
    
    function monitor_disk_block() {
        disk_block_used=$(df | awk 'NR==6{print $5}'|cut -d% -f1)
        disk_block_stat=$disk_block_used
        if [ $disk_block_stat -gt $disk_block_limit ];then
            msg=" DATETIME: $(date +%F_%T)
            HOSTNAME: $(hostname)
            IPADDR: $(hostname -I| awk '{print $1}')
            WARNING:
            Disk Block usage exceeds the limit,current value is ${disk_block_stat}% !!!
            "
        fi
        echo -e $msg
        /usr/bin/mail $msg
    }
    
    function monitor_disk_inode() {
        disk_inode_used=$(df -i | awk 'NR==6{print $5}'|cut -d% -f1)
        disk_inode_stat=$disk_inode_used
        if [ $disk_inode_stat -gt $disk_inode_limit ];then
            msg=" DATETIME: $(date +%F_%T)
            HOSTNAME: $(hostname)
            IPADDR: $(hostname -I| awk '{print $1}')
            WARNING:
            Disk Inode usage exceeds the limit,current value is ${disk_inode_stat}% !!!
            "
        fi
        echo -e $msg
        /usr/bin/mail $msg
    }
    
    
    monitor_cpu &>> /tmp/monitor.log
    monitor_mem  &>> /tmp/monitor.log
    monitor_disk_inode  &>> /tmp/monitor.log
    monitor_disk_block  &>> /tmp/monitor.log
    
    记录成长过程
  • 相关阅读:
    JS中的if语句内如何加or使多个条件通过
    对计算属性中get和set的理解
    如何在vue里实现同步阻塞请求,请求完成之前不加载页面或组件?
    vue 路由传参 params 与 query两种方式的区别
    vue中通过路由跳转的三种方式
    vue生成单文件组件和组件嵌套步骤
    this.$router.push() 在新窗口怎么打开
    Vue路由获取路由参数
    vue的v-for循环普通数组、对象数组、对象、数字
    element el-cascader设置默认值
  • 原文地址:https://www.cnblogs.com/zzzwqh/p/13567846.html
Copyright © 2020-2023  润新知