Shell脚本之条件测试语句和 if 流程控制语句的使用

read 命令键盘读取变量的值

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

read 从键盘读入数据,赋给变量
在这里插入图片描述
s s a ra
然后变量就赋给了a 和 b ,调用变量需要在变量前面加 $ 符号

read 常用见用法及参数

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

[root@zcy1 ~]# read passwd

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

[root@zcy1~]# read firt last
aaaa     bbbb

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

[root@zcy1~]# read -s passwd
[root@zcy1 ~]# echo $passwd
123456

4、输入的时间限制

#超过两秒没有输入,直接退出

[root@zcy1 ~]# read -t 2 time #超过两秒没有输入,直接退出

5、输入的长度限制

#最多只接受 2 个字符

[root@zcy1~]# read -n 2 test #最多只接受 2 个字符

6、使用-r 参数输,允许让输入中的内容包括: \识别为普通字符

[root@zcy1 ~]# read -r line
sdf sdf / sdfs /n
[root@zcy1 ~]# echo $line
sdf sdf / sdfs /n

7、p 用于给出提示符

方法 1:

[root@zcy1 ~]# read -p "please input: " pass
please input: 123456
[root@zcy1 ~]# echo $pass
123456

方法 2:

[root@zcy1 ~]# echo -n "please input: " ; read pass
please input: 123456
[root@zcy1 ~]# echo $pass
123456

8:read 综合实例

