学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用

目录

学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用


本文用于记录学习体会、心得,兼做笔记使用,方便以后复习总结。内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK老师和学神教育的优质教学。希望各位因学习需求而要进行转载时,能申明出处为学神教育,谢谢各位!


假期归来,满血复活,满状态开搞,加油!

21.1 read命令键盘读取变量的值

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

read从键盘读入数据,赋给变量


[root@CentOs7_64_1_128 ~]# read a b
aaa bbb
[root@CentOs7_64_1_128 ~]# echo $a
aaa
[root@CentOs7_64_1_128 ~]# echo $b
bbb

21.1.1 read常用见用法及参数

例1:从标准输入读取一行并赋值给变量passwd


[root@CentOs7_64_1_128 ~]# read passwd
112233
[root@CentOs7_64_1_128 ~]# echo $passwd
112233

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


[root@CentOs7_64_1_128 ~]# read frist last
hello world
[root@CentOs7_64_1_128 ~]# echo $frist$last
helloworld

例3:read -s passwd 将你输入的东西隐藏起来,值赋给passwd。这个用户隐藏密码信息


[root@CentOs7_64_1_128 ~]# read -s passwd
[root@CentOs7_64_1_128 ~]# echo $passwd
334455

例4:输入的时间限制


[root@CentOs7_64_1_128 ~]# read -t 10 passwd
#设置read读取时间为10s,如果超出10s没有输入字符,或者输入字符但是没有输入回车,都会自动推出
[root@CentOs7_64_1_128 ~]# read -t 10 passwd
[root@CentOs7_64_1_128 ~]# echo $? #查看上个程序返回的值为142
142

例5:输入的长度限制


[root@CentOs7_64_1_128 ~]# read -n 5 passwd #设置read读取的字符个数最大为5个
11223[root@CentOs7_64_1_128 ~]# echo $passwd #超过5个字符以后,会自动退出read,并保存变量值为输入的前5个字符
11223

例6:使用-r参数输,允许让输入中的内容包括:空格、/、\、 ?等特殊字符串。


[root@CentOs7_64_1_128 ~]# read -r line #容许输入内容中有特殊字符
112233 ^%$@#$^&*&%()^! 、、、
[root@CentOs7_64_1_128 ~]# echo $line
112233 ^%$@#$^&*&%()^! 、、、

例7:-p 用于给出提示符

方法一:


[root@CentOs7_64_1_128 ~]# read -p "请输入您的信息:" info
请输入您的信息:好的,知道了
[root@CentOs7_64_1_128 ~]# echo $info
好的,知道了

方法二:


[root@CentOs7_64_1_128 ~]# echo -n "请输入您的信息:";read info # echo -n 输出信息后不换行
请输入您的信息:好的,知道了
[root@CentOs7_64_1_128 ~]# echo $info
好的,知道了

例8:read 综合实例

实例1


[root@CentOs7_64_1_128 ~]# read -s -n 3 -t 10 -p "请输入您的年龄:" age
# 设置输入不显示,最多读取3个字符,超时时间为10s
请输入您的年龄:[root@CentOs7_64_1_128 ~]# echo $age
105

实例2


[root@CentOs7_64_1_128 tmp]# vim +14 test1.sh #编辑test1脚本 #!/bin/bash read -p "请输入你的姓名:" NAME
read -p "请输入您的年龄:" AGE
read -p "请输入您的性别:" SEX cat<<EOF
*************
您的基本信息如下:
姓名:$NAME
年龄:$AGE
性别:$SEX
*************
EOF [root@CentOs7_64_1_128 tmp]# bash test1.sh
请输入你的姓名:老杨
请输入您的年龄:32
请输入您的性别:男
*************
您的基本信息如下:
姓名:老杨
年龄:32
性别:男
*************

21.2 流程控制语句if

21.2.1 语法格式:

if 条件;then

commands

fi

学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用

注:根据我们的命令退出码来进行判断(echo $? =0),如果是0,那么就会执行then后面的命令

例1:


[root@CentOs7_64_1_128 tmp]# vim if-1.sh
#!/bin/bash if ls /mnt; then
echo "it's ok"
fi [root@CentOs7_64_1_128 tmp]# bash if-1.sh
it's ok

21.2.2 双分支if语句

语法格式:

if command ; then

commands

else

commands

fi

学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用

例1:

