字符串比对
字符串必须使用双引号
[ "name" = "name" ]   #可以用,但不推荐
[ "name" == "name" ]  #推荐使用 == 判断是否等于
[ "name" != "name" ]
#示例
[root@shell01 ~]# echo $USER
root
[root@shell01 ~]# [ "$USER" = "root" ]
[root@shell01 ~]# echo $?
0
[root@shell01 ~]# [ "$USER" = "alex" ]
[root@shell01 ~]# echo $?
1
[root@shell01 ~]# [ "$USER" != "alex" ]
[root@shell01 ~]# echo $?
0
参数:
-z    字符串长度为0则为真
-n    字符串长度不为0则为真
[root@shell01 ~]# name=""
[root@shell01 ~]# [ -z $name ]
[root@shell01 ~]# echo $?
0
[root@shell01 ~]# [ ! -z $name ]
[root@shell01 ~]# echo $?
1
[root@shell01 ~]# name="alex"
[root@shell01 ~]# [ -n $name ]
[root@shell01 ~]# echo $?
0
#案例:
[root@shell01 scripts]# vim name.sh
#!/bin/bash
read -p "请输入名字" name1
[ -z $name1 ] && echo "请输入名字否则不继续执行" && exit
echo $name1
 
正则比对
[[]]  #格式
[root@shell01 scripts]# [[ "$USER" =~ ^r ]]  #正则匹配用=~, 后面的正则内容不能加单/双引号
[root@shell01 scripts]# echo $?
0
[root@shell01 scripts]# [[ ! "$USER" =~ t$ ]]    #取反
[root@shell01 scripts]# echo $?
1
#在进行正则比较的时候,必须使用双中括号,正则比较,除非是变量需要使用双引号,其他的值一律不允许使用引号
#判断是否为纯数字
[root@shell01 scripts]# age=188
[root@shell01 scripts]# [[ "$age" =~ ^[0-9]+$ ]]
[root@shell01 scripts]# echo $?
0
#判断是否全为字母
[root@shell01 scripts]# [[ "$Name" =~ ^[a-Z]+$ ]] && echo "为真" || echo "为假"
# * 匹配前面的字符出现0次或者0次以上
# + 匹配前面的字符出现1次或者1次以上
 
