条件测试语句和 if 流程控制语句的使用

条件测试语句和 if 流程控制语句的使用

read命令

从键盘读取变量的值,通常用在 shell 脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在 read 命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量 REPLY

常见用法及参数
-p “提示信息”:等待 read 输入时,输出提示信息。
-t 秒数:read 命令会一直等待用户输入,使用此选项可以指定等待时间。
-n 字符数:read 命令只接受指定的字符数量,然后就会执行。
-s 隐藏输入内容,适用于机密信息的输入。
-r 参数输入,允许让输入中的内容包括: 斜线识别为普通字符。
-p 用于给出提示符

**例 1:从标准输入读取一行并赋值给变量**
[root@ ~]# read passwd

**例 2:读取多个值,从标准输入读取一行,直至遇到第一个空白符或换行符。把用户键入的第一个词存到变量 first 中,把该行的剩余部分保存到变量 last 中**
[root@ ~]# read first last
aaaa bbbb

**例 3:read -s passwd 将你输入的东西隐藏起来,值赋给 passwd。这个用户隐藏密码信息**
[root@ ~]# read -s passwd
[root@ ~]# echo $passwd
123456

**例 4:输入的时间限制**
[root@ ~]# read -t 2 username #超过两秒没有输入,直接退出,输入了,不敲回车,也不会保存变量值

**例 5:使用-r 参数输入,允许让输入中的内容包括: 斜线识别为普通字符。**
[root@ ~]# read line
\n
[root@ ~]# echo $line
n
[root@ ~]# read -r line
\n
[root@ ~]# echo $line
\n

**例 6:-p 用于给出提示符**
方法 1:
[root@ ~]# read -p "please input: " pass
please input: 123456
[root@ ~]# echo $pass
123456
 
 **例7:综合示例**
 [root@ ~]# vim test-read.sh #写入以下内容
#!/bin/bash
read -p "请输入姓名:" NAME
read -p "请输入年龄:" AGE
read -p "请输入性别:" SEX
cat<<eof
*********************
你的基本信息如下:
姓名: $NAME
年龄:$AGE
性别:$SEX
********************
eof

流程控制语句if

单支if语句

语法格式
if 条件
then
commands
fi

语句流程图在这里插入图片描述

示例:
:set paste
[root@ ~]# vim if0.sh 
#!/bin/bash
if ls /tmp
then
 echo "it's ok"
fi
根据我们的命令退出码来进行判断(echo $? =0),如果是 0,那么就会执行 then 后面的命令

双分支if语句

语法格式
if command ; then
commands
else
commands
fi
语句流程图
在这里插入图片描述

例1:
[root@ ~]# vim if1.sh 
#!/bin/bash
read -p "检查目录是否存在,请输入目录:" dir
if ls $dir &> /dev/null 
then
echo "目录存在"
else
echo "目录不存在"
fi

例 2:
[root@ ~]# vim if2.sh
#!/bin/bash
if grep "root:x" /etc/passwd;then
 echo "it's ok"
else
 echo "it's err"
fi
[root@ ~]# sh if2.sh 
root:x:0:0:root:/root:/bin/bash
it's ok

例 3:
[root@ ~]# vim if3.sh
#!/bin/bash
if grep "xuegod" /etc/passwd;then
 echo "it's ok"
else
 echo "it's err"
fi 
[root@xuegod63 ~]# sh if3.sh
it's err

多分支if语句

语法结构
if 条件测试操作 1 ; then
commands
elif 条件测试操作 2 ; then
commands
elif 条件测试操作 3 ; then
commands

else
commands
fi
语法流程图
在这里插入图片描述

例 :判断用户在系统中是否存在,是否有家目录
[root@ ~]# vim if4.sh
#!/bin/bash
read -p "input a user:" user
if grep $user /etc/passwd ; then
 echo "用户 $user 已存在"
elif ls -d /home/$user &> /dev/null ; then
 echo "$user 不存在,但家目录存在"
else
 echo "用户 $user 不存在"
 echo "$user 家目录不存在"
fi 
[root@ ~]# useradd user1
[root@ ~]# sh if4.sh 
input a user:user1
user1:x:1000:1000::/home/user1:/bin/bash
用户 user1 已存在
[root@xuegod63 ~]# userdel user1
[root@xuegod63 ~]# sh if4.sh 
input a user:user1
/home/user1
input a user:user1
user1 不存在,但家目录存在

[root@ ~]# sh if4.sh 
input a user:mask
用户 mask不存在
xuegod 家目录不存在

test测试命令

