【Shell 脚本速成】11、Shell 流程控制 while&case、函数

目录

一、循环语句 until

1.1 until 介绍

1.2 until 语法

1.3 案例

1.4 总结

二、shell 函数

2.1 函数介绍

2.2 函数定义 

2.3 函数调用

三、条件循环语句 case 

3.1 case 介绍

3.2 case 语法

3.4 案例

四、综合案例


 

一、循环语句 until

        系统中还有一个类似while的循环语句,大家可以看看until语句,不同于while的是,当条件为假时开始until循环。

1.1 until 介绍

特点:条件为假就进入循环;条件为真就退出循环

1.2 until 语法

until expression   [ 1 -eq 1 ]  (( 1 >= 1 ))
	do
		command
		command
		...
	done

1.3 案例

使用while循环和until循环打印数字接龙,要求while循环输出1-5,until循环输出6-9.

#!/bin/bash
#Description: 数字接龙

i=1
while [ $i -le 5 ]
do
	echo $i
	let i++
	until [ $i -le 5 ]
	do
		    echo $i
	        let i++
	        [ $i -eq 10 ]&&break
	done
done

1.4 总结

  • until 循环条件:判断条件为假时进入循环
  • until 条件和 while 语句一样支持 shell 运算(如比较运算、逻辑运算等)
  • until 同样支持循环控制语句(break、continue、sleep)
  • until 支持嵌套语句(if、for、while、until)

二、shell 函数

        shell 脚本中的代码是按照执行的优先级的顺序从上往下抒写的,代码量越大,在脚本调试的时候就越难排错,当因执行需要调整代码执行顺序的时候就需要不断的复制粘贴,或者删除部分代码来完成,这和从写一个脚本花费的时候相比甚至需要更长的时间。

代码量大后遇到的问题:

  • 单个脚本代码量大 (300-500行)

  • 阅读修改耗时费力

  • 排错困难

  • 改变执行顺序困难

为了解决这些问题,我们可以把代码模块化,按需调用。

2.1 函数介绍

        shell 中允许将一组命令集合语句形成一段可用代码,这些代码块称为shell函数。给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能。

将完成一个功能的一段代码进行命名、封装。

函数的优点:

  1. 代码模块化,调用方便,节省内存
  2. 代码模块化,代码量少,排错简单
  3. 代码模块化,可以改变代码的执行顺序

2.2 函数定义 

# 语法一:

函数名 () {
    代码块
    return N
    }


# 语法二:
function 函数名 {
      代码块
      return N
      }
      
      

# 函数中 return 说明:
1.return 可以结束一个函数,类似于前面讲的循环控制语句break(结束当前循环,执行循环体后面的代码)
2.return 默认返回函数中最后一个命令的退出状态,也可以给定参数值,该参数值的范围是0-256之间。
3.如果没有 return 命令,函数将返回最后一个 Shell 的退出值。

函数定义案例演示

[root@shell ~]# vim fun-1.sh
#!/bin/bash

fun1 () {
        echo "first function"
        echo "haha"
        return 0
}

function fun2 {
        echo "second function"
        echo "xixi"
        return 110
}

2.3 函数调用

  • 当前命令行调用
[root@shell ~]# vim fun-2.sh
#!/bin/bash
hello(){
echo "hello sky $1"
hostname
}

menu(){
cat <<-EOF
1. mysql
2. web
3. app
4. exit
EOF
}

[root@shell ~]# source fun-2.sh 
[root@shell ~]# . fun-2.sh 
[root@shell ~]# hello 99
hello sky 99
shell
[root@shell ~]# menu
1. mysql
2. web
3. app
4. exit
  • 定义到用户的环境变量中
[root@shell ~]# vim ~/.bashrc 
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

hello(){
echo "hello sky $1"
hostname
}

menu(){
cat <<-EOF
1. mysql
2. web
3. app
4. exit
EOF
}

# 注意:当用户打开 bash 的时候会读取该文件
  • 脚本中调用
[root@shell ~]# vim fun-1.sh
#!/bin/bash

fun1 () {
        echo "first function"
        echo "haha"
        return 0
}

function fun2 {
        echo "second function"
        echo "xixi"
        return 110
}

# 调用函数(函数名)
fun2;fun1

[root@shell ~]# sh fun-1.sh 
second function
xixi
first function
haha

三、条件循环语句 case 

        在生产环境中,我们总会遇到一个问题需要根据不同的状况来执行不同的预案,那么我们要处理这样的问题就要首先根据可能出现的情况写出对应预案,根据出现的情况来加载不同的预案。

3.1 case 介绍

特点:根据给予的不同条件执行不同的代码块。