[root@CentOs7_64_1_128 tmp]# vim if-2.sh #在passwd文件中查找root信息,如果有则打印it's ok,即确认root用户是否存在
#!/bin/bash
if grep root /etc/passwd; then
echo "it's ok"
else
echo "it's err"
fi [root@CentOs7_64_1_128 tmp]# bash if-2.sh
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
it's ok

例2:


[root@CentOs7_64_1_128 tmp]# vim if-3.sh #在passwd文件中查找yg信息,如果有则打印it's ok,即确认yg用户是否存在
#!/bin/bash if grep yg /etc/passwd; then
echo "it's ok"
else
echo "it's err"
fi [root@CentOs7_64_1_128 tmp]# bash if-3.sh
it's err

21.2.3 多分支if语句

语法结构:

if条件测试操作1 ; then

commands

elif 条件测试操作2 ; then

commands

elif 条件测试操作3 ; then

commands

.......

else

commands

fi

学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用

例1:判断用户在系统中是否存在,是否有家目录


[root@CentOs7_64_1_128 tmp]# vim if-4.sh #!/bin/bash read -p "input your username:" tu # 将读取的字符串存入tu if grep $tu /etc/passwd; then # 查看$tu是否存在
echo "the user $tu exists on the system"
elif ls -d /home/$tu; then # 查看$tu是否有家目录
echo "the user $tu exists on the system"
echo "the user $tu has a directory"
else
echo "the user $tu doesn't exists on the system"
echo "the user $tu doesn't have a directory"
fi [root@CentOs7_64_1_128 tmp]# bash if-4.sh
input your username:root
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
the user root exists on the system
[root@CentOs7_64_1_128 tmp]# bash if-4.sh
input your username:yangjie
yangjie:x:1000:1000:yangjie:/home/yangjie:/bin/bash
the user yangjie exists on the system

21.3 test测试命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试

格式:test 测试条件

如果结果是对的,也叫结果为真,用$?=0表示,反之为假,用非0表示

21.3.1 数值比较

参数 说明 示例
-eq 等于则为真 [ “\(a” -eq “\)b” ]
-ne 不等于则为真 [ “\(a” -ne “\)b” ]
-gt 大于则为真 [ “\(a” -gt “\)b” ]
-ge 大于等于则为真 [ “\(a” -ge “\)b” ]
-lt 小于则为真 [ “\(a” -lt “\)b” ]
-le 小于等于则为真 [ “\(a” -le “\)b” ]

例1:比较大小


[root@CentOs7_64_1_128 tmp]# vim +12 test2.sh
#!/bin/bash
if test 2 -eq 1 ;then
echo ok
else
echo err
fi if [ 2 -eq 2 ] ;then
echo ook
else
echo eerr
fi [root@CentOs7_64_1_128 tmp]# bash test2.sh
err
ook

例2: 比较整数大小


[root@CentOs7_64_1_128 tmp]# vim test3.sh
#!/bin/bash read -p "请输入要比较的整数1和整数2:" var1 var2 if [ $var1 -gt $var2 ]; then
echo "$var1 > $var2"
elif [ $var1 -lt $var2 ]; then
echo "$var1 < $var2"
else
echo "$var1=$var2"
fi [root@CentOs7_64_1_128 tmp]# bash test3.sh
请输入要比较的整数1和整数2:10 20
10 < 20

21.3.2 字符串比较

参数 说明 示例
== 等于则为真 [ “\(a” == “\)b” ]
!= 不相等则为真 [ “\(a” != “\)b” ]
-z 字符串. 字符串的长度为零则为真 [ -z “$a” ]
-n 字符串 字符串的长度不为空则为真 [ -n “$a” ]
str1 > str2 str1大于str2为真 [ str1 > str2 ]
str1 < str2 str1小于str2为真 [ str1 < str2 ]

例1:根据用户名判断是否是超级管理员


[root@CentOs7_64_1_128 tmp]# vim test4.sh #!/bin/bash read -p "input your name:" name if [ $name == "root" ]; then
echo "you are super administator"
else
echo "you are a general user"
fi [root@CentOs7_64_1_128 tmp]# bash test4.sh
input your name:root
you are super administator

例2:在做字符串大小比较的时候,注意字符串的顺序

  • 大于号和小于号必须转义,要不然SHELL会把它当成重定向符号
  • 大于和小于它们的顺序和sort排序是不一样的
  • 在test比较测试中,它使用的是ASCII顺序,大写字母是小于小写字母的;sort刚好相反

