1、单分支模式
if 条件测试 then 命令序列 fi
if 条件测试 ; then 命令序列 fi
案例:
[root@localhost jiaofan]# cat b.sh #!/bin/bash if [ -z $1 ] then echo "错误:未输入服务名称" echo "用法:脚本名 服务器名称" fi if systemctl is-active $1 &> /dev/null ; then echo "$1 已经启动" else echo "$1 未启动" exit 1 fi if systemctl is-enabled $1 &>/dev/null ; then echo "$1 是开机自选项" else echo "$1 不是开机自选项" fi [root@localhost jiaofan]# ./b.sh 错误:未输入服务名称 用法:脚本名 服务器名称 未启动 [root@localhost jiaofan]# ./b.sh sshd sshd 已经启动 sshd 是开机自选项 [root@localhost jiaofan]# ./b.sh mysql mysql 未启动 [root@localhost jiaofan]#
2、双分支模式
if 条件测试 ; then 命令序列1 else 命令序列2 fi
案例:一键源码安装nginx软件包
[root@localhost jiaofan]# vi install_nginx.sh
#!/bin/bash
#功能描述:一键源码安装nginx软件包
#定义不同的颜色属性
setcolor_failure="echo -en \033[91m"
setcolor_success="echo -en \033[32m"
setcolor_normal="echo -en \033[0m"
#判断是否以管理员身份执行脚本
if [[ $UID -ne 0 ]];then
$setcolor_failure
echo -n "请以管理员身份运行"
$setcolor_normal
exit
fi
#判断系统中是否存在wget下载工具
#wget使用-c选项可以开启断点续传功能
if rpm --quiet -q wget ; then
wget -c http://nginx.org/download/nginx-1.21.6.tar.gz
else
$setcolor_failure
echo -n "未找到wget,请先下载......"
$setcolor_normal
exit
fi
#如果没有nginx账户,则脚本自动创建该账户
if ! id nginx &> /dev/null ; then
adduser -s /sbin/nologin nginx
fi
#测试是否存在正确的源码包软件
#在源码包编译安装之前,先安装相关的依赖包
if [[ ! -f nginx-1.21.6.tar.gz ]];then
$setcolor_failure
echo -n "未找到nginx源码包,请先下载......"
$setcolor_normal
exit
else
yum -y install gcc pcre-devel zlib-devel openssl-devel
clear
$setcolor_success
echo -n "接下来,需要花费几分钟编译安装nginx"
$setcolor_normal
sleep 6
tar -xf nginx-1.21.6.tar.gz
#编译源码包安装 nginx ,指定账户和组,指定安装路径,开启需要的模块,禁用不需要的模块
cd nginx-1.21.6/
./configure
--user=nginx
--group=nginx
--prefix=/data/server/nginx
--with-stream
--with-http_ssl_module
--with-http_stub_status_module
--without-http_autoindex_module
--without-http_ssi_module
make
make install
fi
if [[ -x /data/server/nginx/sbin/nginx ]];then
clear
$setcolor_success
echo -n "一键部署 nginx 已经完成"
$setcolor_normal
fi
3、多分支模式
if 条件测试1 ; then 命令序列1 elif 条件测试2 ; then 命令序列2 elif 条件测试3 ; then 命令序列4 ... ... else 命令序列n fi
案例:脚本自动生成10以内的随机数,根据用户的输入,判断输出结果
[root@localhost jiaofan]# cat guess_num.sh
#!/bin/bash
#功能描述:脚本自动生成10以内的随机数,根据用户的输入,判断输出结果
clear
num=$[RANDOM%10+1]
read -p "请输入1~10之间的整数:" guess
if [ ${guess} -eq ${num} ] ; then
echo "恭喜,猜对了,就是$num"
elif [ $guess -lt $num ];then
echo "Oops,猜小了。"
else
echo "Oops,猜大了。"
fi
[root@localhost jiaofan]# ./guess_num.sh
请输入1~10之间的整数:8
Oops,猜大了。
[root@localhost jiaofan]#
二、选择:case
结束使用 ;; 还是 ;& 。如果使用 ;; 则代表不在往下进行匹配,;& 代表继续往下进行匹配。
case word in 模式1:) 命令序列1;; 模式2:) 命令序列2;; ... ... 模式*:) 命令序列n;; esac
case word in 模式1|模式2|模式3:) 命令序列1;; 模式4|模式5|模式6:) 命令序列2;; ... ... 模式*:) 命令序列n;; esac
[root@localhost jiaofan]# cat echo_menu.sh
#!/bin/bash
#功能描述:定义功能菜单,使用case语句判断用户选择的菜单项,实现对应功能
clear
echo -e " 33[42m--------------------------------- 33[0m"
echo -e "e[2;10H 这里是菜单tt"
echo -e "#e[32m 1.查看网卡信息e[0m #"
echo -e "#e[33m 2.查看内存信息e[0m #"
echo -e "#e[34m 3.查看磁盘信息e[0m #"
echo -e "#e[35m 4.查看CPU信息e[0m #"
echo -e "#e[36m 5.查看账户信息e[0m #"
echo -e " 33[42m--------------------------------- 33[0m"
echo
read -p "请输入选项【1-5】:" key
case $key in
1)
ip a ;;
2)
mem_liyonglv=`free -t | awk 'NR == 2 {printf("%.2f% "), $3/$2*100}'`
mem=$(free | grep Mem | tr -s " " | cut -d" " -f7)
echo "本机内存剩余容量为:${mem}K。"
echo "本机内存利用率为:${mem_liyonglv}。"
;;
3)
root_free=$(df | grep /$ | tr -s " " | cut -d" " -f4)
echo "本机根分区剩余容量为:${root_free}K。"
;;
4)
cpu=$(uptime | tr -s " " | cut -d" " -f13)
cpu_liyonglv=$(top -b -n1 | head -5 | grep ^%Cpu | awk '{printf("%.2f%"),100-$8}')
echo "本机 cpu 15min 的平均负载为:$cpu。"
echo "本机 cpu 利用率为:$cpu_liyonglv。"
;;
5)
login_number=$(who | wc -l)
total_number=$(cat /etc/passwd | wc -l)
echo "当前系统账号为$USER"
echo "当前登录系统的账号数为:$login_number"
echo "当前系统中总用户数为:$total_number";;
*)
echo "输入有误,超出1-5的范围";;
esac
[root@localhost jiaofan]# ./echo_menu.sh
---------------------------------
这里是菜单
# 1.查看网卡信息 #
# 2.查看内存信息 #
# 3.查看磁盘信息 #
# 4.查看CPU信息 #
# 5.查看账户信息 #
---------------------------------
请输入选项【1-5】:2
本机内存剩余容量为:283784K。
本机内存利用率为:56.14% 。
[root@localhost jiaofan]#
案例2:不区分y和yes
[root@localhost jiaofan]# sh case-demo3.sh 你确定需要执行该操作吗(y|n)y 注意:你选择的是yes [root@localhost jiaofan]# sh case-demo3.sh 你确定需要执行该操作吗(y|n)no 你选择的是no [root@localhost jiaofan]# cat case-demo3.sh #!/bin/bash #功能描述:交互脚本,识别用户的输入信息 #可以输入y或yes,不区分大小写 #可以输入n或no,不区分大小写 #使用|分隔多个模式匹配,表示或关系,匹配任意模式即可成功 read -p "你确定需要执行该操作吗(y|n)" key case $key in [Yy]|[Yy][Es][Ss]) echo "注意:你选择的是yes";; [Nn]|[Nn][Oo]) echo "你选择的是no";; *) echo "无效的输入";; esac [root@localhost jiaofan]#三、循环:for、while
for name [ in [ word jiaofan ... ] ] do 命令序列 done
for name #<==默认取值为$@ do 命令序列 done
for (( i=1 ; i<=8 ; i++ )) do 命令序列 done
while 条件判断 do 命令序列 done
案例一:自动生成数
[root@localhost ~]# cat chess.sh
#!/bin/bash
#功能描述:打印国际象棋棋盘
for i in {1..8}
do
for j in {1..8}
do
sum=$[i+j]
if [[ $[sum%2] -ne 0 ]];then
echo -ne "e[41m e[0m"
else
echo -ne "e[47m e[0m"
fi
done
echo
done
四、until和select
until 和 while 刚刚相反,until 是满足条件时退出循环。
until 条件判断 do 命令序列 done
select 变量名 in 值列表 do 命令序列 done
案例1:了解until
[root@localhost jiaofan]# ./until.sh 1 2 3 4 5 [root@localhost jiaofan]# cat until.sh #!/bin/bash #until 语句仅当条件判断为真时才退出循环 i=1 until [[ $i > 5 ]] do echo $i let i++ done [root@localhost jiaofan]#
案例2:了解 select
[root@localhost jiaofan]# cat b.sh
#!/bin/bash
select i in {1..4}
do
echo $i
done
[root@localhost jiaofan]# ./b.sh
1) 1
2) 2
3) 3
4) 4
#? 2
2
#? 4
4
#? ^C
[root@localhost jiaofan]#
案例3:了解 select
[root@localhost jiaofan]# cat a.sh #!/bin/bash echo "请根据提示选择一个选项" select item in "CPU" "ip" "mem" "exit" do case $item in "CPU") uptime;; "ip") ip a s;; "mem") free;; "exit") exit;; *) echo error; esac done [root@localhost jiaofan]# ./a.sh 请根据提示选择一个选项 1) CPU 2) ip 3) mem 4) exit #? 1 16:35:55 up 6:35, 1 user, load average: 0.00, 0.01, 0.05 #? 4 [root@localhost jiaofan]#五、中断与退出:continue、break 和 exit
| 命令 | 作用 |
|---|---|
| continue | 结束单词循环,比如循环10次,但是第三次不用循环,这时就可以用这个跳出第三次循环 |
| break | 结束整个循环体 |
| exit | 退出程序,不管还有多少没有执行的,反正就是结束了 |
正常情况下:
[root@localhost jiaofan]# ./cbe.sh
* * * * *
* * * * *
* * * * *
* * * * *
* * * * *
[root@localhost jiaofan]# cat cbe.sh
#!/bin/bash
#测试continue、break、exit
for i in {1..5}
do
for ((j=0;j<5;j++))
do
echo -n "* "
done
echo
done
案例2:continue测试:当$i=3 && $j=3时,也就是打印第三行第三列时,执行continue,可以看到没有打印33
[root@localhost jiaofan]# ./cbe.sh
10 11 12 13 14
20 21 22 23 24
30 31 32 34
40 41 42 43 44
50 51 52 53 54
[root@localhost jiaofan]# cat cbe.sh
#!/bin/bash
#测试continue、break、exit
for i in {1..5}
do
for ((j=0;j<5;j++))
do
if [[ $i -eq 3 && $j -eq 3 ]] ;then
continue
fi
echo -n "$i$j "
done
echo
done
[root@localhost jiaofan]#
案例3:break:在每一行执行到第三例时遇到break,可以看到直接跳出了循环,但是仍然会执行外循环。break可以跳出自己所在的for循环。
[root@localhost jiaofan]# ./cbe.sh
10 11 12
20 21 22
30 31 32
40 41 42
50 51 52
[root@localhost jiaofan]# cat cbe.sh
#!/bin/bash
#测试continue、break、exit
for i in {1..5}
do
for ((j=0;j<5;j++))
do
if [[ $j -eq 3 ]] ;then
break
fi
echo -n "$i$j "
done
echo
done
[root@localhost jiaofan]#
案例4:exit:遇到exit,直接退出脚本
[root@localhost jiaofan]# ./cbe.sh
10 11 12 [root@localhost jiaofan]# cat cbe.sh
#!/bin/bash
#测试continue、break、exit
for i in {1..5}
do
for ((j=0;j<5;j++))
do
if [[ $j -eq 3 ]] ;then
exit #<==直接退出脚本
fi
echo -n "$i$j "
done
echo
done
[root@localhost jiaofan]#
六、IFS 默认分隔符
在Shell 中使用内部变量IFS (Internal Field Seprator)来决定项目列表或值列表的分隔符,IFS 的默认值为空格、Tab 制表符或换行符。使用 for 循环读取项目列表或值列表时,就会根据IFS 的值判断列表中值的个数,最终决定循环的次数。
特殊的控制字符,可以设置分隔符为特殊控制字符。
| 控制字符 | 描述 |
|---|---|
| a | Bell响铃符 |
| b | Backspace退格符 |
| f | Form Feed 换行符,光标仍旧停留在原来的位置 |
| n | New Line 换行符,且光标移至行首 |
| r | Return 光标移至行首,但不换行 |
| t | Horizontal Tab 水平制表符 |
| v | Vertical Tab 垂直制表符 |
| nnn | 任意八进制字符 |
案例一:输出查看$IFS
[root@localhost ~]# echo $IFS #<==因为IFS的值是空格或Tab制表符,所以无法显示内容,另外IFS的值还是换行符,所以有空行 [root@localhost ~]# printf "%s" $IFS #<==printf 也无内容 [root@localhost ~]# printf "%s" "$IFS" | od -b #<==转换成八进制看看,040是空格键、011是Tab制表符、012是换行符。 0000000 040 011 012
案例二:修改IFS
[root@localhost ~]# OLD_IFS="$IFS" #<==备份原来的,也可以自己设置默认值 [root@localhost ~]# IFS=";" #<==设置分隔符为“;” [root@localhost ~]# read -p "请输入3个数字:" x y z #<==以空格为分隔符测试 请输入3个数字:a b c [root@localhost ~]# echo $x a b c #<==abc三个值都分给你x [root@localhost ~]# echo $y $z [root@localhost ~]# read -p "请输入3个数字:" x y z #<==以分号为分隔符测试 请输入3个数字:a;b;c [root@localhost ~]# echo $x #<==成功 a [root@localhost ~]# echo $y b [root@localhost ~]# echo $z c [root@localhost ~]# IFS="$OLD_IFS" #<==恢复之前的值。
案例三:设置IFS为特殊控制字符
错误设置
[root@localhost ~]# IFS="t" #错误设置,实际这是以字母t为分隔符 [root@localhost ~]# read -p "请输入3个数字:" x y z 请输入3个数字:a b c #<==中间是Tab键进行分隔的 [root@localhost ~]# echo $x #<==测试结果是设置错误 a b c [root@localhost ~]# echo $y $z [root@localhost ~]# read -p "请输入3个数字:" x y z #<==测试是不是以t为分隔符 请输入3个数字:atbtc [root@localhost ~]# echo $x a [root@localhost ~]# echo $y b [root@localhost ~]# echo $z c
正确设置:$‘string’ 必须是单引号
[root@localhost ~]# IFS=$"t" #<==双引号设置出现错误 [root@localhost ~]# read -p "请输入3个数字:" x y z 请输入3个数字:a b c [root@localhost ~]# echo $x a b c [root@localhost ~]# IFS=$'t' #<==单引号设置成功 [root@localhost ~]# read -p "请输入3个数字:" x y z 请输入3个数字:a b c [root@localhost ~]# echo $x a [root@localhost ~]# echo $y b [root@localhost ~]# echo $z c [root@localhost ~]# IFS=$' tn' #<==恢复默认设置:空格、Tab制表符或换行符。



