Day03-SHELL自动化编程-case与函数

9.3 case语句

9.3.1 概述

  • 条件分支语句,一般用于实现有多种选择的脚本。

  • 这个功能:if或多分支if实现,如果使用case语句会更加清晰直观.

  • 菜单。

  • start|stop|restart|status

# case语句格式
case "变量"  in
    start)   
     命令1
     ;;
    stop)
     命令2
     ;;
    restart)
     命令3
     ;;
     *)
     错误提示
esac

#if格式
if [ "$cmd" = "start" ]
then
   echo "start"
elif [ "$cmd" = "stop" ]
then  
   echo "stop"
elif [ "$cmd" = "restart" ]
then  
   echo "restart"  
else
   echo "错误"
fi

case语句 vs if多分支

case 一般用于固定的菜单选择情况,运行脚本用户输入1,2,3,4,start|stop|restart…

if 可以用于一些范围的比较。

eg9.3-运行脚本用户输入自己的选择,可以输入linux,dba,k8s,monitor,sre,devops,选择后输出你选择了xxx.方向

9.3.2 格式与实践

case格式

case "变量"  in  
   选择1)
         命令
         ;;
   选择2)
         命令
         ,,
       *)
         命令(保底的默认输出)
esac
  • 使用case进行修改后的脚本

案例18-某会所菜单展示程序

- oldwang会所的菜单功能(套餐)
  - 输出可选的套餐
   - 138套餐) 吃饱套餐
   - 443套餐) 吃饱喝足套餐
   - 888套餐) 吃喝拉撒套餐
   - 1688套餐) 你想干啥就干啥套餐
   - 8080套餐) 隐藏不便显示
   - 8443套餐) 隐藏老板娘套餐
   - 其他) 劝退套餐
   
[root@m01 devops-shell]# cat 18-case_menu.sh 
#!/bin/bash
##############################################################
# File Name:18-case_menu.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

#1.输出
cat <<EOF
- oldwang会所的菜单功能(套餐)
  - 输出可选的套餐
    输入1选择 138套餐) 吃饱套餐
    输入2选择 443套餐) 吃饱喝足套餐
    输入3选择 888套餐) 吃喝拉撒套餐
    输入4选择 1688套餐) 你想干啥就干啥套餐
    - 其他) 劝退套餐
EOF
#2.获取用户的输入
read -p "尊敬的VIP用户,请输入您的选择:" num

#3.根据用户的输入,输出对应的信息
case "$num" in
  1)
    echo "138套餐"
    ;;

  2)
    echo "443套餐"
    ;;

  3)
    echo "888套餐"
    ;;

  4)
    echo "1688套餐"
    ;;

  5)
    echo "尊敬的SSSSSVIP用户,恭喜激活8080不便显示套餐"
    ;;

  6)
    echo "尊敬的SSSSSVIP用户,恭喜激活8443老板娘套餐"
    ;;
  *)
    echo "选择错误,请充值"
esac

[root@m01 devops-shell]# sh 18-case_menu.sh 
- oldwang会所的菜单功能(套餐)
  - 输出可选的套餐
    输入1选择 138套餐) 吃饱套餐
    输入2选择 443套餐) 吃饱喝足套餐
    输入3选择 888套餐) 吃喝拉撒套餐
    输入4选择 1688套餐) 你想干啥就干啥套餐
    - 其他) 劝退套餐
尊敬的VIP用户,请输入您的选择:4
1688套餐
[root@m01 devops-shell]# sh 18-case_menu.sh 
- oldwang会所的菜单功能(套餐)
  - 输出可选的套餐
    输入1选择 138套餐) 吃饱套餐
    输入2选择 443套餐) 吃饱喝足套餐
    输入3选择 888套餐) 吃喝拉撒套餐
    输入4选择 1688套餐) 你想干啥就干啥套餐
    - 其他) 劝退套餐
尊敬的VIP用户,请输入您的选择:6
尊敬的SSSSSVIP用户,恭喜激活8443老板娘套餐

9.3.3 小结

  • case语句功能,可以通过if+elif+else形式进行替换。

  • 应用场景:同一个变量有多个结果的时候(多种选择的时候),选用case语句,较为清晰。

  • case清晰,适用于菜单输入与选择,服务启动,关闭,重启脚本。

  • 进阶格式:

    • 分支中可以使用|表示或者
    • *号表示所有

案例19-判断用户输入的是yes还是no

用户输入yes,y,Y,Yes 都表示yes
用户输入no,n,N,No   都表示no

[root@m01 devops-shell]# cat 19-case_yesno.sh 
#!/bin/bash
##############################################################
# File Name:19-case_yesno.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