扩展: ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用


[root@CentOs7_64_1_128 tmp]# vim test5.sh #!/bin/bash var1=test
var2=Test if [ $var1 \> $var2 ]; then
echo "$var1 > $var2"
elif [ $var1 \< $var2 ]; then
echo "$var1 < $var2"
else
echo "$var1 = $var2"
fi [root@CentOs7_64_1_128 tmp]# bash test5.sh
test > Test

21.3.3 文件比较

参数 .说明 示例
-e 文件名. 如果文件或目录存在则为真 [ -e file ]
-r 文件名. 如果文件存在且可读则为真 [ -r file ]
-w 文件名. 如果文件存在且可写则为真 [ -w file ]
-x 文件名. 如果文件存在且可执行则为真 [ -x file ]
-s 文件名 如果文件存在且至少有一个字符则为真 [ -s file ]
-d 文件名. 如果文件存在且为目录则为真 [ -d file ]
-f 文件名. 如果文件存在且为普通文件则为真 [ -f file ]
-c 文件名. 如果文件存在且为字符型文件则为真 [ -c file ]
-b 文件名. 如果文件存在且为块特殊文件则为真 [ -b file ]
file1 -nt fle2 检查file1是否比file2新 [ file1 -nt file2 ]
file1 -ot file2 检查file1是否比file2旧 [ file1 -ot file2 ]

[root@CentOs7_64_1_128 tmp]# vim test6.sh
#!/bin/bash if [ -e /etc/passwd ];then
echo "ok"
else
echo "err"
fi
[root@CentOs7_64_1_128 tmp]# bash test6.sh
ok [root@CentOs7_64_1_128 tmp]# test -e /etc/aa.txt && echo ok || echo err
err
# 组合条件的时候,从左往右执行,条件1&&条件2,条件1成立后执行条件2,条件1不成立时不执行条件2. 条件3||条件4当条件3不成立时执行条件4,成立时不执行。 条件1&&条件2||条件3,当条件1成立时执行条件2,条件1不成立时执行条件3
[root@CentOs7_64_1_128 tmp]# test -e /etc/passwd && echo ok || echo err
ok

例:清空日志目录


[root@CentOs7_64_1_128 tmp]# vim test7.sh #!/bin/bash
sourcefile="/var/log/messages" # 设置源文件为/var/log/messages
desitinationfile="/var/log/mesg.tmp" # 设置目标文件为/var/log/mesg.tmp
if [ $USER != "root" ]; then # 确认用户是否为root用户,不是的话退出脚本
echo "你必须是管理员才能执行脚本"
exit 10
fi if [ ! -e $sourcefile ]; then # 判断源文件是否存在,不存在则直接退出
echo "日志文件不存在"
exit 12
fi # 保留最近100行的日志内容 tail -100 $sourcefile > $desitinationfile # 保存源文件的100最后100行到目标文件 # 日志清理 >$sourcefile # 清空源文件 mv $desitinationfile $sourcefile # 改名目标文件为源文件 echo "确认执行脚本" >> $sourcefile
echo "日志清除完毕" [root@CentOs7_64_1_128 tmp]# bash test7.sh
日志清除完毕
[root@CentOs7_64_1_128 tmp]# tail /var/log/messages
Jul 2 11:25:01 CentOs7_64_1_128 systemd: Started Session 27 of user pcp.
Jul 2 11:25:01 CentOs7_64_1_128 systemd: Removed slice User Slice of pcp.
Jul 2 11:28:01 CentOs7_64_1_128 systemd: Created slice User Slice of pcp.
Jul 2 11:28:01 CentOs7_64_1_128 systemd: Started Session 28 of user pcp.
Jul 2 11:28:01 CentOs7_64_1_128 systemd: Removed slice User Slice of pcp.
Jul 2 11:30:01 CentOs7_64_1_128 systemd: Started Session 29 of user root.
Jul 2 11:30:01 CentOs7_64_1_128 systemd: Created slice User Slice of pcp.
Jul 2 11:30:01 CentOs7_64_1_128 systemd: Started Session 30 of user pcp.
Jul 2 11:30:01 CentOs7_64_1_128 systemd: Removed slice User Slice of pcp.
确认执行脚本

注:退出码 exit ,取值范围是0-255