Shell 中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
格式:test 测试条件
如果结果是对的,也叫结果为真,用$?=0 表示,反之为假,用非 0 表示
equal 等于;not equal to 不等于;greater than 大于;less than 小于;

数值比较
在这里插入图片描述

例 1:比较大小
[root@ ~]# vim test1.sh 
#!/bin/bash
if test 2 -eq 1; then
 echo ok
else
 echo err
 fi
if [ 2 -eq 2 ];then
 echo ok
else
 echo err
fi

[root@ ~]# sh test1.sh
[root@ ~]# if test 2 -ne 1;then echo "true";else echo "false";fi
true
[root@ ~]# if test 1 -ne 1;then echo "true";else echo "false";fi
false
[root@ ~]# [ 3 -ge 2 ] && echo "true" || echo "false" #注意括号中的空格
true
[root@  ~]# [ 2 -ge 2 ] && echo "true" || echo "false"
true
[root@  ~]# [ 1 -ge 2 ] && echo "true" || echo "false"
false
[root@  ~]# vim test2.sh 
#!/bin/bash
read -p "请输入第一个整数" a
read -p "请输入第二个整数" b
if [ $a -lt $b ];then
 echo "$a 小于$b "
else
 echo "$a 不小于$b"
fi
[root@ ~]# sh test2.sh

字符串比较
在这里插入图片描述

例 1:根据用户名判断是否是超级管理员
[root@ ~]# vim test3.sh 
#!/bin/bash
read -p "请输入你的名字" name
if [ $name == "root" ];then
 echo "管理员"
else
 echo "不是管理员"
fi
[root@ ~]# [ -z "111111111" ] #长度不为零为假
[root@ ~]# echo $?
1
[root@ ~]# [ -z "" ] #长度为零为真
[root@ ~]# echo $?
0
[root@ ~]# test -n "111111111" #长度不为空为真
[root@ ~]# echo $?
0
[root@ ~]# test -n "" #长度为空为假
[root@ ~]# echo $?
1

文件比较
在这里插入图片描述

[root@  ~]# [ -e /etc/passwd ] && echo "true" || echo "false" tree
[root@  ~]# [ -e /etc/pass ] && echo "true" || echo "false" false
可以创建一个空文件,和-s 对比一下
[root@ ~]# touch aaa
[root@ ~]# [ -s aaa ];echo $?
1
[root@ ~]# echo hello > aaa
[root@ ~]# test -s aaa;echo $?
0
[root@ ~]# > aaa
[root@ ~]# test -s aaa;echo $?
1

例 1:
[root@ ~]# vim /tmp/test5.sh 
#!/bin/bash
if [ -w /etc/passwd ];then
 echo ok
else
 echo err
fi
[root@ ~]# sh /tmp/test5.sh
ok
[root@ ~]# useradd user1
[root@ ~]# su - user1
[user1@ ~]$ sh /tmp/test5.sh
err
[user1@ ~]$ exit
[root@ ~]# chmod a+w /etc/passwd
[root@ ~]# su - user1
[user1@ ~]$ sh /tmp/test5.sh
ok

清空日志目录

示例:
[root@ ~]# vim /tmp/log.sh 
#!/bin/bash
# 这是清空日志脚本
# 判断当前用户是否为 root
if [ $USER != "root" ];then
 echo "脚本需要 root 用户执行"
 exit 10 #直接退出,并返回 10
fi
# 判断文件是否存在,!取反
#文件存在的情形下,-f /var/log/messages,为真,取反,表达式结果为假。不会执行 then 后面的内容,echo "文件不存在" #文件不存在的情形下,-f /var/log/messages,为假,取反,表达式结果为真。会执行 then 后面的内容,echo "文件不存在"
if [ ! -f /var/log/messages ];then
echo "文件不存在"
 exit 12
fi
# 保留最近 100 行的日志内容。
tail -100 /var/log/messages > /var/log/mesg.tmp
# 日志清空
> /var/log/messages
mv /var/log/mesg.tmp /var/log/messages
echo "log clean up" 
exit #退出 bash,并返回一个值 注:退出码 exit ,取值范围是 0-255,超过后值循环 0-255
[root@ ~]# sh /tmp/log.sh
log clean up
# 只保留10天内的日志
find  【文件名】-mtime +10 -name “*.(文件后缀名)” -exec rm rf {} \;

流程控制过程中复杂条件和通配符

两个条件都为真或有一个为真就执行

if [ 条件判断一 ] && [ 条件判断二 ]; then 
 命令一
elif [ 条件判断三 ] || [ 条件判断四 ]; then
 命令二