read -p "input yes or no:" xuan
#choice
case "$xuan" in
   yes|y|Y|Yes) echo "您输入的是yes" ;;
   no|n|N|No) echo "您输入的是yno" ;;
esac
[root@m01 devops-shell]# sh 19-case_yesno.sh 
input yes or no:y
您输入的是yes

9.5 判断小结

  • 条件表达式格式: [] [[]] test , (())

  • 判断文件,字符串,大小,逻辑,正则

  • if判断:

    • 单分支。
    • 双分支。
    • 多分支。
  • case语句: 用户输入与不同的选择,相对固定的选择.

  • 完成案例:比大小,输出指定用户信息,服务管理脚本(优化)。

10. SHELL编程-函数

  • 从入门到大神必会技术点

10.1 概述

  • 把一堆代码,起个名字。

  • 对脚本中重复使用到的代码,设置函数,精简脚本的内容。

  • 让脚本更加的规范。

  • 应用场景:

    • 在书写脚本的时候,尽量使用函数,规范脚本。
    • 让脚本的开发,更加模块化。
    • 方便后期调试,调试的时候只需要注释函数即可。
echo "welcome to oldboy linux lidao996 class"
echo "你的目标:拿下15k offer"
echo "你的目标:拿下100+ shell脚本"
echo "你的目标:书写总共超过5000行脚本"

10.2 格式及实战应用

  • 函数格式:
#定义方式01 最完整
function lidao_show() {
命令
命令
内容
 return n  #函数的返回值
}

#定义方式02   精简写法 一般使用这一种.
lidao_show() {
命令
命令
内容
 return n  #函数的返回值
}

#定义方式03    
function lidao_show {
命令
命令
内容
 return n  #函数的返回值
}

案例20-函数基本格式与使用

[root@m01 devops-shell]# cat 20-test_func.sh 
#!/bin/bash
##############################################################
# File Name:20-test_func.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

show() {
echo "welcome to oldboy linux lidao996 class"
echo "你的目标:拿下15k offer"
echo "你的目标:拿下100+ shell脚本"
echo "你的目标:书写总共超过5000行脚本"
}

show

[root@m01 devops-shell]# sh -x 20-test_func.sh 
+ show
+ echo 'welcome to oldboy linux lidao996 class'
welcome to oldboy linux lidao996 class
+ echo '你的目标:拿下15k offer'
你的目标:拿下15k offer
+ echo '你的目标:拿下100+ shell脚本'
你的目标:拿下100+ shell脚本
+ echo 你的目标:书写总共超过5000行脚本
你的目标:书写总共超过5000行脚本

10.3 函数传参

  • 函数传参与脚本传参类似。使用$xxxxx形式进行
