条件判断和流程控制语句
- read命令键盘读取变量的值
- 流程控制语句if
- test测试命令
- 流程控制过程中复杂条件和通配符
- 实战-3个shell脚本实战
一、read命令键盘从读取变量的值
通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY
Read从键盘读入数据,赋给变量
例1:
[root@localhost ~]# read a b
hello world
[root@localhost ~]# echo $a $b
hello world
例2:read常用见用法及参数
-s:隐藏输入
-p:后跟提示符,双引号括起来
[root@localhost ~]# read passwd
hello world
[root@localhost ~]# echo $passwd
hello world
例3:读取多个值,从标准输入读取一行,默认以空白符或换行符分割。把用户键入的第一个词存在变量中第一个,该行剩余部分值保持到第二个变量
[root@localhost ~]# read first last
aa bb cc dd
[root@localhost ~]# echo $first
aa
[root@localhost ~]# echo $last
bb cc dd
例4:将从标准输入的值隐藏起来,赋值给到变量。一般使用在用户隐藏密码
[root@localhost ~]# read -s passwd
[root@localhost ~]# echo $passwd
Xuegod
例5:标准输入的时间限制,超过时间自动退出
[root@localhost ~]# read -t 2 test #超过2秒自动退出
例6:标准输入的字符长度限制
[root@localhost ~]# read -n 2 test
lj[root@localhost ~]# echo $test #只能输入两个字符,超出后自动退出
lj
例7:允许标准输入的内容包含:空格、/、\、?等特殊字符
[root@localhost ~]# read -r line
aa bb / cc /n
[root@localhost ~]# echo $line
aa bb / cc /n
例8:-p参数用于给出提示符;echo –n “……”加上read
[root@localhost ~]# read -p “Please enter you name:” Name
Please enter you name:zhangsan
[root@localhost ~]# echo $Name
Zhangsan
[root@localhost ~]# echo -n “Please enter your passwd:”;read passwd
Please enter your passwd:123456
[root@localhost ~]# echo $passwd
123456
例9:read综合实例
[root@localhost ~]# vim test.read.sh
[root@localhost ~]# cat test.read.sh
#!/bin/bash
read -p “Input Name:” Name
read -p “Input Age:” Age
read -p “Input Sex:” Sex
cat <<eof
*******************
Name: N a m e A g e : Name Age: NameAge:Age
Sex:$Age
*******************
Eof
[root@localhost ~]# sh test.read.sh
Input Name:zhangsan
Input Age:100
Input Sex:man
*******************
Name:zhangsan
Age:100
Sex:100
*******************
二、流程控制句if
1、语法格式
if 条件
then
commands
fi
理解:如果(if)条件成立,那么(then),就执行(commands),然后退出(fi)
If语句流程图:
注释:if是根据命令退出码来判定,如果是0,(echo $?=0),就执行then后面的命令
例1:脚本1
[root@localhost ~]# vim if-1.sh
[root@localhost ~]# cat if-1.sh
#!/bin/bash
if ls /mnt
then
echo “it’s ok”
fi
[root@localhost ~]# sh if-1.sh
it’s ok
2、双分支if语句
语法格式:
if command ;then
commands
else
commands
if
例1:脚本2
[root@localhost ~]# vim if-2.sh
[root@localhost ~]# cat if-2.sh
#!/bin/bash
if ls /mnt ;then
echo ok
else
echo err
fi
[root@localhost ~]# sh if-2
sh: if-2: 没有那个文件或目录
[root@localhost ~]# sh if-2.sh
Ok
例2:脚本2
[root@localhost ~]# vim if-3.sh
[root@localhost ~]# cat if-3.sh
#!/bin/bash
if ls /xxxmnt &>/dev/null ;then
echo ok
else
echo err
fi
[root@localhost ~]# sh if-3.sh
Err
3、多分支if语句
语法结构:
if 条件1 ;then
commands
elif 条件2;then
commands
……
else
commands
fi
例1:脚本
[root@localhost ~]# vim if-4.sh
[root@localhost ~]# cat if-4.sh
#!/bin/bash
read -p “input a user:” tu
if grep $tu /etc/passwd ; then
echo “the user t u e x i s t s o n t h i s s y s t e m “ e l i f l s − d / h o m e / tu exists on this system” elif ls -d /home/ tuexistsonthissystem”elifls−d/home/tu ; then
echo “the user t u n o t e x i s t s o n t h i s s y s t e m “ e c h o “ tu not exists on this system” echo “ tunotexistsonthissystem”echo”tu has a home directory”
else
echo “the user t u n o t e x i s t s o n t h i s s y s t e m “ e c h o “ tu not exists on this system” echo “ tunotexistsonthissystem”echo”tu not has home directory”
fi
[root@localhost ~]# sh if-4.sh
input a user:root
root❌0root:/root:/bin/bash
operator❌11operator:/root:/sbin/nologin
the user root exists on this system
[root@localhost ~]# sh if-4.sh
input a user:aa
ls: 无法访问/home/aa: 没有那个文件或目录
the user aa not exists on this system
aa not has home directory
注释:多分支if语句,只有第一个if不生效,才会执行下一个if,直到条件生效或执行到else,然后fi返回
三、test测试命令
test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三方面比较
如果结果是对的,也叫做结果为真,即$?=0,反之为假,用非0的数字表示
test命令和[]中括号等价,作用相同,一般我们使用[],不使用test命令
1、数值比较
参数:
-eq :等于则为真
-nq :不等于则为真
-gt :大于则为真
-ge :大于等于则为真
-lt :小于则为真
-le:小于等于则为真
例1:比较大小
[root@localhost ~]# [ 2 -gt 5 ];echo $?
1
[root@localhost ~]# [ 5 -lt 7 ];echo $?
0
例2:脚本
[root@localhost ~]# vim if-5.sh
[root@localhost ~]# cat if-5.sh
#!/bin/bash
if test 2 -eq 3; then
echo ok
elif test 2 -gt 3; then
echo ok
elif [ 2 -eq 2 ];then
echo ok
else
echo err
fi
[root@localhost ~]# sh if-5.sh
Ok
例3:脚本
[root@localhost ~]# vim if-6.sh
[root@localhost ~]# cat if-6.sh
#!/bin/bash
if [ $1 -gt $2 ];then
echo “$1>$2”
elif [ $1 -lt $2 ];then
echo “$1<$2”
elif [ $1 -eq $2 ];then
echo “$1=$2”
else
echo “$1 $2 not”
fi
[root@localhost ~]# sh if-6.sh 11 22
11<22 \[root@localhost ~\]\# sh [if-6.sh][] 22 1 22>1
[root@localhost ~]# sh if-6.sh 22 22
22=22
2、字符串比较
= :等于则为真
!= :不等于则为真
-z :字符串长度为零则为真
-n :字符串长度不为空则为真
Str1>str2 :成立为真
Str1<str2:成立为真
例1:根据用户名判断是否是超级管理员
[root@localhost ~]# vim test3.sh
[root@localhost ~]# cat test3.sh
#!/bin/bash
read -p “input your name:” name
if [ n a m e = = “ r o o t “ ] ; t h e n e c h o “ name == “root” ];then echo “ name==”root”];thenecho”name is super user”
else
echo “$name is general user”
fi
[root@localhost ~]# sh test3.sh
input your name:root
root is super user
[root@localhost ~]# sh test3.sh
input your name:zx
zx is general user
例2:做字符串大小比较的时候,注意字符串的顺序
大于号和小于号必须转义,要不然shell会把它当作重定向符号
大于和小于他们的顺序和sort排序是不一样的
在test或[]比较测试中,使用的是ASCII码顺序,大写字母小于小写字母
例:
[root@localhost ~]# [ “a” < “A” ] && echo ok || echo err
err
[root@localhost ~]# [ “a” > “A” ] && echo ok || echo err
ok
[root@localhost ~]# [ “KaTeX parse error: Expected ‘EOF’, got ‘\>’ at position 7: USER” \̲>̲ “root” ] && ec…USER” == “root” ] && echo ok || echo err
ok
[root@localhost ~]# [ “$PWD” == “/root” ] && echo ok || echo err
ok
3、文件的比较
-e file :如果文件或目录存在则为真
-r file :如果文件存在且可读则为真
-w file:如果文件存在且可写则为真
-x file :如果文件存在且可执行为真
-s file :如果文件存在且至少有一个字符则为真
-d file :如果目录存在则为真
-f file :如果普通文件存在则为真
-c file :如果字符文件存在则为真
-b file :如果块文件存在则为真
file1 –nt file2 :检测file1是否比file2新
file1 –ot file2 :检测file1是否比file2旧
file1 –et file2: :检测file1和file2是否是同一文件(inode、硬链接)
例1:
[root@localhost ~]# [ -e /etc/passwd ] && echo ok || echo err
ok
[root@localhost ~]# [ -f /root/a.txt ] && echo ok || echo err
Err
[root@localhost ~]# [ -x /etc/passwd ] && echo ok || echo err
err
[root@localhost ~]# [ . -ef /root/ ] && echo ok || echo err
ok
[root@localhost ~]# [ /home/zx -ef /root/ ] && echo ok || echo err
Err
[root@localhost ~]# [ -z /etc/passwd ] && echo ok || echo err
err
[root@localhost ~]# [ ! -z /etc/passwd ] && echo ok || echo err
Ok
例2:清空日志脚本
[root@localhost ~]# vim clear-log.sh
[root@localhost ~]# cat clear-log.sh
#!/bin/bash
if [ “ U S E R “ ! = “ r o o t “ ] ; t h e n e c h o “ USER” != “root” ];then echo “ USER”!=”root”];thenecho”USER not super system”
exit
fi
if [ ! -f /var/log/messages ];then
echo “not exits…”
exit
fi
tail -100 /var/log/messages > /var/log/messages.log
/var/log/messages
#cat /dev/null > /var/log/messages
mv /var/log/messages.log /var/log/messages
echo “logs clean up”
[root@localhost ~]# cat /var/log/messages | wc -l
2351
[root@localhost ~]# sh clear-log.sh
logs clean up
[root@localhost ~]# cat /var/log/messages | wc -l
100
四、流程控制过程中中复杂条件和通配符
-a或者&&:表示and或者并且,只有两个表达式都为真时条件才成立,其中 –a只能在test和[]中使用,&&只能在[[]]中使用
-o或者||:表示or或或者,如果两个表达式有一个为真条件就成立,其中-o只能在test和[]使用,||只能在[[]]中使用
!:取反意思
():改变表达式的优先级,注意加转义符号
1、判断第一种:两个条件都为真或者有一个为真
if [ 条件1 ] &&(||)[ 条件2 ];then
命令一
elif [ 条件三 ] &&(||) [ 条件四 ];then
else
执行其它
fi
判断第二种
if [ a –a(-o) b ];then
elif [ c –a(-o) d ];then
else
fi
判断第三种
if [[ 条件1 &&(||) 条件2 ]];then
elif [[ 条件3 &&(||) 条件4 ]];then
else
fi
例1:查看umask值
[root@localhost ~]# vim umask.sh
[root@localhost ~]# cat umask.sh
#!/bin/bash
if [ $UID -gt 199 ] && [ “id -gn
” = “id -un
”];then
echo “umask 002”
else
echo “i am root:umask 022”
fi
[root@localhost ~]# sh umask.sh
i am root:umask 022
例2:[[ …]]和[ … ]的区别
[[…]] 运算符是[…]运算符的扩充;[[…]]能够支持*,<、>等符号且不需要转义符
[root@xuegod63 ~]# if [[ U S E R = = r ∗ ] ] ; t h e n e c h o “ h e l l o , USER == r*]] ; then echo “hello, USER==r∗]];thenecho”hello,USER” ; else echo U S E R n o t ; f i h e l l o , r o o t 注 : USER not ; fi hello,root 注: USERnot;fihello,root注:USER == r对比时,r 表示以r开头的任意长度字符串,这样就包括root
当只有一个[] 方括号时:
[root@xuegod63 ~]# if [ U S E R = = r ∗ ] ; t h e n e c h o “ h e l l o , USER == r* ] ; then echo “hello, USER==r∗];thenecho”hello,USER” ; else echo $USER not ; fi
root not
#对比时r* ,就表示两个字符串r*
[root@xuegod63 mnt]# [[ $USER == r* ]];echo $?
0
[root@xuegod63 mnt]# [ $USER == r* ];echo $?
1
[root@xuegod63 mnt]# [[ $USER == rr* ]];echo $?
1
[root@xuegod63 mnt]# [[ $USER =~ rr* ]];echo $?
0
也可以这样写:
[root@xuegod63 ~]# if [[ U S E R = = [ a − z ] o o t ] ] ; t h e n e c h o “ h e l l o , USER == [a-z]oot ]] ; then echo “hello, USER==[a−z]oot]];thenecho”hello,USER” ; else echo $USER not ; fi
2、[[ …]]和[ …]的区别汇总:
1、所有的字符与逻辑运算符直接用“空格”分开,不能连到一起。
2、在[…]表达式中,常见的>、<需要加转义符\,大小比较
3、进行逻辑运算符&& 、||比较时;如果用的[ ]符号,则用在外面,如[…] && […] || [ …]如果在[…]里面进行逻辑与或的比较,则用-a、-o进行表示,如[ x = y –ax < z –o x > m ]
4、[[…]] 运算符只是[…]运算符的扩充;能够支持<、>符号运算不需要转义符;它还是以字符串比较大小。里面支持逻辑运算符||、&& ,不再使用-a 、-o
5、[[…]] 用&& 而不是-a表示逻辑“与”;用|| 而不是-o表示逻辑“或”
6、[[…]]可以进行算术扩展,而[ … ]不可以
7、[[…]]能用正则,而[…]不行
8、双括号(( ))用于数学表达式
9、双方括号号[[ ]]用于高级字符串处理,比如“模糊匹配”,当使用运算符为”==”或”!=”时,运算符右边使用通配符* ?[…]{…}进行匹配;当使用的通配符为”=~”时,运算符右边使用正则表达式进行匹配
3、shell中的通配符
* 匹配0 或多个字符 a*ba与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。
? 匹配任意一个字符 a?ba与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。
[list] 匹配list 中的任意单一字符 a[xyz]ba与b之间必须也只能有一个字符, 但只能是x 或y 或z, 如: axb, ayb, azb。
[!list] 匹配除list 中的任意单一字符 a[!0-9]ba与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。
[c1-c2] 匹配c1-c2 中的任意单一字符如:[0-9] [a-z] a[0-9]b0与9之间必须也只能有一个字符如a0b, a1b… a9b。
{string1,string2,…} 匹配sring1 或string2 (或更多)其一字符串 a{abc,xyz,123}ba与b之间只能是abc或xyz或123这三个字符串之一。
例:
[root@xuegod63 ~]# ls /etc/*.conf
[root@xuegod63 ~]# ls /etc/???.conf
/etc/nfs.conf /etc/sos.conf /etc/yum.conf
[root@xuegod63 ~]# touch /opt/a{1,2,3}.txt
[root@xuegod63 ~]# ls /opt/a[123].txt
/opt/a1.txt /opt/a2.txt /opt/a3.txt
[root@xuegod63 ~]# ls /opt/a[1,2,3].txt
[root@xuegod63 ~]# ls /opt/a[13].txt
/opt/a1.txt /opt/a3.txt
五、实战-3个shell脚本
1、实战1:编写脚本检车服务器运行状态
[root@localhost ~]# vim status.sh
[root@localhost ~]# cat status.sh
#!/bin/bash
if [ $# -ge 1 ];then
systemctl status $1 >/dev/null
if [ $? -eq 0 ];then
echo “$1 service is running…”
else
systemctl start $1 >/dev/null
echo “$1 serive restart…”
fi
else
echo “sh $0 service name”
fi
[root@localhost ~]# sh status.sh sshd
sshd service is running…
[root@localhost ~]# sh status.sh firewalld
firewalld serive restart…
[root@localhost ~]# sh status.sh firewalld
firewalld service is running…
2、实战2-根据学生成绩判断优劣
[root@localhost ~]# vim check_cj.sh
[root@localhost ~]# cat check_cj.sh
#!/bin/bash
read -p “Input your cj:” cj
if [ $cj -ge 0 ] && [ $cj -le 59 ];then
echo “cj bad…”
elif [ $cj -ge 60 ] && [ $cj -le 70 ];then
echo “cj good”
elif [ $cj -ge 70 ] && [ $cj -le 100 ];then
echo “cj very good”
else
echo “not cj”
fi
[root@localhost ~]# sh check_cj.sh
Input your cj:22
cj bad…
[root@localhost ~]# sh check_cj.sh
Input your cj:66
cj good
[root@localhost ~]# sh check_cj.sh
Input your cj:88
cj very good
[root@localhost ~]# sh check_cj.sh
Input your cj:120
not cj
3、实战3-每周一晚上3:00,备份数据服务器上webdb的所有数据到系统的/mysqlbak目录里,使用系统日期做备份文件名
[root@localhost ~]# vim etcbak.sh
[root@localhost ~]# cat etcbak.sh
#!/bin/bash
FileName=`date +%Y-%m-%d`
BackDir=/etcback
SrcDir=/etc
[ -e $BackDir ] || mkdir $BackDir
tar zcvf B a c k D i r / BackDir/ BackDir/{FileName}-etc.tar.gz $SrcDir
echo “————————————————————”
ls -lh B a c k D i r / BackDir/ BackDir/{FileName}-etc.tar.gz
echo “back etc is ok!”
[root@localhost ~]# vim etcbak.sh
[root@localhost ~]# cat etcbak.sh
#!/bin/bash
FileName=`date +%Y-%m-%d`
BackDir=/etcback
SrcDir=/etc
[ -e $BackDir ] || mkdir $BackDir
tar zcvf B a c k D i r / BackDir/ BackDir/{FileName}-etc.tar.gz $SrcDir &>/dev/null
echo “————————————————————”
ls -lh B a c k D i r / BackDir/ BackDir/{FileName}-etc.tar.gz
echo “back etc is ok!”
echo “======================”[root@localhost ~]# sh etcbak.sh
-rw-r–r—. 1 root root 11M 5月 3 06:41 /etcback/2019-05-03-etc.tar.gz
back etc is ok!
还没有评论,来说两句吧...