例: exit 退出bash,并返回一个值


[root@CentOs7_64_1_128 tmp]# ssh root@192.168.87.127 # 远程登陆127
root@192.168.87.127's password:
Last login: Tue Jul 2 11:48:11 2019 from 192.168.87.128
[root@CentOs7_64_2_127 ~]# exit 234 # 退出ssh登录,并返回值234
登出
Connection to 192.168.87.127 closed.
[root@CentOs7_64_1_128 tmp]# echo $?
234

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

21.4.1 判断第一种:两个条件都为真或有一个为真就执行

if [ 条件判断一 ] && (||) [ 条件判断二 ]; then

命令一

elif [ 条件判断三 ] && (||) [ 条件判断四 ]; then

命令二

else

执行其它

fi

判断第二种

if [条件判断一 -a (-o) 条件判断二 -a (-o) 条件判断三]; then

elif [条件判断三 -a (-o) 条件判断四 ]; then

else

执行其它

fi

判断第三种

if [[条件判断一 && (||) 条件判断二 ]]; then

elif [[ 条件判断三 && (||) 条件判断四 ]]; then

else

执行其它

fi

例1:设置umask


[root@CentOs7_64_1_128 tmp]# vim umask.sh
#!/bin/bash if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ];then
echo "umask 002"
else
echo "i am root:umask 022"
fi [root@CentOs7_64_1_128 tmp]# bash umask.sh
i am root:umask 022
[root@CentOs7_64_1_128 tmp]# su - yangjie
[yangjie@CentOs7_64_1_128 tmp]$ bash umask.sh
umask 002

21.4.2 [[ 。。。 ]]和[ 。。。]的区别

[[… ]] 运算符是[… ]运算符的扩充;[[… ]]能够支持 *,< 、>等符号且不需要转义符

[[ 。。。 ]]和[ 。。。]的区别汇总:

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

例1:


[root@CentOs7_64_1_128 tmp]# if [[ $USER == r* ]];then echo "hello,$USER";else echo $USER not;fi
hello,root
# 注: 在[[]]中的$USER == r*对比时, r* 表示以r开头的任意长度字符串,这样就包括root
[root@CentOs7_64_1_128 tmp]# if [ $USER == r* ];then echo "hello,$USER";else echo $USER not;fi
root not
# 在[]中对比时r* ,就表示两个字符串 r*

20.4.3 shell中的通配符

字符 含义 实例
* 匹配 0 或多个字符 a*b a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab.
? 匹配任意一个字符 a?b a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。
[list] 匹配 list 中的任意单一字符 a[xyz]b a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。
[!list] 匹配 除list 中的任意单一字符 a[!0-9]b a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。
[c1-c2] 匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] a[0-9]b 0与9之间必须也只能有一个字符 如a0b, a1b... a9b。
{string1,string2,...} 匹配 sring1 或 string2 (或更多)其一字符串 a{abc,xyz,123}b a与b之间只能是abc或xyz或123这三个字符串之一。

例:


[root@CentOs7_64_1_128 tmp]# ls /etc/*.conf # 查看etc下所有的.conf文件
/etc/asound.conf /etc/host.conf /etc/nfs.conf /etc/slp.conf
/etc/autofs.conf /etc/idmapd.conf /etc/nfsmount.conf /etc/softhsm2.conf
/etc/autofs_ldap_auth.conf /etc/ipsec.conf /etc/nsswitch.conf /etc/sos.conf
/etc/brltty.conf /etc/kdump.conf /etc/ntp.conf /etc/sudo.conf
/etc/cgconfig.conf /etc/krb5.conf /etc/numad.conf /etc/sudo-ldap.conf
/etc/cgrules.conf /etc/ksmtuned.conf /etc/oddjobd.conf /etc/sysctl.conf
/etc/cgsnapshot_blacklist.conf /etc/ld.so.conf /etc/pbm2ppa.conf /etc/tcsd.conf
/etc/chrony.conf /etc/libaudit.conf /etc/pcp.conf /etc/updatedb.conf
/etc/dleyna-server-service.conf /etc/libuser.conf /etc/pnm2ppa.conf /etc/usb_modeswitch.conf
/etc/dnsmasq.conf /etc/locale.conf /etc/radvd.conf /etc/vconsole.conf
/etc/dracut.conf /etc/logrotate.conf /etc/request-key.conf /etc/wvdial.conf
/etc/e2fsck.conf /etc/man_db.conf /etc/resolv.conf /etc/yum.conf
/etc/fprintd.conf /etc/mke2fs.conf /etc/rsyncd.conf
/etc/fuse.conf /etc/mtools.conf /etc/rsyslog.conf
/etc/GeoIP.conf /etc/named.conf /etc/sestatus.conf
[root@CentOs7_64_1_128 tmp]# ls /etc/????.conf # 查看etc下所有的名称为4个字母的.conf文件
/etc/fuse.conf /etc/host.conf /etc/krb5.conf /etc/sudo.conf /etc/tcsd.conf
[root@CentOs7_64_1_128 tmp]# touch a{1,2,3}.txt # 创建 a1,a2,a3.txt文件
[root@CentOs7_64_1_128 tmp]# ll a[123].txt #查看当前目录下的a1,a2,a3.txt文件
-rw-r--r--. 1 root root 0 7月 2 12:30 a1.txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a2.txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a3.txt
[root@CentOs7_64_1_128 tmp]# ll a[13].txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a1.txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a3.txt
[root@CentOs7_64_1_128 tmp]# ll a[1,2,3].txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a1.txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a2.txt
-rw-r--r--. 1 root root 0 7月 2 12:30 a3.txt