else
 执行其它
fi
#!/bin/bash
if [ -d /etc ] && [ -d /root ];then
 echo "etc 和 root 目录都存在"
 fi
if [ -d /etc ] || [ -d /root ];then
 echo "etc 或 root 目录至少有一个存在"
fi

[[ 。。。 ]]和[ 。。。],() 和(())的区别汇总:

()单小括号:
多条命令执行:
括号中的命令将会新开一个子 shell 顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。

单小括号,(cmd1;cmd2;cmd3) 新开一个子 shell 顺序执行命令 cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后可以没有分号。
[root@ ~]# (cc=1;dd=2,ee=3)
[root@ ~]# echo $cc $dd $ee

多条命令执行:

{} 花括号,大括号,{ cmd1;cmd2;cmd3;} 在当前 shell 顺序执行命令 cmd1,cmd2,cmd3, 各命
令之间用分号隔开, 最后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。
[root@ ~]# { c=1;d=2;e=3;}
[root@ ~]# echo $c $d $e

1、所有的字符与逻辑运算符直接用“空格”分开,不能连到一起。
2、在[… ]表达式中,常见的> 、<需要加转义符\,大小比较
3、进行逻辑运算符&& 、||比较时;如果用的[ ]符号,则用在外面,如[… ] && [… ] || [ …]如果在[…]里面进行逻辑与或的比较,则用-a、-o 进行表示,如[ x = y –a x < z –o x > m ]
4、[[… ]] 运算符只是[… ]运算符的扩充;能够支持< 、>符号运算不需要转义符;它还是以字符串比较大小。里面支持逻辑运算符 || 、 && , 不再使用-a 、-o
5、[[…]] 用 && 而不是 -a 表示逻辑“与”;用 || 而不是 -o 表示逻辑“或”
6、[[… ]]可以进行算术扩展,而[ … ]不可以
7、[[…]]能用正则,而[…]不行
8、双括号(( ))用于数学表达式
9、双方括号号[[ ]]用于高级字符串处理,比如“模糊匹配”
10、[[]]对于字符串的比较支持并不好,尤其在使用[[]]和<>符号进行比较的时候会出现返回值错误的情况。

常见通配符
在这里插入图片描述

例:
[root@ ~]# ls /etc/*.conf
[root@ ~]# ls /etc/???.conf
/etc/nfs.conf /etc/sos.conf /etc/yum.conf
[root@ ~]# touch /opt/a{1,2,3}.txt
[root@ ~]# ls /opt/a[13].txt
/opt/a1.txt /opt/a3.txt
[root@ ~]# ls /opt/a[!12].txt
/opt/a3.txt
[root@ ~]# ls /opt/a[1-3].txt
/opt/a1.txt /opt/a2.txt /opt/a3.txt

实践脚本

编写脚本检查服务器运行状态

[root@ ~]# vim status.sh
#!/bin/bash
if [ $# -ge 1 ] ;then
 systemctl status $1 > /dev/null
 if [ $? -eq 0 ] ;then
 echo "$1 服务正常运行"
 else
 systemctl start $1
 echo "$1 服务没有运行,已经尝试启动该服务"
 fi
else
 echo "执行脚本的格式"
 echo "sh $0 服务名"
fi
[root@ ~]# systemctl stop rsyslog
[root@ ~]# sh status.sh rsyslog
rsyslog 服务没有运行,已经尝试启动该服务
[root@ ~]# sh status.sh rsyslog
rsyslog 服务正常运行

编写脚本每晚凌晨3点备份/etc目录,并以日期命名备份文件,且只保留最近15天的备份文件,非root用户运行该脚本提示:脚本需要root用户执行并退出。

[root@ ~]# cat etcbak.sh 
#!/bin/bash
if [ $USER != "root" ]
then
    echo "脚本需要root用户执行"
    exit 10 #直接退出,并返回10
fi
baknamefile=`date +%y-%m-%d`
bakdir=/etcbak
srcdir=/etc
if ls $bakdir &> /dev/null
then
    echo "目录存在"
else
    mkdir -p $bakdir
    echo "目录不存在,但是已经创建"
fi
tar czvf ${bakdir}/${baknamefile}-etc.tar,gz ${srcdir}
find $bakdir -mtime +15 -name "*.tar.gz" -exec rm rf {} \;
echo "=========backup success======="

[root@ ~]# chmod +x etcbak.sh
[root@ ~]# ./etcbak.sh
[root@ ~]# crontab -e
0 3 * * * /root/etcbak.sh &> /dev/null
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值