本节所讲内容
20.1 read 命令从键盘上读取变量的值
20.2 流程控制语句if
20.3 test测试命令
20.4 流程控制过程中复杂条件和通配符
20.5 实战-3个shell脚本实战
20.1 read 命令键盘读取变量的值
从键盘上读取变量的值,通常用在shell脚本与用户进行交互的场合,该命令可以读取的和输入的值都需要使用空格隔开,在read命令后面,如果没有指定变量名,读取的额数据江北自动赋值给特点的变量reply
[root@localhost ~]# read a b
hello world
[root@localhost ~]# echo $a
hello
[root@localhost ~]# echo $b
world
[root@localhost ~]# echo $a $b
hello world
第二种
[root@localhost ~]# read a b
aaaaa
[root@localhost ~]# echo $a $b
aaaaa
[root@localhost ~]# echo $b
[root@localhost ~]#
2.1.1 read 常见用法以及参数
例1 :从标准读取一行赋值变量answer
例2 读取多个值,从标准输入读取一行,知道遇到第一个空白换行符,把用户键入的而第一个词存入到变量first,把改行的剩余部分存入last 中
例3 :read -s passwd 将你输入的东西藏起来,赋值给passwd ,这个用户输入密码时,隐藏密码信息
[root@localhost ~]# read -p "input your passwd:" -s passwd
input your passwd:[root@localhost ~]#
[root@localhost ~]#
例4 :输入的时间限制
read -t 2 time 超过两秒没有输入,直接退出
[root@localhost ~]# read -t 2 aaa
[root@localhost ~]# read -t 2 aaa
aaaa
[root@localhost ~]# echo $aaa
aaaa
[root@localhost ~]#
例5 输入长度的限制
read -n 2 aaa 字符输入的个数 输入两个自觉退出
例6 使用-r 参数输入,允许让输入的内容包含 空格,\, / ? 等特殊符号
read -r line
[root@localhost ~]# read -r line
aaaa bbbb $%@#$\\\\/////
[root@localhost ~]# echo $line
aaaa bbbb $%@#$\\\\/////
例7 :-p 用于给出提示符
方法1 :[root@localhost ~]# read -p "please input:" pass
please input:123456
[root@localhost ~]# echo $pass
123456
方法2:[root@localhost ~]# echo -n 'pleace input:'; read pass
pleace input:123456
[root@localhost ~]# echo $pass
123456
例8 : read 综合实例
①[root@localhost ~]# vim test-read.sh
写入以下信息
②#! /bin/bash
read -p "请输入姓名:" NAME
read -p "请输入年龄:" AGE
read -p "请输入性别:" SEX
cat<<eof
你的基本信息如下
姓名:$NAME
年龄:$AGE
性别:$SEX
eof
③root@localhost ~]# bash test-read.sh
请输入姓名:cang
请输入年龄:18
请输入性别:woman
*********************
你的基本信息如下
姓名:cang
年龄:18
性别:woman
*********************
29.2 流程控制语句
20.2.1 语法格式
if 条件
then
commands
fi
if 语句流程图
注: 根据我们的命令退出码,判断(echo $?=0) 如果是0 ,那么就会执行then 后面的命令
1 )[root@localhost ~]# vim if-1.sh 写入以下内容
2)#! /bin/bash
if ls /mnt
then
echo "it is ok"
fi
3) [root@localhost ~]# bash if-1.sh
it is ok
20.2 .2 双分支if 语句
语法格式
if 条件; then
commands
else
commands
fi
1)[root@localhost mnt]# vim if-2.sh
2)#! /bin/bash
if grep root /etc/passwd ; then
echo "it's ok"
else
"it's error"
fi
3) [root@localhost mnt]# bash if-2.sh
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
it's ok
第二种情况 如果过滤不出来
就会发生以下情况
#! /bin/bash
if grep mroot /etc/passwd ; then
echo "it's ok"
else
"it's error"
fi
2)[root@localhost mnt]# bash if-2.sh
if-2.sh: line 5: it's error: command not found
4)[root@localhost mnt]# vim +5 if-2.sh 修改第5行
3)#! /bin/bash
if grep root /etc/passwd ; then
echo "it's ok"
else
echo "it's error" 加上echo
fi
注: 退出esc 使用 e! 恢复到原始状态
5) [root@localhost mnt]# bash if-2.sh
it's error
20.2.3 多分支if 语句
语法结构
if 条件测试操作;then
commands
elif 条件测试操作2;then
elif 条件测试操作3; then
commands
else
commands
fi
例4 判断用户是否存在家目录
1)[root@localhost ~]# vim if-4.sh
2)#! /bin/bash
read -p "input a user:" tu
if grep $tu /etc/passwd; then
echo "the user $tu exits on the system"
elif ls -d /home/$tu
then
echo "the user $tu not exits on the system"
echo "$tu has a home directory"
else
echo "the user $tu exits on the system"
echo "$tu has a directory"
fi
3) [root@localhost ~]# bash if-4.sh
input a user:centos
centos:x:1000:1000:centos:/home/centos:/bin/bash
the user centos exits on the system
20.3 test测试命令
Shell中的test命令用于检测某个条件是否成立,它可以进行数值,字符和条件三个方面的测试
注:如果结果是对的,也叫结果为真,用echo $? =0 表示,反之为假,用非0 表示
20.3.1 数值比较
1)[root@localhost ~]# vim test1.sh
2)#! /bin/bash
if test 2 -eq 1;then
echo ok
else
echo error
fi
~
3) [root@localhost ~]# bash test1.sh
error
还有第二种脚本的写法
1)#! /bin/bash
if test 2 -eq 1;then
echo ok
else
echo error
fi
if [ 2 -eq 2 ];then
echo ok
else
echo error
fi
2)[root@localhost ~]# bash test1.sh
error
ok
例2 比整数的大小
1)[root@localhost ~]# vim test2.sh
2)#! /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 注意:在做数值比较时,只能做整数比较
3)[root@localhost ~]# bash test2.sh
input var1 var2 :1 2
1 < 2
20.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@localhost ~]# vim test3.sh
2)#! /bin/bash
read -p "input your name:" name
if [ $name == root ]; then
echo "you are super adminnistrator"
else
echo "you are genneral user"
fi
~
3)[root@localhost ~]# bash test3.sh
input your name:centos
you are genneral user
例2 在做字符串大小的时候,注意字符串的顺序
大于号和小于号必须转义,要不然SHELL会把他当成是重定向符号
大于和小于他们的顺序和sort排序是不一样的
在test比较中,它使用的ASCII顺序,大写字母是小于小写字母的,sort放好相反
①[root@localhost ~]# vim +4 test4.sh
②写入以下内容
#! /bin/bash
var1=test
var2=Test
if [ $var1 \> $var2 ]; then 也可以使用>
echo "$var1 > $var2"
else
echo "$var1 < $var2"
fi
③[root@localhost ~]# bash test4.sh
test > Test
①[root@localhost ~]# vim test5.sh
②#! /bin/bash
if [ -e /etc/passwd ];then
echo ok
else
echo error
fi
③[root@localhost ~]# bash test5.sh
ok
例2 [root@localhost ~]# test -e /etc/aaa.txt && echo ok || echo err
err
[root@localhost ~]# test -e /etc/passwd && echo ok || echo err
ok
清空日志目录
打开sshd
1) [root@localhost ~]# vim clear-log.sh
2)#! /bin/bash
# clear /var/log/messages
# 确定当前用户是root用户
if [ $USER != "root" ];then
echo "你必须使用root用户才能执行脚本"
exit 10 # 直接退出,并返回10
fi
# 判断文件是否存在
if [ ! -f /var/log/messages ];then
echo "文件不存在"
echo 12
fi
# 保留最近100行的日志内容
tail -100 /var/log/messages > /var/log/mesg.tmp
# 日志清除
> /var/log/messages
#cat /dev/null > /var/log/messages
mv /var/log/mesg.tmp /var/log/messages
echo "Logs clean up"
截图如下
3)[root@localhost ~]# bash clear-log.sh
Logs clean up
20.4 流程控制过程中复杂条件和通配符
20.4.1 判断第一种:两个条件都为真或有一个为真就行
if [ 条件判断一 ] && (||)[ 条件判断二];then
命令一
elif [ 条件判断三 ] && (||)[ 条件判断四];then
命令二
else
执行其他
fi
判断第二种
if [ 条件判断一 -a(-o)条件判断二 -a (-o) 条件判断三 ];then
elif [ 条件判断三 -a (-o) 条件判断四 ];then
else
执行其他
fi
例1:设置umask
1)[root@localhost ~]# vim /etc/profile
vim umask.sh
3)
#! /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
例2: [ [ ......] ] 和[.....]的区别
[ [ ] ] 运算符是[....] 运算符的扩充; [[ ]] 能够支持,*,<,> 等符号不需要转义符
[root@localhost ~]# if [[ $USER==R* ]];then echo "hello root";else echo $USER not;fi
hello root
如果是单个括号
就会输出
注意: $USER == r* 对比时, r * 表示以r 开头的任意长度的字符串,也包括了root
当只有一个[] 放括号时
[root@localhost ~]# if [ $USER==R* ];then echo "hello root";else echo $USER not;fi
root not
[root@localhost ~]# ls /etc/*.conf
/etc/asound.conf /etc/e2fsck.conf /etc/libaudit.conf /etc/numad.conf /etc/sudo.conf
/etc/autofs.conf /etc/fprintd.conf /etc/libuser.conf /etc/oddjobd.conf /etc/sudo-ldap.conf
/etc/autofs_ldap_auth.conf /etc/fuse.conf
加入我只想找出三个conf
[root@localhost ~]# ls /etc/???.conf
/etc/nfs.conf /etc/ntp.conf /etc/sos.conf /etc/yum.conf
2)
[root@localhost ~]# touch /opt/a{1,2,3}.txt
[root@localhost ~]# ls /opt/
a1.txt a2.txt a3.txt rh
3)
[root@localhost ~]# ls /opt/a[123].txt
/opt/a1.txt /opt/a2.txt /opt/a3.txt
[root@localhost ~]# ls /opt/a[1,2,3].txt
/opt/a1.txt /opt/a2.txt /opt/a3.txt
20.5 实战-3个shell脚本实战
20.5.1 编写脚本检查服务器运行状态
①[root@localhost ~]# vim status.sh
②
#! /bin/bash
if [ $# -ge 1 ];then
systemctl status $1 > /dev/null
if [ $? -eq 0 ];then
echo "$1 服务正在运行"
else
systemctl start $1
fi
else
echo "执行脚本的格式"
echo "sh $0 服务名"
fi
systemctl start $1
fi
③[root@localhost ~]# bash status.sh sshd
sshd 服务正在运行
20.5.2 实战2: 根据学生的成绩判断,学生的优劣
实战3: 每周一晚上3:00 。备份数据库上webdb 库上的所欲数据到系统的/mysqlbak 目录上
使用系统做备份文件名
1)vim mysqlbak.sh
2)#! /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
~
因为我们还没数据库,这里以/etc/ 目录来做实验
1) vim backetc.sh
2)
#! /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"
3) bash etcbak.sh
-rw-r--r--. 1 root root 11M Apr 10 07:50 /etcbak/2020-04-10-etc.tar.gz
back etc is ok
[root@localhost ~]# ls /etcbak/
2020-04-10-etc.tar.gz -etc.tar.gz
4)
[root@localhost ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
5) 0 3 * * * /root/etcbak.sh 2 >&1 > /dev/null
总结
20.1 read 命令键盘读取变量的值
20.2 流程控制语句if
20.3 test 测试命令
20.4 流程控制过程中复杂条件和通配符
20.5 实战-3 个shell脚本