Shell流程控制

本文详细解析了Shell脚本中的分支结构(if-else、elif、case)、循环结构(for、while)、以及流程控制语句如break和continue的用法,通过实例展示了如何在实际场景中应用这些结构。同时提及了服务管理、定时任务和Shell脚本的扩展性,如环境变量管理、DNF包管理等。
摘要由CSDN通过智能技术生成

流程控制

分支结构、循环结构

分支结构

if 条件判断、case 分支匹配

if 条件判断

  • 单分支

    if 条件判断式
    then
    	动作
    fi
    
  • 双分支

    if 条件判断式
    then
    	动作1
    else
    	动作2
    fi
    
  • 多分支

    if 条件判断式1
    then
    	动作1
    else if	条件判断式2			# elif 可以这样写
    then
    	动作2
    elif 条件判断式n
    then
    	动作n
    else
    	动作
    fi
    

例1:单分支

  • ~/.bash_profile

    # .bash_profile
    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then				#判断有,这个文件
    	. ~/.bashrc							#则,调用这个文件
    fi
    # User specific environment and startup programs
    

例2:双分支

  • /etc/bashrc

    if [ -e /etc/sysconfig/bash-prompt-xterm ]; then		# -e 仅判断文件是否存在,不判断类型
    	PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
    else
    	PROMPT_COMMAND='printf "\033]0:%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
    fi
    

例3:多分支

  • 判断文件类型

    #!/bin/bash
    read -p "请输入需要判断的文件名" file
    if [ -L "$file" ]						# -L 表示软链接
    then
    	echo "${file}是一个软链接文件"
    elif [ -f "$file" ]
    then
    	echo "${file}是一个普通文件"
    elif [ -d "$file" ]
    then
    	echo "${file}是一个目录文件"
    else
    	echo "${file}是一个不常见类型文件,例如:块设备、字符设备、套接字、管道符"
    fi
    

注:软链接目录的结尾加 “/” 表示其源文件目录,不加,表示文件

例4:分支嵌套

  • 判断文件类型 —— 判断软链接最好进行优先判断,软链接存在源文件的类型关系

    #!/bin/bash
    read -p "请输入需要判断的文件名:" file
    if [ -L "$file" ] ; then					# -L 表示软链接
            if [ -f "$file" ] ; then			# 进行二次判断其源文件的文件类型
                    echo "${file}是一个软链接文件,源文件是普通文件"
            elif [ -d "$file" ] ; then
                    echo "${file}是一个软链接文件,源文件是目录文件"
            else
                    echo "${file}是一个不常见类型文件,例如:块设备、字符设备、套接字、管道符"
            fi
    elif [ -f "$file" ] ; then
            echo "${file}是一个普通文件"
    elif [ -d "$file" ] ; then
            echo "${file}是一个目录文件"
    else
            echo "${file}是一个不常见类型文件,例如:块设备、字符设备、套接字、管道符"
    fi
    

注:Linux 不以文件后缀名区分文件类型,但是还是会以文件后缀名区分文件显示规则

例:编写一个定时检查磁盘使用情况的脚本,并写好其定时计划任务

  • 使用 df -h 检查已挂载的分区使用情况

    [root@localhost ~]# df -h
    Filesystem					Size	Used	Avail	Use%	Mounted on
    /dev/mapper/centos-home		1.0T	650G	374G	64%		/home
    
  • 编写脚本 check_disk.sh,检查过滤,/home 的 Use%,达到 80% 提醒

    #/bin/bash
    used=$(df -h|grep "home$"|awk '{print $5}'|cut -d% -f1)
    if [ $used -ge 80 ]
    then
    	echo "$(date +%Y-%m-%d_%H:%M:%S) /home分区使用率超过80%了,请抓紧扩容。" >> /tmp/check.log
    fi
    
  • 定时计划任务,crontab -e

    0 4 * * * bash /root/check_disk.sh
    # 每天凌晨四点整,执行 bash /root/check_disk.sh
    

查看日志:tailf /var/log/cron —— 查看脚本调用的记录

case 分支匹配 —— 匹配多种可能性,可以预设匹配条件

  • 格式:

    case "变量" in
    预设值1)			#变量和预设值相匹配,就执行动作
    	动作1
    	;;
    预设值2)
    	动作2
    	;;
    ...
    esac
    

补充:/etc/init.d/ —— 服务启动管理目录,也可以管理脚本(CentOS 6)

