1、read赋值
read通过交互式的方式进行赋值
-p:交互的时候提示信息
-t:超过这个时间没有操作,自动退出
-s:不显示用户的输入,记录密码才用
基本用法:
[root@m01 ~]#read -p "请输入密码:" pass
请输入密码:12345
[root@m01 ~]#echo $pass
12345
[root@m01 ~]#read -p '请输入密码ip和用户名' ip user
请输入密码ip和用户名192.168.10.6 test
[root@m01 ~]#echo $ip
192.168.10.6
[root@m01 ~]#echo $user
test
[root@m01 ~]#
案例1:书写脚本,检查输入的域名是否可以ping通
[root@m01 /server/script/devops-shell]#vim check_url_ping.sh
read -p '请输入域名:' url
ping -c 3 $url &> /dev/null
if [ $? -eq 0 ]
then
echo "域名$url可以ping通。"
else
echo "域名$url ping不通"
fi
2、运算符
shell运算符 | 含义 |
---|---|
+ | 加法 |
– | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余,可以用于生成指定范围的随机数 |
^、** | 幂、指数,如2^10=1024,10个2相乘 |
i=i+1,i++ | 计数 |
j=j+??、j+=?? | 求和 |
&& | 并且,前一个命令执行成功,再执行后面的命令(判断) |
|| | 或者,前一个命令执行失败,再执行后面的命令(判断) |
%:取余
[root@m01 ~]#echo $((4%3))
1
任何一个数对10取余,余数为0-9之间
[root@m01 ~]#echo $((RANDOM%10))
2
[root@m01 ~]#echo $((RANDOM%10))
5
[root@m01 ~]#echo $((RANDOM%10))
8
[root@m01 ~]#echo $((RANDOM%10))
2
[root@m01 ~]#
随机的数字(n)对一个数字取余,可以得到0到n-1范围的随机数
[root@m01 ~]#echo $RANDOM%5 | bc
&&:并且
[root@m01 ~]#ls /etc &> /dev/null && echo 目录存在
目录存在
[root@m01 ~]#
||:或者
[root@m01 ~]#ls /etc &> /dev/null || echo 目录存在
[root@m01 ~]#ls /etc000 &> /dev/null || echo 目录b不存在
目录b不存在
[root@m01 ~]#
3、运算方法
运算的命令、符号 | 说明 | 应用场景 |
---|---|---|
awk | 可以进行计算、带小数,可以与shell脚本进行变量传递 | 一般计算都可以使用awk |
bc | 带小数 | 一般计算都可以使用bc,需要安装 |
expr | 计算,整数 | 用于检查输入内容是否为数字的一种方法 |
let | 计算,整数,变量直接使用即可 | 用于计算i++ |
$(()) | 计算,整数,变量直接使用即可 | |
$[] | 计算,整数,变量直接使用即可 |
1)awk计算
基础用法:
[root@m01 ~]#awk 'BEGIN{print 1/3}'
0.333333
[root@m01 ~]#awk 'BEGIN{print 1/3*100}'
33.3333
[root@m01 ~]#
在shell中使用awk
[root@m01 ~]#a=1
[root@m01 ~]#b=2
[root@m01 ~]#awk -v x=$a -v y=$b 'BEGIN{print x/y,x+y}'
0.5 3
[root@m01 ~]#
案例2:输入两个数字,进行计算
[root@m01 /server/script/devops-shell]#vim 11.num.calc.sh
#输入两个数字
read -p "请输入第1个数字:" num1
read -p "请输入第1个数字:" num2
#计算
awk -vn1=$num1 -vn2=$num2 'BEGIN{print "加法:"n1+n2}'
[root@m01 /server/script/devops-shell]#sh 11.num.calc.sh
请输入第1个数字:2
请输入第1个数字:3
加法:5
[root@m01 /server/script/devops-shell]#
2)bc
安装bc:yum install bc -y
基本用法,-l显示小数
[root@m01 ~]#echo 1/3 | bc
0
[root@m01 ~]#echo 1/3 | bc -l
.33333333333333333333
[root@m01 ~]#
3)expr
使用注意事项:需要使用空格,使用*的时候要转义
[root@m01 ~]#expr 1+2
1+2
[root@m01 ~]#expr 1 + 2 #要使用空格
3
[root@m01 ~]#
*的使用:
[root@m01 ~]#expr 1 * 2
expr: syntax error
[root@m01 ~]#expr 1 \* 2
2
[root@m01 ~]#
注意:expr 0 + 0的返回值是1
[root@m01 ~]#expr 0 + 0
0
[root@m01 ~]#echo $?
1
[root@m01 ~]#
案例3:前面的计算脚本修改:加入判断:
#输入两个数字
read -p "请输入第1个数字:" num1
read -p "请输入第1个数字:" num2
#判断输入的是否为数字
expr "$num1" + "$num2" &> /dev/null
if [ $? -gt 1 ];then #判断返回值是否大于1
echo "Usage:输入必须为数字"
exit 1
fi
#计算
awk -vn1=$num1 -vn2=$num2 'BEGIN{print "加法:"n1+n2}'
4)let、$(())、$[]
不支持小数,一般进行简单计算
let:
[root@m01 ~]#a=1
[root@m01 ~]#b=2
[root@m01 ~]#let c=a+b
[root@m01 ~]#echo $c
3
[root@m01 ~]#let x=3+5
[root@m01 ~]#echo $x
8
[root@m01 ~]#
let与i++:
[root@m01 ~]#i=1
[root@m01 ~]#let i++
[root@m01 ~]#echo $i
2
[root@m01 ~]#
$(()):
[root@m01 ~]#a=1
[root@m01 ~]#b=2
[root@m01 ~]#echo $((a+b))
3
[root@m01 ~]#
$[]:
[root@m01 ~]#a=1
[root@m01 ~]#b=2
[root@m01 ~]#echo $[a+b]
3
[root@m01 ~]#
4、判断
4.1 条件表达式
条件表达式属于判断中的核心
1)格式
条件表达式也可以叫做条件测试语句。
查看帮助:man test
[]与[[]]的区别
含义与特点 | test 或 [] | [[]] 或 (()) |
---|---|---|
共同点 | 都可以用于判断 | 都可以用于判断 |
区别1 | 仅支持普通判断,不支持正则 | [[]]普通判断,支持正则 |
区别2 | 表示逻辑关系(与、或、非)符号不同:-a、-o、!、-gt等 | [[]]使用的是:&&、||、!、>、<、>=、<=等 |
应用场景 | 大部分情况下可以使用[]进行常见判断 | [[]]使用正则的时候使用2对中括号,(())可以用于运算 |
例如:
[root@m01 ~]#[ 1 -eq 2 ] && echo 成功 || echo 失败
失败
[root@m01 ~]#test 1 -eq 2 && echo 成功 || echo 失败
失败
[root@m01 ~]#
2)判断文件
条件表达-文件 | 说明 |
---|---|
-f | f,file。判断是否存在,是否文件,如果是,则为真 |
-d | dir,判断是否存在否是目录,如果是,则为真 |
-x | executable,判断是否存在,是否有执行权限 |
-s | size,小写s。判断是否存在,文件大小是否大于0(是否为空),非空为真 |
-r | 是否有读权限 |
-w | 是否有写权限 |
-nt | newer then,两个文件修改时间,是否更加新 |
-ot | older then,两个文件修改时间,是否更加旧 |
-L | 软连接 |
-e | 是否存在(任何类型的文件) |
条件测试语句,不会直接显示提示对错,通过返回值提示(0则表示真,非0为假)
检查指定文件是否存在
[root@m01 ~]#[ -f 11.txt ] && echo 成功 || echo 失败
失败
[root@m01 ~]#[ -d /etc ] && echo 成功 || echo 失败
成功
[root@m01 ~]#
3)字符串比较
对比两个字符串的内容
字符串对比 | 说明 |
---|---|
“str1” = “str2” | str1是否等于str2,如果相等则为真 |
“str1” != “str2” | str1是否不等于str2,如果不相等则为真 |
-z “str” | z,zero。检查str字符串是否为空,空则为真 |
-n “str” | not zero。检查str字符串是否为空,非空则为真 |
一般情况下,字符串比较使用双引号引起来。如果不使用双引号可以写成:
${str}x=rootx
后面添加一个字符,来确保等号左边的字符串是空的情况下,不会报错
例如:
[root@m01 ~]#input=start
[root@m01 ~]#[ "$input" = "start" ] && echo "成立" || echo "失败"
成立
[root@m01 ~]#
判断是否是root用户执行
[ "$UID" != "0" ] && exit 4
判断服务是否运行、是否开机启动:
[root@m01 ~]#systemctl is-active sshd
active
[root@m01 ~]#systemctl is-enabled sshd
enabled
[root@m01 ~]#
4)比较大小(整数)
大小比较-整数 | [] | [[]] |
---|---|---|
大于 | -gt | > |
大于等于 | -ge | >= |
小于 | -lt | < |
小于等于 | -le | <= |
等于 | -eq | == |
不等于 | -ne | != |
不支持小数的对比
比较小数,可以使用awk
例如:
free -h | awk -F"[ G]+" 'NR==2 && $(NF-1)>=1.2'
5)逻辑判断
逻辑判断:与、或、非
逻辑判断 | [] | [[]] |
---|---|---|
与(同时成立) | 条件1 -a 条件2 (a:and) | && |
或(至少一个成立) | 条件1 -o 条件2 (o:or) | || |
非(取反) | ! | ! |
与:
[root@m01 ~]#[[ 1 > 2 && 1 == 1 ]] && echo 成功 || echo 失败
失败
[root@m01 ~]#[ 1 -gt 2 -a 1 -eq 1 ] && echo 成功 || echo 失败
失败
或:
[root@m01 ~]#[[ 1 > 2 || 1 == 1 ]] && echo 成功 || echo 失败
成功
[root@m01 ~]#[ 1 -gt 2 -o 1 -eq 1 ] && echo 成功 || echo 失败
成功
[root@m01 ~]#[ "a" = "a" -o 1 -eq 1 ] && echo 成功 || echo 失败
成功
非:
[root@m01 ~]#[[ ! 1 == 1 ]] && echo 成功 || echo 失败
失败
[root@m01 ~]#[ ! 1 -eq 1 ] && echo 成功 || echo 失败
失败
[root@m01 ~]#
6)正则表达式
初步使用正则
[root@m01 ~]#a=123
[root@m01 ~]#[[ $a =~ [0-9] ]] && echo 成功 || echo 失败
成功
[root@m01 ~]#b=123ss
[root@m01 ~]#[[ $b =~ [0-9] ]] && echo 成功 || echo 失败
成功
[root@m01 ~]#
上面案例中的正则,仅仅表示变量中只要有数字即可。
案例:精确匹配数字
[root@m01 ~]#b=123ss
[root@m01 ~]#[[ $b =~ ^[0-9]+$ ]] && echo 成功 || echo 失败
失败
[root@m01 ~]#b=123
[root@m01 ~]#[[ $b =~ ^[0-9]+$ ]] && echo 成功 || echo 失败
成功
[root@m01 ~]#[[ "$b" =~ ^[0-9]+$ ]] && echo 成功 || echo 失败
成功
[root@m01 ~]#
#匹配开头中间结尾全是数字
案例02:判断输入的是否为数字
[root@m01 /server/script/devops-shell]#vim 16.check_str.sh
#1、vars
read -p "请输入内容:" str
#2、判断
#是否为纯数字
[[ "$str" =~ ^[0-9]+$ ]] && {
echo "$str是纯数字"
exit #默认是0
}
#是否为纯字母
[[ "$str" =~ ^[a-zA-Z]+$ ]] && {
echo "$str是纯字母"
exit #默认是0
}
#其他
echo "$str 是数字、字母、其他组合"
缺点:如果输入的是小数,则会认为是其他,但小数也数字。
[[]]判断的坑:
[root@m01 ~]#[[ 100 > 20 ]] && echo 成功 || echo 失败
失败 #100大于20,但是结果为失败
[root@m01 ~]#[[ 300 > 20 ]] && echo 成功 || echo 失败
成功
[root@m01 ~]#
[[]]比较大小的时候,是一位一位的比较,先比较第1位,然后第2位…
[[ 100 > 20 ]]:
先比较第1位,1>2,结果为假
[[]]使用>=也可能会报错:
[root@m01 ~]#[[ 100 >= 20 ]] && echo 成功 || echo 失败
-bash: syntax error in conditional expression
-bash: syntax error near `20'
[root@m01 ~]#
因此,不太建议使用[[]]进行比较大小
4.2 if判断
格式1(单分支):
if [];then
xxx
fi
或
if []
then
xxx
fi
格式2(多分支):
if [];then
xx
else
xxx
fi
或者
if [];then
xx
elif
then
xxx
else
xxx
fi
if单分支也可以使用以下方式代替:
[] && xxx
或
[] || xxx
1)单分支判断
应用场景:与&&、||类似,用于放在脚本开头进行判断
if 条件;then
满足条件后执行的内容
fi
if、then可以分开写:
if 条件
then
满足条件后执行的内容
fi
这种形式类似于&&或||形式
if [ 1 -eq 1 ];then
echo "正确"
exit 0
fi
可以写成:
[ 1 -eq 1 ] && {
echo "正确"
exit
}
2)多分支判断
双分支:
if 条件;then
xxx
else
xxx
fi
多分支(2个以上分支):
if 条件;then
xxx
elif #else if可以有多个
then
xxx
elif
then
xxx
else
xxx
fi
案例01:输入服务名称,检查其状态脚本
输入服务名字的方法:read方式或$1
检查是否运行:systemctl is-active 服务
是否开机启动:systemctl is-enabled 服务
[root@m01 /server/script/devops-shell]#vim 17.check_service.sh
#1、var
name=$1
#2、参数个数1个
[ $# -ne 1 ] && {
echo "Please input service name"
exit 1
}
#3、判断状态
run=`systemctl is-active $name`
#是否运行
if [ "$run" = "active" ];then
echo "$name服务is running"
else
echo "$name服务is not running"
fi
#是否开机启动
enable=`systemctl is-enabled $name`
if [ "$enable" = "enabled" ];then
echo "$name服务开机启动"
else
echo "$name服务没有开机启动"
fi
执行脚本:
[root@m01 /server/script/devops-shell]#sh 17.check_service.sh sshd
sshd服务is running
sshd服务开机启动
[root@m01 /server/script/devops-shell]#
案例02:检查根分区磁盘空间使用率
如果大于等于80%,提示磁盘空间不足,否则,提示磁盘空间正常
[root@m01 /server/script/devops-shell]#vim 18.check_disk.sh
#1、vars
root_used=`df -h | grep -w / | awk '{print $(NF-1)}' | awk -F'%' '{print $1}'`
#2、判断
if [ $root_used -gt 80 ];then
echo "磁盘空间不足"
else
echo "磁盘空间正常"
fi
取出使用率也可以写成:
df -h | grep -w / | awk -F'[ %]+' '{print $(NF-1)}'
-w:word
案例03:比大小
num1=20
num2=30
if [ $num1 -eq $num2 ];then
echo "$num1 等于 $num2"
elif [ $num1 -lt $num2 ];then
echo "$num1 小于 $num2"
else
echo "$num1 大于 $num2"
fi
案例04:输出指定用户的信息
检查:
是否输入了用户名
用户是否存在,如果不存在,则退出,提示用户不存在
如果用户存在,则输出:
是否可以登录
uid、gid
用户家目录
最近一次登录情况
脚本:
[root@m01 /server/script/devops-shell]#vim 20.check_user_info.sh
#1、vars
username=$1
#2、检查输入的是否合规
# [[ ! "$username" =~ ^[a-zA-Z0-9_]+$ ]] && {
[[ "$username" =~ ^[a-zA-Z0-9_]+$ ]] || {
echo "请输入正确格式的用户名"
exit 1
}
#3、检查用户是否存在
id $username &> /dev/null
[ $? -ne 0 ] && {
echo "用户不存在"
exit 2
}
#4、获取信息
#是否可以登录(/bin/bash)
shell=`grep -w "^${username}" /etc/passwd | awk -F':' '{print $NF}'`
if [ "$shell" = "/bin/bash" ];then
denglu=yes
else
denglu=no
fi
#uid、gid
ids=`grep -w "^${username}" /etc/passwd | awk -F':' '{print $3,$4}'`
#家目录
homedir=`grep -w "^${username}" /etc/passwd | awk -F':' '{print $(NF-1)}'`
#最后1次登录情况
#lastlog -u 用户名
login=`lastlog -u $username | tail`
#5、信息显示
cat << EOF
#################################
用户名:${username}
是否可以登录:$denglu
uid、gid:${ids}
用户家目录:$homedir
最后一次登录情况:
$login
#################################
EOF
测试脚本:
[root@m01 /server/script/devops-shell]#sh 20.check_user_info.sh
请输入正确格式的用户名
[root@m01 /server/script/devops-shell]#sh 20.check_user_info.sh 66
用户不存在
[root@m01 /server/script/devops-shell]#sh 20.check_user_info.sh root
#################################
用户名:root
是否可以登录:yes
uid、gid:0 0
用户家目录:/root
最后一次登录情况:
Username Port From Latest
root pts/1 192.168.10.1 Sat Jul 15 14:35:09 +0800 2023
#################################
[root@m01 /server/script/devops-shell]#