Linux下的shell(三):普通脚本的编写

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Leslie_qlh/article/details/100065415

Linux下的shell(三):普通脚本的编写

文章目录

1.脚本中的语句控制器

exit n		脚本退出,退出值为n
break		退出当前循环
continue	提前结束循环内部的命令,但不终止循环

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.if判断语句

使用if语句可以对条件进行依次判断。

格式:
if 	如果(判断条件1)
then			那么
	(满足条件1要执行的动作)	
elif	又如果(判断条件2)
then		那么
	(满足条件1要执行的动作)	
...		...
else	否则(以上所有条件都不满足)
	(都不满足时要执行的动作)
fi		结尾

【1】编写脚本实现功能:使用if语句编写脚本,实现输入命令调用相应功能

vim filectrl.sh 

#!/bin/bash
        [ -z "$1" ]&&{			判断是否输入命令
                echo -e "\033[31mPlease input scrip first[-a or -d or -p]! following $0\033[0m"
                }
        [ -z "$2" ]&&{			判断是否输入相应文件
                echo -e "\033[31mPlease input filename following scrip ! \033[0m"
                exit 0
                }
        if [ "$1" = "-d" ]		当输入的命令为“-d”时,删除相应文件
        then
                `rm -fr "$2"`
                echo -e "\033[32m$2 is deleted...\033[0m"
        elif [ "$1" = "-a" ]		当输入的命令为“-a”时,判断文件是否存在,如果存在则报错,不存在则新建相应文件
        then
		 [ -e "$2" ]&&{
                        echo -e "\033[31m$2 is exist...\033[0m"
                        }||{
                `touch "$2"`
                echo -e "\033[32m$2 is added...\033[0m"
                        }
        elif [ "$1" = "-p" ]		当输入的命令为“-p”时,对相应文件进行备份,如果备份文件已存在则进行提示
        then
		 [ -e "${2}.bak" ]&&{
                        echo -e "\033[31m${2}.bak is exist...\033[0m"
                        }||{
                cp $2 ${2}.bak 
                echo -e "\033[32m$2 is copy...\033[0m"
                        }
        else				当输入的命令是其他命令是,提示输入正确命令
                echo -e "\033[31mPlease input -a or -d or -p following $0...\033[0m"
        fi

在这里插入图片描述
在这里插入图片描述

【2】编写脚本实现功能:使用if语句,输入文件名查看文件类型

#!/bin/bash
READ()					设定函数
{
        read -p "Please input filename [or exit to quit] : " NAME	获取文件名变量
        if [ "$NAME" = "exit" -o "$NAME" = "EXIT" ]	当输入“exit”时,直接退出
        then
                echo -e "\033[31mbye~\033[0m"
                exit 0
	elif [ -L "$NAME" ]				判断文件是否为软链接
        then
                echo -e "\033[32m$NAME is softlink file...\033[0m"
        elif [ -d "$NAME" ]				判断文件是否为目录
        then
                echo -e "\033[32m$NAME is direcotry...\033[0m"
       
        elif [ -f "$NAME" ]				判断文件是否为规则文件
        then
                echo -e "\033[32m$NAME is common file...\033[0m"
        else						如果都不是则报错并重新再次执行函数
                echo -e "\033[31m$NAME is not exist...\033[0m"
                READ
        fi
}
READ					执行函数

在这里插入图片描述
在这里插入图片描述

3.case判断语句

使用case语句可以对条件进行同时判断,相对于if判断语句效率更高。

格式:
case #变量# in
	判断条件1)
		(满足条件1需要执行的动作)	
	;;
	判断条件2)
		(满足条件2需要执行的动作)	
	;;
	判断条件3)
		(满足条件3需要执行的动作)	
	;;
	*)		(不满足以上条件的其他条件)
		(以上条件均不满足需要执行的动作)	
esac