例:下载源码包 nginx —— nginx.org

  • 将 nginx 的启动管理交给脚本执行 —— 叠加 PATH 环境变量,/bash

    [root@localhost ~]# vim ~/.bash_profile
    #User specific environment
    if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
    then
    	PATH="$HOME/.local/bin:$HOME/bin:$PATH:/bash"		#环境变量叠加一个 /bash目录
    fi
    export PATH
    
  • 编辑后,载入配置文件

    source /root/.bash_profile		# 加载配置文件,使之生效
    
  • 编辑脚本,nginx —— 做源码包服务管理

    [root@localhost ~]# vim nginx
    #!/bin/bash
    nginx="/usr/local/nginx/sbin/nginx"
    case "$1" in		# 调用脚本外的第一个值
    start)
    	$nginx			# 说明,执行脚本 nginx start 表示开启 nginx
    	;;				# ;; 表示结束,跳出
    stop)
    	$nginx -s stop
    	;;
    restart)
    	$0 stop			# "$0" 表示调用脚本本身,表示执行 nginx stop
    	$0 start
    	;;
    test)
    	$nginx -t		# nginx -t,这是配置文件检查工具,检查语法是否有错
    	;;
    *)					# 其它输入情况,统一,给予提示
    	echo "Usage:$0 start|stop|restart|test"
    esac
    
  • 添加可执行权限,然后移动到 /bash

    [root@localhost ~]# chmod +x nginx ; mv ./nginx /bash
    [root@localhost ~]# nginx start ; ngingx stop ; nginx restart ; nginx test
    

注:可以临时性的,叠加环境变量 —— export PATH=$PATH:/bash

补充:dnf —— 比 yum 更强大的源码包管理命令,新版本软件包管理机制 —— 支持自动搜索软件包

循环结构

for 循环 —— 计数循环

  • 格式1

    for i in 值的池	# $(命令)
    do
    	动作
    done
    
  • 格式2

    for ((i=初始值;i<=最大值;i+=自增量))
    do
    	动作
    done
    
  • 无限循环

    for ((;;));do
    	动作
    done
    

例:循环遍历输出

  • 格式1

    #!/bin/bash
    for i in nc1230 nc1231 nc1232 nc1233
    do
    	echo $i		#依次,循环的输出 nc1230 nc1231 nc1232 nc1233
    done
    ##################### 另一种写法 #####################
    for i in $(find /etc/ -name "*.txt")	# 使用命令取值
    do
    	echo $i
    done
    
  • 格式2:做数值累加 1+2+3+4+…+100

    #!/bin/bash
    sum=0
    for ((i=1;i<=100;i++))
    do
    	sum=$(($sum+$i))
    done
    ##################### 进一步完善 #####################
    read -p "请输入最小值:" min
    read -p "请输入最大值:" max
    read -p "请输入累加值:" n
    sum=0
    for ((i=$min;i<=$man;i+=$n))
    do
    	sum=$(($sum+$i))
    done
    echo "${min}${max} 直接的累加结果是 ${sum}"			# 输出
    
  • 无限循环,输出随机数

    #!/bin/bash
    for ((;;))
    do
    	echo $(($RANDOM%100))			# 0-99 的随机数
    done
    ##################### 加上退出条件 #####################
    for ((;;))
    do
    	num=$(($RANDOM%100));echo $num	# 使用变量保存随机数
    	if [ "$num" -eq "88" ]			# 若等于 88
    	then
    		exit						# 则,退出
    	fi
    done
    

注:RANDOM 是一个可以生成随机数字的环境变量

流程控制

流程控制语句

  • exit —— 退出当前脚本
  • break —— 退出当前循环,会继续执行循环结构以外的代码
  • continue —— 仅跳过本次循环,继续执行后续的循环

当存在多循环嵌套时,可以使用数字执行跳出的层数

  • break N
  • continue N

例1:生成随机数,出现 88 则退出脚本

#!/bin/bash

for ((;;));do
	num=$(($RANDOM%100));echo $num
	if [ "$num" -eq "88" ];then					# 出现 88
		exit									# 退出脚本
	fi
done
echo "hello world"

说明:循环输出随机数字,出现 88 以后,脚本直接退出,hello world 不会被输出

例2:生成随机数,出现 88 则退出循环结构

#!/bin/bash

for ((;;));do
	num=$(($RANDOM%100));echo $num
	if [ "$num" -eq "88" ];then
		break
	fi
done
echo "hello world"								# break 仅退出循环,后续代码正常执行

说明:循环输出随机数字,出现 88 结束循环输出,hello world 正常输出

例3:顺序输出 1-9,仅跳过输出数字 5

#!/bin/bash

for i in 1 2 3 4 5 6 7 8 9
do
	if [ "$i" -eq "5" ]		#continue 仅退出符合条件的那一轮循环
	then
		continue
	else
		echo $num
	fi
done
echo "hello world"

说明:continue 仅跳过一轮循环,所以数字 5 不会被输出,跳过后,循环和后续代码正常执行

补充:双层循环嵌套 —— 输出 99乘法表

#!/bin/bash

for i in $(seq 9);do
	for j in $(seq $i);do
		echo -en "${i}x${j}=$(($i*$j))\t"	# -en 配合 \t 规定输出格式
	done
	echo					# 换行
done

说明 —— seq 命令

  • seq 9 —— 输出 1-9
  • seq 5 9 —— 输出 5-9
  • seq 5 2 9 —— 输出 5-9,每次自增 2,也就是 5、7、9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值