一、if 条件语句
1、 if条件语句语法
if结构用于在Shell脚本中进行判定。如果指定的条件为真,则执行指定的命令。if语句的基本语法如下所 示:
if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi
或
if TEST-COMMANDS; then
CONSEQUENT-COMMANDS
fi
或
if TEST-COMMANDS
then
CONSEQUENT-COMMANDS
fi
注意:if和then若写在同一行,TEST-COMMANDS与then之间要使用分号 ; 隔开。
if语句结构一定 要以“fi”结尾。
在上述语法中,如果TEST-COMMANDS为真,则CONSEQUENT-COMMANDS将被执行,否则脚本将直接跳转到if结构之后的语句继续执行。
2、 单分支if条件语句
(1)if...then...fi
if test-commands
then
commands
fi
eg:下面我们来看一个使用if语句的实例: 从标准输入读入输入的密码,并判断密码是否正 确:
#!/bin/bash
read -sp "please enter your password: " passwd #输入的密码不在屏幕上显示
if test "$passwd" == "nebula123"
then
echo -e "\npassword verified"
exit 0 #如果变量pass的值为nebula123,则显示密码为通过验证的信息,然后退出脚本的执行,退出的状态码为0
fi
echo -e "\nyour input is wrong" #开启转义
exit 99
(2)if…else…fi
if test-commands
then
commands (test-commands条件为真时)
else
commands (test-commands条件为假时)
fi
#!/bin/bash
read -sp "please enter your password: " passwd
if [ "$passwd" == "nebula123" ]
then
echo -e "\npassword verified"
exit 0
else
echo -e "\nyour input is wrong"
exit 99
fi
3、多分支if条件语句
(1)if语句中或else语句中再嵌入一个完整的if…else…fi结构,这被称为嵌套的if/else语句。 语法:
if test-commands
then
if test-commands1
then
commands (test-commands1条件为真时)
else
commands (test-commands1条件为假时)
fi
else
commands (test-commands条件为假时)
fi
或
if test-commands
then
commands (test-commands条件为真时)
else
if test-commands1
then
commands (test-commands1条件为真时)
else
commands (test-commands1条件为假时)
fi
fi
#/bin/bash
read -t 5 -p "please enter enter an count: " count
if [ $count -eq 100 ]
then
echo -e "\ncount is 100"
else
if [ $count -gt 100 ]
then
echo -e "\ncount is greater than 100"
else
echo -e "\ncount is lesser than 100"
fi
fi
(2)多级的if…elif…else…fi让脚本有多种可能性和条件。
语法:
if test-commands
then
commands (test-commands条件为真时)
elif test-commands1
then
commands (test-commands1条件为真时)
elif test-commands2
then
commands (test-commands2条件为真时)
else
commands (test-commands条件为假时)
fi
#!/bin/bash
#read -t 5 -p "please input one number: " num
if [ $# -eq 0 ]
then
echo "$0: you must give one integes"
exit 1
fi
if [ $1 -gt 0 ]
then
echo "The number is positive"
elif [ $1 -lt 0 ]
then
echo "The number is negative"
elif [ $1 -eq 0 ]
then
echo "The number is 0"
else
echo "$1 is not number,give me a number"
fi
4、if练习题
1、创建一个脚本,脚本作用如下:
1).先查看/tmp/nebula这个名称是否存在
2).若不存在则创建一个文件,建立完后退出
3).若存在则判断该名称是否是文件,若为文件则将其删除后创建一个同名目录,之后退出
4).如果存在且为目录则删除此目录
#!/bin/bash
if [ -e "/tmp/nebula" ] #判断文件是否存在
then #文件存在时执行下面语句
if [ -f "/tmp/nebula" ] #判断是否普通文件
then
rm -rf /tmp/nebula
mkdir -p /tmp/nebula
elif [ -d "/tmp/nebula" ] # 判断是否为目录
then
rm -rf /tmp/nebula
fi
else
touch /tmp/nebula #不存在创建
exit 0
fi
2、编写一个猜年龄的游戏程序,程序设置一个默认年龄,然后让用户猜年龄,如果刚好跟你设置的年龄一致,
则提示用户“你猜对了”,否则提示“你猜错了”。(这个脚本需要判断用户输入的是否是数字,如果输入的不
是,需要提示用户输入的错误。)
#! /bin/bash
myage=20
read -t 10 -p "请输入年龄:" age
n=`echo $age | grep "\<[[:digit:]]*\>" > /dev/null`
if [ $? -eq 0]
if [ $age -gt $myage ]
then
echo "你猜大了!"
elif [ $age -lt $myage ]
then
echo "你猜小了"
else
echo "你猜对了!"
else
echo "你输入的不是数字!"
fi
3、编写一个监控脚本,用来监控你的主机的CPU、内存、磁盘使用率,分别设置对应参数指标的阈值,当程序
达到某个阈值时,提示“系统的某个指标性能过高,请排查!”。比如,你设置磁盘的监控指标为根分区的使用
率不超过90%为正常,否则报警。
#! /bin/bash
disk=df -h | grep '/$' | awk '{print $5}' | cut -d '%' -f 1
cpu=expr 100 - $(mpstat | tail -1 | awk '{print $13}' | awk -F. '{print $1}')
Mem=expr $(free -m | tail -2 | head -n 1 | awk '{print $7}') \* 100 / $(free -m
| tail -n 2 | head -n 1 | awk '{print $2}')
if [ $disk -gt 90 ] || [ $cpu -gt 50 ] || [ $Mem -gt 100 ]
then
echo "系统的某个指标性能过高,清排查"
else
echo "系统指标正常"
fi
if [ $disk -gt 90 ]
then
echo "disk使用率超过90%,请排查"
fi
if [ $cpu -gt 90 ]
then
echo "CPU使用率超过90%,请排查"
fi
if [ $Mem -gt 90 ]
then
echo "Mem使用率超过90%,请排查"
fi
4、根据用户名查询该用户的所有信息,比如返回用户的用户名、uid、gid、家目录、组名以及是否能登录本
系统
#!/bin/bash
#Function:根据用户名查询该用户的所有信息
read -p "请输入要查询的用户名:" A
echo "------------------------------"
n=`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}' | wc -l`
if [ $n -eq 0 ];then
echo "该用户不存在"
echo "------------------------------"
else
echo "该用户的用户名:$A"
echo "该用户的UID:`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}'|awk -F:
'{print $3}'`"
echo "该用户的组为:`id $A | awk {'print $3'}`"
echo "该用户的GID为:`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}'|awk -F:
'{print $4}'`"
echo "该用户的家目录为:`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}'|awk -F:
'{print $6}'`"
Login=`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}'|awk -F: '{print $7}'`
if [ $Login == "/bin/bash" ];then
echo "该用户有登录系统的权限!!"
echo "------------------------------"
elif [ $Login == "/sbin/nologin" ];then
echo "该用户没有登录系统的权限!!"
echo "------------------------------"
fi
fi
#! /bin/bash
read -p "请输入用户名:" name
echo "name:$name"
uid=`id $name|awk '{print $1}'`
gid=`id $name|awk '{print $2}'`
home=`cat /etc/passwd|grep $name|awk -F: '{print $6}'`
group=`cat /etc/group|grep $name|awk -F: '{print $1}'`
shell=`cat /etc/passwd|grep $name|awk -F: '{print $7}'`
echo "$uid"
echo "$gid"
echo "home:$home"
echo "group:$group"
if test "$shell" == "/sbin/nologin"
then
echo "$name is Non-logged user"
else
echo "$name is login user"
fi
5、创建一个脚本,该脚本可以根据你输入的日期计算出你还有多少天过生日
#!/bin/bash
read -p "请输入你生日(例如08-20)" num
year=`date +%Y` #以两位数字格式打印年份
A=`date -d "${year}-${num}" +%j`
B=`date +%j` #本年第几天
if [ $A -lt $B ] # A<B
then
year=$((year+1))
D=`date -d "$year-12-31" +%j`
F=`date -d "${year}-${num}" +%j`
E=`expr $D - $B + $F`
echo "您的生日已过,还有$E天就要过生日了"
else
C=`expr $A - $B`
echo "您的生日还有:$C 天"
fi
二、case条件语句
1、语法
case expression in
模式1)
conmmands1;;
模式2)
conmmands2;;
模式3)
conmmands3;;
esac
如果表达式(expression)匹配到模式1,则执行conmmands1,匹配到模式2,则执行conmmands2,依次类推;case条件语句以esac结尾;
注意:每写完一个commands必须以两个分号结尾。
2、实例
我们通过下面的实例来感受一下;
#!/bin/bash
read -p "please input a number or a str: " n
case $n in
[0-9])
echo "this is a number";;
[a-Z])
echo "This is a str";;
*)
echo "not known" ;;
esac
#!/bin/bash
read -p "请输入进程ID及你想要发送的信号值: " a b
case "$b" in
练习
while循环
1)
echo "Sending SIGHUP signal to pid $a"
kill -SIGHUP $a;;
#向指定的PID发送SIGHUP信号
2)
echo "Sending SIGINT signal to pid $a"
kill -SIGINT $a;;
9)
echo "Sending SIGKILL signal to pid $a"
kill -SIGKILL $a;;
*)
echo "signal number $b not found"
esac
上述脚本中,特殊变量$a $b分别是指定的进程号和信号值。
使用kill命令,它会发送相应的信号到指 定的进程。
最后一个模式匹配项“*)”表示的是默认匹配项,即表示若脚本中“1)、2)、9)”都没有被匹 配,则匹配此项。
小练习:判断今天是星期几,根据星期几来判断 今天是工作日还是休息日
#!/bin/bash
a=`date +%w` #将日期转换为星期几,用数字0-6表示
case $a in
[1-5])
echo "今天是工作日,社畜没有休息日哦。";;
[06])
echo "哦~今天是休息日呢,请好好休息哦~";;
esac
三、while循环
1、语法
1)
while [ 条件 ] #条件为真 循环一直执行
do
command1
command2
...
commandN
done
#!/bin/bash
i=0
until循环语句
while [ $i -lt 10 ]
do
let i++
echo $i
done
2)
true命令——不做任何事,表示成功,总是返回退出状态码0。
false命令——不做任何事,表示成功,总是返回退出状态码1。
:命令——无作用,此命令也不做任何事,总是返回退出状态码0。
#无限循环
while :
do
commands
done
#!/bin/bash
# Author: Nebula xiaoxing
# Emal: 454562487@qq.com
# Time: 2023-01-08 11:03:19
# Name: while.sh
# Version: v1.0
# Description: This is a Script.
i=0
while false
do
let i++
echo $i
done
四、until循环
1、语法
until循环与while循环类似,也同样基于一个条件。但until循环的判断条件正好与while循环的判断 条件相反,until循环在条件为假的情况下才会持续地运行。一旦条件被满足,即为真,就会退出循环。
until循环的语法如下所示:
until [ CONDITION ]
do
command1
command2
…
…
command
done
2、实例
#!/bin/bash
i=0
until [ $i -gt 10 ]
do
echo "The loop is run $i times"
i=$((i+1))
done
也是就是它会一直循环执行,直到不满足until的条件。
五、for循环
Shell可以重复地执行特定的指令,直到特定的条件被满足时为止。这重复执行的一组命令就叫做循 环。
每一个循环都具有如下特点:
(1)首先,循环条件中使用的变量必须是已初始化的,然后在循环中开始执行。
(2)在每一次循环开始时进行一次测试。
(3)重复地执行一个代码块
1)
for $var in item1..... #条件
do
commands
....
done
2)
for $var in $N
do
commans
...
done
3))for循环还有三项表达式语法,这种语法与C语言中常见的for循环使用方法相同,其语法如下所示
for((exp1;exp2;exp3))
do
commands
...
done
4)
for $var in {1,n}
do
commands
...
done
#!/bin/bash
for i in 1 2 3 4 5
do
echo "The loop is run $i times!"
done
#!/bin/bash
for((i=0;i<10;i++))
do
for ((n=0;n<5;n++))
do
echo -n "*" #打印*并不掉末尾的换行符,效果就是一行有5个*
done
echo ""
done
- for循环经常会用到的例子
1.1产生随机数
方法1: 通过环境变量RANDOM 随机数范围0-32767 一般可以搭配加密算法配合使用;
Linux系统常见的加密算法命令 【sha1sum、 sha128sum 、sha256sum 、sha512sum、 sha384sum 、md5sum】
一般取随机数从第2位开始切,更能保证它是一个随机数;
[root@node1 ~]# echo $RANDOM
1865
[root@node1 ~]# echo "nebula$RANDOM"|md5sum | cut -d " " -f1 |cut -c 2-16
a992fa3aa2be325 <======获取到15位随机字符
方法2 :使用openssl的随机函数
openssl rand [-out file] [-rand file(s)] [-base64] [-hex] num
##########################
-out :指定随机数输出文件,否则输出到标准输出。
-rand file :指定随机数种子文件。种子文件中的字符越随机,openssl rand生成随机数的速度
越快,随机度越高。
-base64 :指定生成的随机数的编码格式为base64。
-hex :指定生成的随机数的编码格式为hex。
##########################
num :指定随机数的长度。
[root@node1 ~]# openssl rand -base64 12
pmxxVoeM0KuxYjpp
[root@node1 ~]#
方法3 :通过date命令获取,可以搭配加密算法
[root@node1 ~]# date +%s
1638276870
[root@node1 ~]# date +%N
916287501
[root@node1 ~]# date +%N%s
8122225971638276890
[root@node1 ~]#
[root@node1 ~]# date +%s | sha512sum |base64|head -1|cut -c 8-39
hZDI5ZmI0OWQyZGQ1ZDA3ODc2Nzc5M2I
方法4 :通过/dev/unrandom 生成,/dev/urandom存储着系统当前运行环境的实时数据,可以看到
系统在某个时刻的唯一值,可以通过读取文件的方式,读取设备中的数据
[root@node1 ~]# cat /dev/urandom | od -x | tr -d " "| head -1| cut -c 8-
d15460933f8e81769efce888c6f4a9c9
[root@node1 ~]# head /dev/urandom |cksum | tr -d " "
18787492911556
方法5 :通过UUID生成
[root@node1 ~]# cat /proc/sys/kernel/random/uuid
dcc9071f-5109-4d75-b363-1f9092f08916
[root@node1 ~]# cat /proc/sys/kernel/random/uuid
67cc1bb3-5100-4ef6-b5a6-efb3ecc85a50
[root@node1 ~]# cat /proc/sys/kernel/random/uuid
1115e88e-7877-466f-955e-20074eb53c71