```bash
[root@zcy1 ~]# vim test.read.sh    #写入以下内容
#!/bin/bash

read -p "请输入姓名:" NAME
read -p "请输入年龄:" AGE
read -p "请输入性别:" SEX
cat<<eof ********************* 你的基本信息如下:
姓名: $NAME
年龄:$AGE
性别:$SEX
******************** eof
[root@zcy1 ~]# sh test-read.sh
请输入姓名:zcy
请输入年龄:111
请输入性别:man
********************* 你的基本信息如下:
姓名: zcy
年龄:111
性别:man

流程控制语句 if

if语法格式

在这里插入图片描述

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

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

双分支 if 语句

语法格式:

if command ; then  #如果条件成立则执行
commands    #需要执行的命令
else   #条件不成立则执行
commands  #条件不成立需要执行的语句 
fi  #结尾

实战演示

[root@bogon ~]# cat if.sh
#!/bin/bash
read -p "检查目录是否存在,请输入目录:" aaa
if ls $aaa > /dev/null
then
echo "目录存在" else
echo "请输入正确路径"
fi
[root@zcy1 ~]# cat if-2.sh
#!/bin/bash #注释信息 shell 类型
if grep root /etc/passwd ; then #在指定文件中查找 root 字符串
echo "it's ok" else
echo "it's err"
fi
[root@zcy1 ~]# sh if-2.sh
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
it's ok

多分支 if 语句

在这里插入图片描述在这里插入图片描述
实战:判断用户在系统中是否存在,是否有家目录

[root@zcy1 ~]# cat if-4.sh
#!/bin/bash

read -p "input a user:" tu
if grep $tu /etc/passwd ; then
echo "the user $tu exists on this system" elif ls -d /home/$tu ; then
echo "the user $tu not exists on this system" echo "$tu has a home directory" else
echo "the user $tu not exists on this system" echo "$tu not has a direcotry"
fi
[root@zcy1~]# sh if-4.sh
Input a user: hr
chrony:x:994:990::/var/lib/chrony:/sbin/nologin
hr:x:1000:1000:hr:/home/hr:/bin/bash
the user hr exists on this system
[root@zcy1 ~]# sh if-4.sh
Input a user: zcy1
/home/zcy
zcy has a directory

#if 另一种书写格式

[root@bzcy1 ~]# cat if2.sh
#!/bin/bash
read -p "请输入用户名:" hhh
if grep $hhh /etc/passwd
then
echo "当前系统中存在此用户" elif ls -d /home/$hhh
then
echo "$hhh 用户不存在" echo "$hhh 有主目录" else
echo "系统用户不存在" echo "系统不存在用户目录"
fi

test 测试命令

数值比较

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

在这里插入图片描述


如果2等于2 那么就执行echo "ok" 否则执行“err”

[root@zcy1~]# [ 2 -eq 2 ] && echo "ok" || echo "err"  
ok 

如果2等于1 那么就执行echo "ok" 否则执行“err”

[root@zcy1~]# [ 2 -eq 1 ] && echo "ok" || echo "err" 
err
[root@zcy1 ~]# cat /root/test1.sh
#!/bin/bash
read -p "请输入第一个数字:" a
read -p "请输入第二个数字:" b
if [ $a -eq $b ]
then
echo "$a 等于$b,两个数字相等。" else
echo "$a 不等于$b,两个数字不相等。"
fi

例 1:比较大小

[root@zcy1 ~]# cat 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

例 2: 比较整数大小

[root@zcy1 ~]# cat test2.sh
#!/bin/bash
read -p "input var1 var2:" var1 var2
if [ $var1 -gt $var2 ] ; then
echo "$var1 > $var2" elif [ $var1 -lt $var2 ] ; then
echo "$var1 < $var2" else
echo "$var1 = $var2"
fi#    流程控制过程中复杂条件和通配符

字符串比较

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

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

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

[root@zcy1 ~]# cat test3.sh
#!/bin/bash
read -p "请输入你的名字:" name
if [ $name == "root" ]
then
echo "管理员" else
echo "不是管理员"
fi

扩展:ASCII表

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

[root@zcy1 ~]# cat test4.sh
#!/bin/bash
var1=test
var2=Test
if [ $var1 \> $var2 ]
then
echo "$var1 > $var2" else
echo "$var1 < $var2"
fi
[root@bogon ~]# ./test4.sh
test > Test

文件比较

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

[root@zcy1 ~]# [ -e /etc/passwd ] && echo "是文件" || echo "不是文件" 是文件
[root@zcy1 ~]# [ -e /etc/pass ] && echo "是文件" || echo "不是文件" 不是文件
[root@zcy1 ~]# vim test5.sh
#!/bin/bash
if [ -e /etc/passwd ] ; then
echo ok
else
echo err
fi
[root@zcy1 ~]# bash test5.sh
ok

[root@zcy1 ~]# test -e /etc/aaa.txt && echo ok || echo err
err
[root@zcy1 ~]# test -e /etc/passwd && echo ok || echo err
ok
[root@zcy1 ~]# test -e /etc && echo ok || echo err
ok

例:清空日志目录

[root@zcy1 ~]# cat /tmp/log.sh
#!/bin/bash
if [ $USER != "root" ]
then
echo "脚本需要 root 用户执行" exit 10
fi
if [ ! -f /var/log/messages ]
then
echo "文件不存在" exit 12
fi
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 ,取值范围是 0-255

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

[root@zcy1 ~]# ssh 192.168.1.63
root@192.168.1.63's password: 123456
Last login: Mon May 30 10:40:41 2020 from zcy1.cn
[root@zcy1 ~]#
[root@zcy1 ~]# exit 10

登出
Connection to 192.168.1.63 closed. 

[root@zcy1 ~]# echo $?
10

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

在这里插入图片描述
例1:

[[ … ]] 和 [ …] 的区别

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

例 1:

[root@zcy1 ~]# if [[ $USER == r* ]] ; then echo "hello,$USER" ; else echo $USER not ; fi
hello,root

注: $USER == r* 对比时, r* 表示以 r 开头的任意长度字符串,这样就包括 root
当只有一个[] 方括号时:

[root@zcy1 ~]# if [ $USER == r* ] ; then echo "hello,$USER" ; else echo $USER not ; fi
root not

#对比时 r* ,就表示两个字符串 r*

也可以这样写:

[root@zcy1 ~]# if [[ $USER == [a-z]oot ]] ; then echo "hello,$USER" ; else echo $USER not ;
fi
[[ ... ]] 和 [ ...] 的区别汇总:

1、所有的字符与逻辑运算符直接用“空格”分开,不能连到一起。

2、在[… ]表达式中,常见的> 、<需要加转义符\,大小比较

3、进行逻辑运算符&& 、||比较时;如果用的[ ]符号,则用在外面,如[… ] && [… ] || [ …]
如果在[…]里面进行逻辑与或的比较,则用-a、-o 进行表示,如[ x = y –a x < z –o x > m ]

4、[[… ]] 运算符只是[… ]运算符的扩充;能够支持< 、>符号运算不需要转义符;它还是以字符串比较大小。
里面支持逻辑运算符 || 、 && , 不再使用-a 、-o

5、[[…]] 用 && 而不是 -a 表示逻辑“与”;用 || 而不是 -o 表示逻辑“或”

6、[[… ]]可以进行算术扩展,而[ ... ]不可以

7、[[...]]能用正则,而[...]不行

8、双括号(( ))用于数学表达式

9、双方括号号[[ ]]用于高级字符串处理,比如“模糊匹配”

shell 中的通配符

在这里插入图片描述
例:

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

实战-3 个 shell 脚本实战

实战 1:编写脚本检查服务器运行状态

[root@zcy1 ~]# cat if-elif.sh
#!/bin/bash
read -p "Please input you filename:" file #接收键盘输入并赋予变量 file。
if [ -z "$file" ] #判断 file 变量是否为空。
then
echo "Error,please input a filename" #如果为空,输出报错信息。
elif [ ! -e "$file" ] #判断 file 的值是否存在。
then
echo "your input is not file" #如果不存在,输出此信息。
elif [ -f "$file" ] #判断 file 的值是否为普通文件。
then
echo "$file is a regulare file" #如果是普通文件输出此信息。
elif [ -d "$file" ] #判断 file 是否是目录文件。
then
echo "$fiel is a directory!" #如果是目录文件输出此信息。
else #如果都不是则执行本程序。
echo "$file is an other file!" #都不是的话输出此信息。
fi

实战 2:根据学生的成绩判断 学生的优劣

[root@zcy1 ~]# vim check_cj.sh
#!/bin/bash
read -p "请输入你的成绩 " cj
if [ $cj -ge 0 ] && [ $cj -le 59 ] ;then
echo "补考" elif [ $cj -ge 60 ] && [ $cj -le 70 ] ;then
echo "良好" elif [ $cj -ge 71 ] && [ $cj -le 85 ] ;then
echo "好" elif [ $cj -ge 86 ] && [ $cj -le 100 ] ;then
echo "优秀" else
echo "成绩的有效范围是 0-100 之间"
fi

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

[root@zcy1 ~]# vim mysqlbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d` bakdir=/mysqlbak
user=root
password=123
dbname=webdb
[ -e $bakdir ] || mkdir $bakdir
mysqldump -u$user -p$password --flush-logs $dbname >
$bakdir/${
    
    baknamefile}-webdb.sql

因为 mysql 咱们还没有学,这里以/etc 目录来做实验:

[root@zcy1 ~]# vim etcbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d` bakdir=/etcbak
srcdir=/etc
[ -e $bakdir ] || mkdir $bakdir
tar zcvf ${
    
    bakdir}/${
    
    baknamefile}-etc.tar.gz /etc/
echo "========================"
ls -lh ${
    
    bakdir}/${
    
    baknamefile}-etc.tar.gz
echo "back etc is ok!"
[root@zcy1 ~]# chmod +x etcbak.sh
[root@zcy1 ~]# crontab -e
0 3 * * * /root/etcbak.sh 2>&1 > /dev/null

猜你喜欢

转载自blog.csdn.net/weixin_45412401/article/details/111941647
今日推荐