21.5 实战-3个shell脚本

21.5.1 编写脚本查看服务运行状态

[root@CentOs7_64_1_128 tmp]# vim status.sh
#!/bin/bash if [ $# -ge 1 ]; then # 判断运行脚本是否带有参数,如果有将第一个参数,即服务名称传给systemctl status
systemctl status $1 > /dev/null
if [ $? -eq 0 ]; then # 判断前一个命令是否执行成功,执行成功表示运行正常
echo "$1 服务正在运行"
else
systemctl restart $1 # 运行不正常的话,重启服务
fi
else #如果运行脚本没有带有服务名称的话,提示用户正确的使用格式
echo "执行脚本的格式"
echo "sh $0 服务名"
fi
[root@CentOs7_64_1_128 tmp]# bash status.sh httpd
httpd 服务正在运行

21.5.2 根据学生的成绩判断优劣

[root@CentOs7_64_1_128 tmp]# vim chengji.sh
#!/bin/bash read -p "input your score:" cj if [ $cj -le 100 ] && [ $cj -ge 86 ]; then
echo "优秀"
elif [ $cj -le 85 ] && [ $cj -ge 71 ]; then
echo "好"
elif [ $cj -le 70 ] && [ $cj -ge 60 ]; then
echo "良好"
elif [ $cj -le 59 ] && [ $cj -ge 0 ]; then
echo "补考"
else
echo "输入的成绩无效,请重新输入一个0到100之间的整数"
fi
[root@CentOs7_64_1_128 tmp]# bash chengji.sh
input your score:89
优秀
[root@CentOs7_64_1_128 tmp]# bash chengji.sh
input your score:102
输入的成绩无效,请重新输入一个0到100之间的整数

21.5.3 每周一晚上3:00 ,备份数据库服务器上webdb库的所有数据到系统的/mysqlbak目录里,使用系统日期做备份文件名。


[root@CentOs7_64_1_128 tmp]# vim mysqlbackup.sh
#!/bin/bash backupdir="/mysql" # 定义备份文件夹路径
filename=$(date "+%Y%m%d-%H%M") # 使用日期定义备份文件名称
user=root # 定义执行备份用户名
password=123 # 定义执行备份用户名密码
dbname=webdb # 定义执行备份mysql数据库名称 [ -d ${backupdir} ] || mkdir ${backupdir} #查看备份文件夹是否存在,不存在的话创建该文件夹 mysqldump -u{$user} -p${password} --flush-logs ${dbname} > ${backupdir}/${filename}-webdb.sql #执行mysql备份
if [ $? -eq 0 ]; then # 备份执行成功,打印备份完成
echo "备份完成"
fi find ${backupdir} -mtime +7 -exec rm -rf {} \; #删除七天之前的备份文件 [root@CentOs7_64_1_128 tmp]# bash mysqlbackup.sh #因为本机没有安装mysql数据库因此脚本执行失败
mysqldump: Got error: 2002: "Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)" when
trying to connect


END

2019-7-2 15:39:44

上一篇:python字符串方法以及注释


下一篇:angular2 安装 打包成发布项目过程