【3】编写脚本实现功能:使用case语句,实现输入命令与文件,调用相应功能对文件进行操作

#!/bin/bash
if [ "$#" -lt "2" ]			判断脚本后的字符串是否够两个(判断用户是否正确输入命令与文件)
then
        echo -e "\033[31mError:Please input option [-a|-p|-d] and filename following $0\033[0m"
        exit 0
fi

case $1 in				使用case对命令变量进行判断
        -d|-D|d|D)			如果是-d|-D|d|D	,则执行删除命令
        rm -fr $2
                echo -e "\033[32m$2 is deleted!!!\033[0m"
        ;;
        -a|-A|a|A)			如果是-a|-A|a|A	,则执行新建命令
        [ -e "$2" ]&&{			判断文件是否存在,存在则报错并退出,不存在则直接新建
                echo -e "\033[31m$2 is exist...\033[0m"
                exit 0
                }||{
        touch $2
                echo -e "\033[32m$2 is created!!!\033[0m"
                }
        ;;
        -p|-P|p|P)			如果是-p|-P|p|P,则进行备份
        [ -e "/mnt/${2}.bak" ]&&{			判断备份文件是否存在,如果存在则报错并退出,不存在则进行备份
                echo -e "\033[31m${2}.bak is exist...\033[0m"
                exit 1
                }||{
        cp $2 ${2}.bak &> /dev/null
                echo -e "\033[32m$2 is copy!!!\033[0m"
                }
        ;;
        *)				如果都不是则进行提示
          echo -e "\033[31mError:Please input option [-a|-p|-d] and filename following $0\033[0m"
esac

在这里插入图片描述
在这里插入图片描述

4.expect语句

expect 自动应答命令,用于交互式命令的自动执行
spawn expect中的监控程序,其运行后监控命令提出的交互问题
send 发送问题答案交给交互命令
\r 表示回车
exp_continue 表示方问题不存在时继续回答下面的问题
expect eof 表示问题回答完毕退出expect环境
interact 表示问题回答完毕留在交互界面
set NAME [ lindex $argv n ] 定义变量
部属expect:
yum install expect -y
systemctl start expect
systemctl enable expect

【4】使用expect语句编写脚本实现功能:输入ip和密码,实现自动ssh连接

#!/user/bin/expect
set IP [ lindex $argv 0 ]		设定变量IP是命令后的第一个字符串
set PWD [ lindex $argv 1 ]		设定变量PWD是命令后的第二个字符串
spawn ssh root@$IP			对"ssh"动作进行监听
expect {
        "(yes/no)?"      {send "yes\r";exp_continue}		设定当遇到"(yes/no)?"时,填写“yes“并回车
        "password:"      {send "$PWD\r"}			设定当遇到"password"时,填写“$PWD变量“并回车
}
interact				表示不结束(expect eof 则表示结束)

在这里插入图片描述
在这里插入图片描述

【5】使用expect语句编写脚本实现功能:自动测试十台主机是否可以ping,可以则显示主机名

#!/bin/bash
Connect()		定义函数
{
/usr/bin/expect <<EOF		输出重定向至expect环境
spawn ssh root@$1 $2		对"ssh"动作进行监听
expect {
"(yes/no)?" { send "yes\r";exp_continue }	设定当遇到"(yes/no)?"时,填写“yes“并回车
"password:" { send "westos\r" }		设定当遇到"password"时,填写“$PWD变量“并回车
}
expect eof	表示问题回答完毕退出expect环境
EOF
}
for IP in {1..10}	设置变量IP的范围为1-10
do
        ping -c1 -w1 172.25.254.$IP &> /dev/null	尝试ping
        if [ "$?" = "0" ]		如果成功则显示主机名
        then
                Connect 172.25.254.$IP hostname | tail -n 1	调用函数
        fi
done

在这里插入图片描述
在这里插入图片描述

