目录
1.read命令键盘读取变量的值
从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY
read常用见用法及参数
示例1:从标准输入读取一行并赋值给变量passwd
示例2:读取多个值,从标准输入读取一行,直至遇到第一个空白符或换行符。把用户键入的第一个词存到变量
示例 3:read -s passwd 将你输入的东西隐藏起来,值赋给passwd。这个用户隐藏密码信息
示例4:输入的时间限制
示例5:输入的长度限制
示例6:使用-r参数输,允许让输入中的内容包括:空格、/、\、 ?等特殊字符串。
示例7:-p 用于给出提示符,在前面的例子中我们使用了echo –n “…“来给出提示符
方法1:
方法2:
示例8:综合实例
test_read.sh脚本:
运行结果:
2.流程控制语句if
(1)单分支
if 条件
then
commands
fi
示例:
if_1.sh脚本:
运行结果:
(2)双分支if语句
if command ; then
commands
else
commands
fi
示例:
if_2.sh脚本1:
运行结果1:
if_2.sh脚本2:
运行结果2:
(3)多分支if语句
if条件测试操作1 ; then
commands
elif 条件测试操作2 ; then
commands
elif 条件测试操作3 ; then
commands
.......
else
commands
fi
示例:
if_3.sh脚本:
运行结果:
3.test命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
格式:test 测试条件
如果结果为真,用$?=0表示,反之为假,用非0表示
(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” ]
示例:
test1.sh脚本:
运行结果:
示例2:
test2.sh脚本:
运行结果:
(2)字符串比较
参数. | 说明 | 示例 |
== | 等于则为真 | [ “$a” == “$b” ] |
!= | 不相等则为真 | [ “$a” != “$b” ] |
-z 字符串. | 字符串的长度为零则为真 | [ -z “$a” ] |
-n 字符串 | 字符串的长度不为空则为真 | [ -n “$a” ] |
str1 > str2 | str1大于str2为真 | [ str1 \> str2 ] |
str1 < str2 | str1小于str2为真 | [ str1 \< str2 ] |
示例1:
test3.sh脚本:
运行结果:
注意:
在做字符串大小比较的时候,注意字符串的顺序
- 大于号和小于号必须转义,要不然SHELL会把它当成重定向符号
- 大于和小于它们的顺序和sort排序是不一样的
在test比较测试中,它使用的是ASCII顺序,大写字母是小于小写字母的,A是65,a是97;sort刚好相反
示例2:
test4.sh脚本:
运行结果:
(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 ] |
示例1:
test5.sh脚本:
运行结果:
示例2:
示例3:
clear_log.sh
运行结果:
注:退出码 exit ,取值范围是0-255
exit用法示例:
4.流程控制过程中复杂条件和通配符
(1)复杂条件
1)判断第一种:两个条件都为真或有一个为真就执行
if [ 条件判断一 ] && (||) [ 条件判断二 ]; then
命令一
elif [ 条件判断三 ] && (||) [ 条件判断四 ]; then
命令二
else
执行其它
fi
2)判断第二种
if [条件判断一 -a (-o) 条件判断二 -a (-o) 条件判断三]; then
elif [条件判断三 -a (-o) 条件判断四 ]; then
else
执行其它
fi
3)判断第三种
if [[条件判断一 && (||) 条件判断二 ]]; then
elif [[ 条件判断三 && (||) 条件判断四 ]]; then
else
执行其它
fi
如/etc/profile中的umask的设置:
示例1:
umask.sh
运行结果:
(2)[[ 。。。 ]]和[ 。。。]的区别
[[… ]] 运算符是[… ]运算符的扩充;[[… ]]能够支持 *,< 、>等符号且不需要转义符
注: $USER == r*对比时, r* 表示以r开头的任意长度字符串,这样就包括root
注:此时就表示两个字符 r*
[[ 。。。 ]]和[ 。。。]的区别汇总:
- 1、所有的字符与逻辑运算符直接用“空格”分开,不能连到一起。
- 2、在[… ]表达式中,常见的> 、<需要加转义符\,大小比较
- 3、进行逻辑运算符&& 、||比较时;如果用的[ ]符号,则用在外面,如[… ] && [… ] || [ …]如果在[…]里面进行逻辑与或的比较,则用-a、-o进行表示,如[ x = y –a x < z –o x > m ]
- 4、[[… ]] 运算符只是[… ]运算符的扩充;能够支持< 、>符号运算不需要转义符;它还是以字符串比较大小。里面支持逻辑运算符 || 、 && , 不再使用-a 、-o
- 5、[[…]] 用 && 而不是 -a 表示逻辑“与”;用 || 而不是 -o表示逻辑“或”
- 6、[[… ]]可以进行算术扩展,而[ ... ]不可以
- 7、[[...]]能用正则,而[...]不行
- 8、双括号(( ))用于数学表达式
- 9、双方括号号[[ ]]用于高级字符串处理,比如“模糊匹配”
(3) shell中的通配符
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这三个字符串之一。 |
5.3个shell脚本的实战
实战1:
编写脚本检查服务器运行状态
#!/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
实战2:
根据学生的成绩判断 学生的优劣
#!/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:
备份数据库服务器上webdb库的所有数据到系统的/mysqlbak目录里,使用系统日期做备份文件名。
#!/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