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
记录成长过程
原文地址:https://www.cnblogs.com/zzzwqh/p/13567846.html