【6】编辑脚本实现功能:执行命令后建立名单中的用户,并设定密码为指定文件中的密码。当执行脚本时没有输入用户名单以及密码文件时、当用户名单与密码文件的行数不同时、当有文件不存在时、当新建的用户已存在时均报错。

vim users_create.sh

#!/bin/bash
        if [ "$#" -lt "2" ]		判断是否输入了用户名单以及密码文件,如果没有输入两个文件则报错并退出
        then
                echo -e "\033[31mPlease input userlist and passlist following $0 !!!\033[0m"
                exit 0
        fi
        [ "$1" = "0" -o "$2" = "0" ]&&{		判断输入的两个文件是否存在
                echo -e "\033[31mPlease input right file !!! \033[0m"
                exit 1
        }

    NAME=`awk 'BEGIN{N=0}{N++}END{print N}' $1`	统计用户名单的行数
    PWD=`awk 'BEGIN{M=0}{M++}END{print M}' $2`	统计密码文件的行数
    if [ "$NAME" -ne "$PWD" ]	当两个文件行数不一致时,报错并退出
   then
            echo -e "\033[31mPlease input right file !!! \033[0m"
            exit 2
    fi
    for NUM in `seq 1 $NAME`	设定NUM变量的取值范围(从1用户名单的总行数)
    do
            USERNAME=`sed -n ${NUM}p $1`	设定用户名变量
            PASSWORD=`sed -n ${NUM}p $2`	设定用户密码变量
            useradd $USERNAME &> /dev/null &&{	添加用户,如果成功则进行改密
            echo $PASSWORD | passwd --stdin $USERNAME &> /dev/null		为新加用户设置密码
            echo -e "\033[32m$USERNAME is created ! \033[0m"
            }||{				添加失败则提示用户已存在
            echo -e "\033[31m$USERNAME is exist !!! \033[0m"
    }
   done

在这里插入图片描述
在这里插入图片描述

【7】编辑脚本实现功能:执行脚本并输入密码后会备份数据库中的所有库到/mnt/db/musqldump目录中。并且备份文件名称为“库名称.sql”,当此文件存在时报错并询问动作:输入“S”跳过备份,输入“B”时备份“库名词.sql”文件为“库名称_backup.sql”,输入“O”则覆盖源文件。

vim db_dump.sh 

#!/bin/bash
ACTION()		定义函数ACTION
{
        case $CHOOSE in		使用case语句定义变量CHOOSE
                S|s)		当变量CHOOSE为“S”或“s”时执行退出命令
                        exit 0
                ;;
                B|b)		当变量CHOOSE为“B”或“b”时自动备份已存在的文件并备份数据库
                        mv /mnt/db/mysqldump/${DATABASE}.sql /mnt/db/mysqldump/${DATABASE}_backup.sql
                        mysqldump -uroot -p"$1" $DATABASE  > /mnt/db/mysqldump/${DATABASE}.sql
                        echo -e "\033[32m${DATABASE} is dumped successfully !!!\033[0m"
                ;;
                O|o)		当变量CHOOSE为“O”或“o”时覆盖已存在的文件	
                        mysqldump -uroot -p$1 $DATABASE > /mnt/mysqldump/db/${DATABASE}.sql
                        echo -e "\033[32m${DATABASE} is dumped successfully !!!\033[0m"
                ;;
                *)		当变量CHOOSE时其他数据时进行报错,并重新执行ACTION函数
                         echo -e "\033[31mError:Please input right choose !!! \033[0m"
                        ACTION
        esac			结尾
}

        if [ ! -e "/var/lib/mysql/mysql.sock" ]		判断数据库是否开启,未开启则报错并退出脚本
        then
                echo -e "\033[31mMysql is not running !!!\033[0m"
                exit 1
        fi

        if [ -z "$1" ]			判断是否已经输入密码,没有则报错并退出脚本
        then
                echo -e "\033[31mPlease input password for Mysql following $0 !!\033[0m"
                exit 2
        fi


        mysql -uroot -p$1 -e "SHOW DATABASES;" &> /dev/null	使用输入的密码尝试查看数据库,判断输入的密码是否正确

        if [ ! "$?" = "0" ]	判断退出值是否为0(判断输入的密码是否正确),不是0时(不正确)则报错并退出脚本
        then
                echo -e "\033[31mPassword error !!!\033[0m"
                exit 3
        fi

        for DATABASE in `mysql -uroot -pwestos -e "SHOW DATABASES;" -EN | grep -E '\*|schema$' -v`	采集并定义数据库名变量
        do
                [ -d "/mnt/db/mysqldump" ] || mkdir -p /mnt/db/mysqldump		判断备份的目录是否存在,不存在则自动新建目录
		if [ ! -e "/mnt/db/mysqldump/${DATABASE}.sql" ]			判断备份文件如果不存在就执行备份动作
		then
                mysqldump -uroot -p$1 $DATABASE > /mnt/db/mysqldump/${DATABASE}.sql
                echo -e "\033[32m${DATABASE} is dumped successfully !!!\033[0m"
		else								如果备份文件存在则进行提示,剧提示进行相关动作
                read -p "The ${DATABASE}.sql is exist,please choose [S]kip or [B]ackup or [O]ver : " CHOOSE
                ACTION westos
		fi
		done
	

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.shell中常用的运算命令