# 比如你去相亲:你会在脑子里出现以下的预案:
第一眼看到对方父亲,你应该说:伯父好
第一眼看到对方母亲,你应该说:伯母好
第一眼看到对方奶奶,你应该说:奶奶好
。。。。

# 而这个例子中触发就是你第一眼看到了对方的谁,预案则是叫什么称呼。

# 再来说一个计算机的相关例子---监控内存使用率:
内存使用率低于80%,          脚本输出: 绿色字体的Memory use xx%
内存使用率大于80%小于90%,   脚本输出: 黄色字体的Memory use xx%
内存使用大于90%,            脚本输出: 红色字体的Memory use xx%

3.2 case 语法

case $var in            # 定义变量; var 代表是变量名
pattern 1)              # 模式1;用 | 符号分割多个(选项)模式,相当于or
    command1            # 需要执行的语句
    ;;                  # 两个分号代表命令结束
pattern 2)
    command2
    ;;
pattern 3)
    command3
    ;;
		  *)            # default,不满足以上模式,默认执行*)下面的语句
    command4
    ;;
esac					# esac 表示 case 语句结束

3.4 案例

[root@shell ~]# vim case.sh
#!/bin/bash

read -p "性别: " gender

case $gender in
        B|b|男)
                echo "显示,您好"
                ;;
        G|g|女)
                echo "女士,您好"
                ;;
        *)
                echo "请输入性别"
esac

[root@shell ~]# sh case.sh
性别: 男
先生,您好
[root@shell ~]# sh case.sh
性别: b
先生,您好
[root@shell ~]# sh case.sh
性别: G
女士,您好

四、综合案例

案例需求
        写一个nginx启动管理脚本,可以实现 /etc/init.d/nginx start|stop|restart|status|reload
或者 systemctl start nginx。注意:提前编译安装 nginx

#!/bin/bash

#variables
nginx_install_doc=/usr/local/nginx
proc=nginx
nginxd=$nginx_install_doc/sbin/nginx
pid_file=$nginx_install_doc/logs/nginx.pid

# Source function library.
if [ -f /etc/init.d/functions ];then
   . /etc/init.d/functions
else
   echo "not found file /etc/init.d/functions"
   exit
fi

# 假如pid文件存在,那么统计一下 nginx 进程数量
if [ -f $pid_file ];then
   nginx_process_id=`cat $pid_file` 
   nginx_process_num=`ps aux |grep $nginx_process_id|grep -v "grep"|wc -l`
fi


#function
start () {
# 如果nginx 没有启动直接启动,否则报错 已经启动
if [ -f $pid_file ]&&[ $nginx_process_num -ge 1 ];then
   echo "nginx running..."
else
   # 如果pid文件存在,但是没有进程,说明上一次非法关闭了nginx,造成pid文件没有自动删除,所以启动nginx之前先删除旧的pid文件
   if [ -f $pid_file ] && [ $nginx_process_num -lt 1 ];then
        rm -f $pig_file
	# 可以使用两个函数,两种方法来执行命令,并返回执行结果
        #1)daemon
        #2)action   建议这个,简单易用
        
	#echo " nginx start `daemon $nginxd` "
        action "nginx start" $nginxd
  fi
  #echo " nginx start `daemon $nginxd` "
  action "nginx start" $nginxd
fi

}

stop () {
# 判断nginx启动的情况下才会执行关闭,如果没启动直接报错,或者提示用户服务没启动,这里我直接报错的原因是为了给大家演示失败的输出
if [ -f $pid_file ]&&[ $nginx_process_num -ge 1 ];then
     action "nginx stop" killall -s QUIT $proc
     rm -f $pid_file
else
     action "nginx stop" killall -s QUIT $proc 2>/dev/null
fi
}

restart () {
  stop
  sleep 1
  start
}

reload () {
# 重载的目的是让主进程重新加载配置文件,但是前提是服务必须开启
# 这里先判断服务是否开启,开启就执行加载,没有开启直接报加载错误
if [ -f $pid_file ]&&[ $nginx_process_num -ge 1 ];then
    action "nginx reload" killall -s HUP $proc
else
    action "nginx reload" killall -s HUP $proc 2>/dev/null
fi
}

status () {
if [ -f $pid_file ]&&[ $nginx_process_num -ge 1 ];then
 echo "nginx running..."
else
 echo "nginx stop"
fi 
}

#callable
case $1 in 
start) start;;
stop) stop;;
restart) restart;;
reload) reload;;
status) status;;
*) echo "USAGE: $0 start|stop|restart|reload|status";;
esac

上一篇文章:【Shell 脚本速成】10、Shell 流程控制 while 循环_Stars.Sky的博客-CSDN博客

参考文档:流程控制-case语句-组团学

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stars.Sky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值