位置参数shell脚本中函数中
$n脚本的第n个参数函数的第n个参数
$0脚本的名字脚本的名字
$#脚本的参数的格式函数参数个数
@ / @/ @/*脚本所有的参数函数所有的参数

案例21-函数传参案例

sh 21.show_func.sh lidao996
把脚本的$1参数传递到show函数中.

show函数的参数个数:1
show函数的所有参数:lidao996
lidao996.com
lidao996.cn
lidao996.org
lidao996.企业
lidao996.icu
lidao996.我爱你

[root@m01 devops-shell]# cat 21-func_params.sh 
#!/bin/bash
##############################################################
# File Name:21-func_params.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

show() {
cat <<EOF
   show函数的参数个数:$#
   show函数的所有参数:$*
   $1.com
   $1.cn
   $1.org
   $1.企业
   $1.icu
   $1.我爱你
EOF
}

show lidao996 lidao--7
#show $1       #这是脚本的第1个参数
[root@m01 devops-shell]# sh 21-func_params.sh 
   show函数的参数个数:2
   show函数的所有参数:lidao996 lidao--7
   lidao996.com
   lidao996.cn
   lidao996.org
   lidao996.企业
   lidao996.icu
   lidao996.我爱你                                                   

[root@m01 devops-shell]# cat 21-func_params.sh 
#!/bin/bash
##############################################################
# File Name:21-func_params.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

show() {
cat <<EOF
   show函数的参数个数:$#
   show函数的所有参数:$*
   $1.com
   $1.cn
   $1.org
   $1.企业
   $1.icu
   $1.我爱你
EOF
}

#show lidao996 lidao--7
show $1       #这是脚本的第1个参数
[root@m01 devops-shell]# sh 21-func_params.sh lidao007
   show函数的参数个数:1
   show函数的所有参数:lidao007
   lidao007.com
   lidao007.cn
   lidao007.org
   lidao007.企业
   lidao007.icu
   lidao007.我爱你

在这里插入图片描述

10.4 案例22-sersync服务管理脚本

  • 目标:书写服务管理脚本

    • /server/scripts/xxxx {start|stop|restart|status}
  • 服务是编译安装,二进制包。

  • 流程:

    • 找命令:
      • 找出开启服务的命令.
      • 找出关闭服务的命令.
      • 找出重启服务的命令.
      • 找出查看服务状态的命令.
  • 写脚本:case语句

  • 调试

1)需求分析

  • sersync

  • 书写data_sync.sh脚本,用于管理sersync服务.

  • sh data_sync.sh start|stop|restart|status

  • 分析

    • 如果用户输入的是start,则运行sersync启动的命令。
    • 如果用户输入的是stop,则运行关闭sersync的命令。
    • 如果用户输入的是status,则显示sersync是否运行中,pid。
    • 如果用户输入的是restart,则运行stop的命令,然后运行start的命令。
    • 如果用户输入的是其他的内容,则提示输入错误,提示格式。
      在这里插入图片描述

先书写脚本骨架

[root@m01 devops-shell]# cat 22-sersync.sh 
#!/bin/bash
##############################################################
# File Name:22-sersync.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

#函数使用建议,根据步骤创建函数

#1.vars
choice=1

#2.定义函数
#2.0加入检查类函数
#命令是否存在
#配置文件是否存在

#2.1 启动服务的函数
sersync_start() {
  sersync2 -rdo /app/tools/sersync/confxml.xml
}

#2.2 关闭服务的函数
sersync_stop() {
   sersync_pid=`ps -ef |grep sersync2|grep -v grep |awk '{print $2}'`
   kill $sersync_pid
}

#2.3 重启服务的函数
sersync_restart() {
   sersync_pid=`ps -ef |grep sersync2|grep -v grep |awk '{print $2}'`
   kill $sersync_pid
   sersync2 -rdo /app/tools/sersync/confxml.xml
}

#2.4 服务状态的函数
sersync_status() {
  #判断服务是否运行
  ##如果运行则显示 sersync is running(pid)
  ##如果没有运行显示 sersync is gualed
  #检查服务的进程数量
  sersync_count=`ps -ef |grep sersync2 |grep -v grep |wc -l`
  if [ $sersync_count -eq 0 ]
  then
      echo "sersync is gualed"  
  else
      sersync_pid=`ps -ef |grep sersync2|grep -v grep |awk '{print $2}'`
      echo "sersync is running ${sersync_pid}"
  fi
}

#2.5 用户输入异常提示
error_msg() {
   echo "Usage: $0 {start|stop|restart|status}"
}

#3.case语句引用函数 脚本主要部分
case "$choice" in
    start)   sersync_start ;;
    stop)    sersync_stop ;;
    restart) sersync_restart ;;
    status)  sersync_status ;;
    *)       error_msg ;;
esac

10.5 小结

  • 应用:书写脚本尽量使用变量,函数规范脚本。
  • 使用函数流程:分析问题,列出步骤,步骤 --> 命令 --> 函数。
  • 函数传参:$* $@ $n $0

案例题一

脚本执行
sh /server/scripts/exam01-backup dir.sh /etc/
要求:(共计4项要求)
1.备份到/backup/_etc_2023-01-01.tar.gz #目录中所有的斜线替换为_
2.要检查用户指定的目录是否存在,不存在则提示目录不存在或者不是目录,然后退出脚本。
3.如果用户指定备份根目录,则提示开玩笑,你要备份根?然后退出脚本。
4.备份的目录就是固定为/backup/

脚本流程:
1.命令行传参dir=$1
2.检查目录是否存在?-d
3.检查目录是否是根目录?如果是提示…
4.进行处理与备份

[root@m01 devops-shell]# cat exam01.bakup_dir.sh
#!/bin/bash
##############################################################
# File Name:exam01.backup_dir.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

#函数使用建议,根据步骤创建函数

#1.vars
dir=$1

#2.检查是否为目录
backup_dir_check() {
    [ -d "$dir" ] || {
      echo "请输入目录"
      exit 1
    }
}
#3.检查是否为根目录
backup_root_check() {
    [ "$dir" = "/" ] && {
      echo "开玩笑,你要备份根?"
      exit 2
    }
}
#4.进行备份处理
backup_dir() {
    dir_new=`echo $dir /sed 's#/#_#g'`
    [ ! -d /backup/ ] && mkdir -p /backup/
    tar zcf /backup/${die_new}-`date +%F`.tar.gz $dir &>/dev/null
}
#5.调用函数
main() {
    backup_dir_check
    backup_root_check
    backup_dir
}
main

案例题二

sh /sever/scripts/exam2_user_check.sh
要求:(共计:2+6+7=15项要求)
1.执行脚本后进行交互式提示。
2.输入1进行系统用户检查。输入2进行指定用户信息检查。

3.如果用户输入1则进行系统用户检查,要求输出如下内容。
1)系统一共有多少用户(所有用户,普通用户和虚拟用户都算)
2)可以登录用户有多少?
3)可以登录系统用户的用户名。
4)root用户最后一次登录时间和ip。
5)输出/home/目录占用磁盘空间。
6)输出/root/用户占用磁盘空空间。

4.如果用户输入2则检查指定用户信息。
1)检查用户是否存在,不存在则提示并退出脚本。
2)如果用户存在输出下面信息。
3)用户名
4)用户uid
5)用户gid
6)用户家目录
7)用户是否可以登录(如果是/bin/bash则可以登录)

步骤:
1.执行脚本,read提示用户进行输入num
2.如果用户输入1
1)系统一共有多少用户(所有用户,普通用户和虚拟用户都算)
2)可以登录用户有多少?
3)可以登录系统用户的用户名。
4)root用户最后一次登录时间和ip。
5)输出/home/目录占用磁盘空间。
6)输出/root/用户占用磁盘空空间。

3.如果用户输入2
1)检查用户是否存在,不存在则提示并退出脚本。
2)如果用户存在输出下面信息。
3)用户名
4)用户uid
5)用户gid
6)用户家目录
7)用户是否可以登录(如果是/bin/bash则可以登录)

[root@m01 devops-shell]# cat exam02.check_user.sh 
#!/bin/bash
##############################################################
# File Name:exam02.check_user.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc:
##############################################################

#1.vars
user_check_welcome() {
  cat <<EOF
     输入数字选择对应的功能:
     1. 对系统所有用户进行巡检
     2. 对某个用户进行巡检
EOF
  read num
}
#2.如果选择1 系统用户巡检
user_all_check() {
  #系统一共有多少用户
  user_all_count=`wc -l /etc/passwd | awk '{print $1}'`
  #可以登录用户有多少
  user_all_login=`grep -c '/bin/bash' /etc/passwd`
  #可以登录系统用户的用户名
  user_all_login_username=`grep '/bin/bash' /etc/passwd | awk -F: '{print $1}' |xargs`
  #root用户最后一次登录时间和ip
  user_root_lastlog=`lastlog -u root|tail -1`
  #输出/home/目录占用磁盘空间
  home_dir_size=`du -sh /home/ |awk '{print $1}'`
  #输出/root/用户占用磁盘空空间
  root_dir_size=`du -sh /root/ |awk '{print $1}'`
  
  cat<<EOF
  系统一共有多少用户:$user_all_count
  可以登录用户有多少:$user_all_login
  可以登录系统用户的用户名:$user_all_login_username
  root用户最后一次登录时间和ip:$user_root_lastlog
  输出/home/目录占用磁盘空间:$home_dir_size
  输出/root/用户占用磁盘空空间:$root_dir_size
EOF
}
#3.如果选择2 用户巡检
check_user_exist() {
  read -p "请指定用户:" user
  [ -z "$user" ] && user=root
  id $user &>/dev/null || {
    echo "$user 用户不存在"
    exit 1
  }
}

user_one_check() {
  check_user_exist
  user_shell=`grep "^${user}:" /etc/passwd | awk -F: '{print $NF}'`
  if [ "$user_shell" = "/bin/bash" ];then
    user_login="可以登录"
  else
    user_login="不可以登录"
  fi
  
  user_uid=`grep "^${user}:" /etc/passwd | awk -F: '{print $3}'`
  user_gid=`grep "^${user}:" /etc/passwd | awk -F: '{print $4}'`
  user_homedir=`grep "^${user}:" /etc/passwd | awk -F: '{print $(NF-1)}'`
  user_lastlog=`lastlog | grep -w "${user}"`

  echo "##############################################"
  echo "####用户名:${user}"
  echo "####用户uid:${user_uid}"
  echo "####用户gid:${user_gid}"
  echo "####用户是否可以登录:${user_login}"
  echo "####用户家目录:${user_homedir}"
  echo "####用户最后一次登录情况:${user_lastlog}"
  echo "##############################################"
}
#4.all in one
all() {
  user_check_welcome
  case "$num" in
    1) user_all_check ;;
    2) user_one_check ;;
    *) echo "请按照要求输入"
esac
}
all
  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值