1、单分支模式
if 条件测试then命令序列fi
if 条件测试 ; then命令序列fi
案例:
[root@localhost jiaofan]# cat b.sh#!/bin/bashif [ -z $1 ]thenecho "错误:未输入服务名称"echo "用法:脚本名 服务器名称"fiif systemctl is-active $1 &> /dev/null ; thenecho "$1 已经启动"elseecho "$1 未启动"exit 1fiif systemctl is-enabled $1 &>/dev/null ; thenecho "$1 是开机自选项"elseecho "$1 不是开机自选项"fi[root@localhost jiaofan]# ./b.sh错误:未输入服务名称用法:脚本名 服务器名称 未启动[root@localhost jiaofan]# ./b.sh sshdsshd 已经启动sshd 是开机自选项[root@localhost jiaofan]# ./b.sh mysqlmysql 未启动[root@localhost jiaofan]#
2、双分支模式
if 条件测试 ; then命令序列1else命令序列2fi
案例:一键源码安装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 exitfi#判断系统中是否存在wget下载工具#wget使用-c选项可以开启断点续传功能if rpm --quiet -q wget ; then wget -c http://nginx.org/download/nginx-1.21.6.tar.gzelse $setcolor_failure echo -n "未找到wget,请先下载......" $setcolor_normal exitfi#如果没有nginx账户,则脚本自动创建该账户if ! id nginx &> /dev/null ; then adduser -s /sbin/nologin nginxfi#测试是否存在正确的源码包软件#在源码包编译安装之前,先安装相关的依赖包if [[ ! -f nginx-1.21.6.tar.gz ]];then $setcolor_failure echo -n "未找到nginx源码包,请先下载......" $setcolor_normal exitelse 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_modulemakemake installfiif [[ -x /data/server/nginx/sbin/nginx ]];then clear $setcolor_success echo -n "一键部署 nginx 已经完成" $setcolor_normalfi
3、多分支模式
if 条件测试1 ; then命令序列1elif 条件测试2 ; then命令序列2elif 条件测试3 ; then命令序列4..、...else命令序列nfi
案例:脚本自动生成10以内的随机数,根据用户的输入,判断输出结果
[root@localhost jiaofan]# cat guess_num.sh#!/bin/bash#功能描述:脚本自动生成10以内的随机数,根据用户的输入,判断输出结果clearnum=$[RANDOM%10+1]read -p "请输入1~10之间的整数:" guessif [ ${guess} -eq ${num} ] ; thenecho "恭喜,猜对了,就是$num"elif [ $guess -lt $num ];thenecho "Oops,猜小了。"elseecho "Oops,猜大了。"fi [root@localhost jiaofan]# ./guess_num.sh 请输入1~10之间的整数:8Oops,猜大了。[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语句判断用户选择的菜单项,实现对应功能clearecho -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"echoread -p "请输入选项【1-5】:" keycase $key in1)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)" keycase $key in[Yy]|[Yy][Es][Ss])echo "注意:你选择的是yes";;[Nn]|[Nn][Oo])echo "你选择的是no";;*)echo "无效的输入";;esac[root@localhost jiaofan]#
三、循环:for、whilefor 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}dosum=$[i+j]if [[ $[sum%2] -ne 0 ]];thenecho -ne "e[41m e[0m"elseecho -ne "e[47m e[0m"fidoneecho done
四、until和selectuntil 和 while 刚刚相反,until 是满足条件时退出循环。
until 条件判断do命令序列done
select 变量名 in 值列表do命令序列done
案例1:了解until
[root@localhost jiaofan]# ./until.sh 12345[root@localhost jiaofan]# cat until.sh #!/bin/bash#until 语句仅当条件判断为真时才退出循环i=1until [[ $i > 5 ]]doecho $ilet i++done[root@localhost jiaofan]#
案例2:了解 select
[root@localhost jiaofan]# cat b.sh#!/bin/bashselect i in {1..4}doecho $idone[root@localhost jiaofan]# ./b.sh 1) 12) 23) 34) 4#? 22#? 44#? ^C[root@localhost jiaofan]#
案例3:了解 select
[root@localhost jiaofan]# cat a.sh#!/bin/bashecho "请根据提示选择一个选项"select item in "CPU" "ip" "mem" "exit"docase $item in"CPU")uptime;;"ip")ip a s;;"mem")free;;"exit")exit;;*)echo error;esacdone[root@localhost jiaofan]# ./a.sh请根据提示选择一个选项1) CPU2) ip3) mem4) 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正常情况下:
[root@localhost jiaofan]# ./cbe.sh * * * * * * * * * * * * * * * * * * * * * * * * * [root@localhost jiaofan]# cat cbe.sh #!/bin/bash#测试continue、break、exitfor i in {1..5}dofor ((j=0;j<5;j++))doecho -n "* "doneechodone
案例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、exitfor i in {1..5}dofor ((j=0;j<5;j++))doif [[ $i -eq 3 && $j -eq 3 ]] ;thencontinuefiecho -n "$i$j "doneechodone[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、exitfor i in {1..5}dofor ((j=0;j<5;j++))doif [[ $j -eq 3 ]] ;thenbreakfiecho -n "$i$j "doneechodone[root@localhost jiaofan]#
案例4:exit:遇到exit,直接退出脚本
[root@localhost jiaofan]# ./cbe.sh 10 11 12 [root@localhost jiaofan]# cat cbe.sh #!/bin/bash#测试continue、break、exitfor i in {1..5}dofor ((j=0;j<5;j++))doif [[ $j -eq 3 ]] ;thenexit #<==直接退出脚本fiecho -n "$i$j "doneechodone[root@localhost jiaofan]#
六、IFS 默认分隔符在Shell 中使用内部变量IFS (Internal Field Seprator)来决定项目列表或值列表的分隔符,IFS 的默认值为空格、Tab 制表符或换行符。使用 for 循环读取项目列表或值列表时,就会根据IFS 的值判断列表中值的个数,最终决定循环的次数。
特殊的控制字符,可以设置分隔符为特殊控制字符。
案例一:输出查看$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 $xa 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 $yb[root@localhost ~]# echo $zc[root@localhost ~]# IFS="$OLD_IFS" #<==恢复之前的值。
案例三:设置IFS为特殊控制字符
错误设置
[root@localhost ~]# IFS="t" #错误设置,实际这是以字母t为分隔符[root@localhost ~]# read -p "请输入3个数字:" x y z请输入3个数字:abc #<==中间是Tab键进行分隔的[root@localhost ~]# echo $x #<==测试结果是设置错误abc[root@localhost ~]# echo $y $z[root@localhost ~]# read -p "请输入3个数字:" x y z #<==测试是不是以t为分隔符请输入3个数字:atbtc [root@localhost ~]# echo $xa[root@localhost ~]# echo $yb[root@localhost ~]# echo $zc
正确设置:$‘string’ 必须是单引号
[root@localhost ~]# IFS=$"t" #<==双引号设置出现错误[root@localhost ~]# read -p "请输入3个数字:" x y z请输入3个数字:abc[root@localhost ~]# echo $xabc[root@localhost ~]# IFS=$'t' #<==单引号设置成功[root@localhost ~]# read -p "请输入3个数字:" x y z请输入3个数字:abc[root@localhost ~]# echo $xa[root@localhost ~]# echo $yb[root@localhost ~]# echo $zc [root@localhost ~]# IFS=$' tn' #<==恢复默认设置:空格、Tab制表符或换行符。