多整数比对(多条件比较)
-a    and
-o    or
&&   并且  #必须使用双中括号
||   或者  #必须使用双中括号
[ 10 -eq 10 -a 100 -ne 100 ]        #10等于10,并且100不等于100
[root@shell01 scripts]# [ 10 -eq 10 -a 100 -ne 100 ]
[root@shell01 scripts]# echo $?
1
[root@shell01 scripts]# [ 10 -eq 10 -o 100 -ne 100 ]    #(10=10) or (100!=100)
[root@shell01 scripts]# echo $?
0
#如果使用[[]],正则比较    就要使用&&表示and,||表示or
[root@shell01 scripts]# [[ 10 -eq 10 && 100 -ne 100 ]]
[root@shell01 scripts]# [[ 10 -eq 10 || 100 -ne 100 ]]
#案例
传入两个数字 对比两个数字的大小
[root@shell01 scripts]# vim compare.sh
#!/bin/bash
[ $# -ne 2 ] && echo "please input two number" && exit    #传入数字必须是2个
[[ ! $1 =~ ^[0-9]+$ ]] && echo "请输入整数" && exit 50     #exit退出,$?获取值为50
[[ ! $2 =~ ^[0-9]+$ ]] && echo "请输入整数" && exit 100
[ $1 -eq $2 ] && echo "$1=$2"
[ $1 -gt $2 ] && echo "$1>$2"
[ $1 -lt $2 ] && echo "$1<$2"
#案例:批量创建用户 批量创建10个用户 oldboy1 oldboy2 oldboy3...oldboy10
    要求密码统一设置为123456
#!/bin/bash
read -p "please input prefix: " name
read -p "创建的个数: " num
for i in `seq $num`    #seq为一个序列
do
    useradd $name$i >/dev/null 2>&1
    echo 123456|passwd --stdin $name$i &>/dev/null
    [ $? -eq 0 ] && echo "$name$i create is ok"
done
#网络相关
#案例:判断当前10.0.0.0/24网络中 有哪些IP地址在线 ping通则在线
#通过24掩码判断,可用范围10.0.0.1-254,在这个范围内进行测试
[root@shell01 scripts]# cat ping.sh
#!/bin/bash
[ -f /etc/init.d/functions ] && . /etc/init.d/functions    #加载函数库,下方可以用action
for i in `seq 254`
do
    {     IP=10.0.0.$i
    ping -c 1 -W 1 $IP >/dev/null 2>&1
    [ $? -eq 0 ] && action "ping $IP is" /bin/true
    } &    #使用{} &把方法后台运行,多线程运行,提速(几乎1秒钟内完成)
done
#一个网卡添加多个ip地址
ip addr add 10.0.0.3/24 dev eth0    #临时生效 重启失效
#网卡删除ip地址
ip addr del 10.0.0.3/24 dev eth0
#面试题: 配置一条默认网关
route add default gw 10.0.0.253
#删除网关
route del default gw 10.0.0.253
#其他方式添加网关 静态路由方式
ip route add 0/0 via 10.0.0.254    #ip route添加路由  0/0可以去任意网段  10.0.0.254通过这个地址去
#策略路由
服务器使用vpn常用 网关被替换成vpn
pptpstup 拨号命令(导致原来的网关没了,变成vpn服务器的网关,需要其他方式处理)
#查看网关
route -n
#开机启动配置文件(/etc/rc.local) +x权限    #开机执行命令要写在这个文件中  (禁止用alias和变量)
 
 
1. if判断
#单分支
#if后面是条件,[]可以进行判断;可以不用[]改成一组命令,判断命令是否执行成功
if [你有房];then        #[ -f file ] && echo ok
#另一种写法
if [你有房]
then
    我就嫁给你
fi
#双分支
if [ 你有房 ]            #[ -f file ] && echo ok || echo error
then
    我就嫁给你
else
    拜拜
fi
if [];then
else
fi
#多分支
if [ 你有房 ]
then
    我就嫁给你
elif [ 你有钱 ]
then
    我也嫁给你
elif [ 你爸是李刚 ]
then
    我也嫁给你
elif [ 活好!运维技术好 ]
then
    我倒贴也嫁给你
else    #可以不使用else
    拜拜
fi
if [];then
elif [];then
elif [];then
else
fi
#案例:猜数字        笔试题
生成一个随机数1-100之间,用户输入一个数字,判断数字是否正确,不正确提示大了还是小了
RANDOM 随机数的范围 0-32767
取余    echo $((RANDOM%100+1))
[root@shell01 scripts]# vim ran.sh
#!/bin/bash
ran=`echo $((RANDOM%100+1))`
while true
do
    let i++
read -p "请输入一个数字[1-100]: " num
if [ $num -gt $ran ];then
    echo "你输入的数字大了"
elif [ $num -lt $ran ];then
    echo "你输入的数字小了"
else
    echo "恭喜你才对了 总共猜了 $i 次"
    exit
fi
done
 
2. 流程控制语句之文件比较
[root@shell01 scripts]# vim if-1.sh
#!/bin/bash
read -p "请输入要测试的文件: " File
if [ -f $File ];then
    echo "$File  文件存在"
else
    echo "$File 文件不存在"
fi
#案例
备份数据库
1.备份数据库命令    mysqldump -uroot -p123 -B db_name > mysql.sql
2.备份到哪里        /backup/mysql
3.提示用户输入要备份的数据库        read -p
4.备份之后的数据库名称    时间属性信息+数据库名称.sql
[root@shell01 scripts]# vim backup.sh
#!/bin/bash
#1.定义相关变量
Back_Dir=/bacup/mysql
Date=$(date+%F)
#2.判断备份目录是否存在,不存在则创建
[ -d $Back_Dir ] || mkdir -p $Back_Dir
#3.根据用户输入要备份的目录
read -p "请输入要备份数据库的账号名称: " M_User
read -s -p "请输入${M_User}数据库账号的密码: " M_Pass #-s输入的时候不显示内容,安全
echo    #调整上面的格式,不然上面输完不会换行
read -p "请输入要备份的数据库名称: " Db_Name
#4.根据用户输入的数据库名称进行备份
mysqldump -u$M_User -p$M_Pass -B $Db_Name > $Back_Dir/${Db_Name}_${Date}.sql #备份数据命令后面不要将执行结果定向到空!
#5.根据备份的结果进行判断
if [ $? -eq 0 ];then
    echo "数据库$Db_Name 备份成功....."
else
    echo "数据库$Db_Name 备份失败....."
fi
 
3.流程控制语句之整数比较
#linux系统中比较数字大小,一般都是整数比较
#实例
编写一个脚本,监测一个服务是否在运行状态
    1.怎么判断一个服务是否在运行中    
    用systemctl status查服务,$?查返回值
    当服务在运行状态下    返回值是0
    当服务没有在运行状态下    返回值是3
    当系统没有这个服务    返回值是4
    当输入的服务名称是数字时    返回值是1或者其他
[root@shell01 scripts]# vim if-6.sh
#!/bin/bash
#1.提示用户输入一个要进行检测的服务名称
read -p "请输入一个你要检测的服务名称: " Server
#2.查看这个服务是否在运行中
systemctl status $Server &>/dev/null
#3.根据服务的返回值进行判断
Rc=$?
if [ $Rc -eq 0 ];then
    echo "$Server 服务正在运行中......"
elif [ $Rc -eq 3 ];then
    echo "$Server 没有在运行中......"
elif [ $Rc -eq 4 ];then
    echo "$Server 没有这个服务!"
else
    echo "系统运行中的所有服务没有这个PID号存在!"
fi
#实例
创建用户,判断用户是否存在,不存在时创建。判断是否创建成功
[root@shell01 scripts]# vim if-7.sh
#!/bin/bash
#1.提示用户输入要创建的用户
read -p "请输入你要创建的用户: " User
#2.判断要进行新创建的用户是否存在
id $User &>/dev/null
if [ $? -eq 0 ];then
    echo "用户$User 已经存在!"
else
    #3.不存在则进行创建用户
    useradd $User &>/dev/null
    #4.判断用户是否创建成功
    if [ $? -eq 0 ];then
        echo "用户$User 创建成功!"
    else
        echo "用户$User 创建失败!"
    fi
fi
 
4.流程控制语句场景示例
1.清空/var/log/messages日志,保留最近的100行内容,且只能是超级管理员root才有权限执行这个脚本
    1.必须是root用户才有权限执行这个脚本
    2.清空/var/log/messages日志,判断这个日志文件是否存在
    3.清空之后还要保留最近的100行内容
    
[root@shell01 scripts]# vim clear_log.sh
#!/bin/bash
#1.判断当前的用户是否是超级管理员root用户
if [ "$USER" == "root" -a "$UID" -eq 0 ];then    #$UID为0说明是超级管理员
    #2.判断/var/log/messages日志文件是否存在
    File=/var/log/messages
    if [ -f $File ];then
        #不能对文件操作再重定向到该文件(否则文件会为空)
        tail -100 $File > ${File}.bak && mv -f ${File}.bak $File &>/dev/null #强制覆盖
        #3.判断日志是否清空和保留成功
        if [ $? -eq 0 ];then
            echo "${File}清空成功!且保留了最近的100行内容!"
        else
            echo "${File}清空失败!保留失败!"    
        fi
    else
        echo "${File}日志文件不存在"
    fi
else
    echo "${USER}用户没有权限执行该脚本! "
fi
2.判断一个服务是否在正常运行
    1.判断其是否在运行中 systemctl status sshd
    2.判断端口号是否存在 netstat -lntp |grep sshd
    3.判断服务进程是否存在 ps aux |grep sshd |grep -Ev 'grep|pts'    #pts为执行窗口号,要过滤(即使sshd停止也存在)
[root@shell01 scripts]# vim check_service.sh
#!/bin/bash
#1.判断脚本的位置变量是否只有一个
if [ $# -ne 1 ];then
    echo "Usage: $0 {sshd|nginx|mariadb|nfs}"
    exit
fi
#2.0.判断服务是否是rsync
if [ $1 == "rsync" ];then
    Server1=rsyncd
else
    Server1=$1
fi
#2.判断服务是否在运行中
systemctl status ${Server1} &>/dev/null
#3.根据命令的执行结果进行判断服务在什么状态
Rc=$?
if [ $Rc -eq 0 ];then
    ehco "${1}服务正在运行中....."
elif [ $Rc -eq 3 ];then
    echo "${1}服务没有运行中....."
elif [ $Rc -eq 4 ];then
    echo "系统中没有安装这个${1}服务!"
    exit
else
    echo "当前系统中没有正在运行的服务进程ID为$1"
    exit
fi
#4.0.判断服务是否是mariadb
if [ $1 == "mariadb" ];then
    Server=mysqld
else
    Server=$1
fi
#4.判断服务端口号是否存在
netstat -lntp |grep $Server &>/dev/null
#5.根据命令的执行结果进行判断服务是否存在端口号
if [ $? -eq 0 ];then
    echo "${1}服务端口号存在...."
else
    echo "${1}服务端口号不存在...."
fi
#6.判断服务的进程是否存在
ps aux |grep $1 |grep -Ev 'grep|pts' &>/dev/null
#7.根据命令的执行结果进行服务是否存在进程
if [ $? -eq 0 ];then
    echo "${1}服务进程存在...."
else
    echo "${1}服务进程不存在...."
fi