0
点赞
收藏
分享

微信扫一扫

shell编程--判断、选择、循环、中断、IFS

江南北 2022-02-13 阅读 102

一、判断:if

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 "\033[42m---------------------------------\033[0m"
echo -e "\e[2;10H 这里是菜单\t\t"
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 "\033[42m---------------------------------\033[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 的值判断列表中值的个数,最终决定循环的次数。

特殊的控制字符,可以设置分隔符为特殊控制字符。

控制字符描述
\aBell响铃符
\bBackspace退格符
\fForm Feed 换行符,光标仍旧停留在原来的位置
\nNew Line 换行符,且光标移至行首
\rReturn 光标移至行首,但不换行
\tHorizontal Tab 水平制表符
\vVertical 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=$' \t\n'       #<==恢复默认设置:空格、Tab制表符或换行符。
举报

相关推荐

0 条评论