运算操作与运算命令 含义
(()) 用于整数运算
let 用于证书运算,与(())类似
expr 用于整数运算,功能相对较多
bc linux下的计算器,适合整数和小数的运算
$[] 用于整数运算

【8】编辑脚本实现功能:进行数字运算

运用bc进行计算:
vim bc.sh

#!/bin/bash
        read -p "请输入您要操作的数字:" N
        read -p "请输入要操作的运算:" T
        read -p "请输入要操作的第二个数字:" M

bc<<EOF
${N}${T}${M}

EOF

在这里插入图片描述
在这里插入图片描述

运用运算符进行计算(无法运算小数):
vim jisuanji.sh

#!/bin/bash
        read -p "请输入您要操作的数字:" N			采集变量“N”
        read -p "请输入要操作的运算:" T			采集变量“T”
        read -p "请输入要操作的第二个数字:" M		采集变量“M”

    case $T in				对变量“T“进行判断
            +)				“T”为“+”时,进行加法运算,赋值给变量“NUM”
                    let NUM=${N}+${M}
            ;;
            -)				“T”为“-”时,进行减法运算,赋值给变量“NUM”
                    let NUM=${N}-${M}
            ;;
            \*)				“T”为“*”时,进行乘法运算,赋值给变量“NUM”
                   let NUM=${N}*${M}
            ;;
            /)				“T”为“/”时,进行除法运算,赋值给变量“NUM”
                    let NUM=${N}/${M}
            ;;
            %)				“T”为“%”时,进行取余运算,赋值给变量“NUM”
                    let NUM=${N}%${M}
            ;;
            \**)			“T”为“**”时,进行幂运算,赋值给变量“NUM”
                    let NUM=${N}**${M}
    esac
    echo -e "\033[32m结果为:$NUM\033[0m"		显示变量“NUM”

在这里插入图片描述
在这里插入图片描述

【9】编辑脚本实现功能:实现1分10秒的倒计时

vim daojishi.sh

#!/bin/bash


for NUM in {70..1}		定义变量NUM取值范围为1-70
do
        let MIN=$NUM/60		对分的变量“MIN”进行取值
        let SEC=$NUM%60		对秒的变量“SEC”进行取值
        echo -ne "\033[32mAftrer ${MIN}m:${SEC}s will end ... \033[0m"	进行显示
        echo -ne "\r"		每次变化都进行覆盖
        sleep 1			延迟一秒执行
done

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Leslie_qlh/article/details/100065415
今日推荐