第9章 Shell函数
第9章 shell函数
1.函数的作用
函数的作用就是将需要重复运行的代码抽象出来然后封装成一个函数,后续需要使用的时候只需要引用函数就可以了,而不需要每次都写重复的内容。
2.函数的定义和调用
2.1 定义函数的两种方法
第一种方法
start(){
    command
}
第二种方法
function start(){
    command
}
2.2 函数调用的方法
start(){
    command
}
function stop(){
    command
}
start
stop
3.函数的传参
3.1 函数传参介绍
1.用户执行脚本传递的位置参数和函数传递的参数事两回事
2.函数执行的时候需要将位置参数传递给函数,这样才会将参数带入函数执行。
3.2 举例
#!/bin/bash
fun1() {
    case $2 in
        +)
            echo "$1 + $3 = $[ $1 + $3 ]"
            ;;
        -)
            echo "$1 + $3 = $[ $1 + $3 ]"
            ;;
        x)
            echo "$1 * $3 = $[ $1 * $3 ]"
            ;;
        /)
            echo "$1 + $3 = $[ $1 + $3 ]"
            ;;
        *)
            echo "bash $0 num1 {+|-|x|/} num2"
    esac
}
fun1 $1 $2 $3
4.函数的练习
4.1 编写nginx管理脚本
#!/bin/bash
UAGE(){
    echo "UAGE: bash $0 {start|stop|restart}"
}
start_nginx(){
    echo "nginx is start"
}
stop_nginx(){
    echo "nginx is stop"
}
case $1 in
    start)
      start_nginx
      ;;
    stop)
      stop_nginx
      ;;
    restart)
      stop_nginx
      start_nginx
      ;;
    *)
      UAGE
esac
4.2 编写多极菜单
#!/bin/bash
#1级菜单
menu1(){
echo "
-----------------------------
1.Install Nginx
2.Install PHP
3.Install MySQL
4.Quit
-----------------------------
"
}
#2级菜单
menu2(){
echo "
-----------------------------
1.Install Nginx1.15
2.Install Nginx1.16
3.Install Nginx1.17
4.返回上一层
-----------------------------
"
}
#打印1级菜单
menu1
while true
do
    #选择1级菜单
    read -p "选择对应的数字:" num1
    case $num1 in
       1)
           #打印2级菜单
           menu2
           while true
           do
               read -p "请选择您要安装的Nginx版本: " num2
               case $num2 in
                   1)
                       echo "Install Nginx1.15 is OK!"
                       ;;
                   2)
                       echo "Install Nginx1.16 is OK!"
                       ;;
                   3)
                       echo "Install Nginx1.17 is OK!"
                       ;;
                   4)
                       clear
                       menu1
                       break
                       ;;
                   *)
                       continue
               esac
           done
           ;;
       2)
           echo "Install PHP"
           ;;
       3)
           echo "Install Mysql"
           ;;
       4)
           exit
           ;;
       *)
           continue
    esac
done
4.3 深圳6期多级菜单脚本
原始脚本:
#!/bin/bash
while true
do
  echo -e "
  1.Install Nginx
  2.Install PHP
  3.Quit"
  read -p "please input num" num
  case $num in
  1)
    while true
    do
      echo -e "
      1.Install Nginx1.15
      2.Install Nginx1.16
      3.Install Nginx1.17
      4.return"
      read -p "please input num" num
      case $num in
      1)
        echo "Nginx1.15 is installed"
        break
      ;;
      2)
        echo "Nginx1.16 is installed"
        break
      ;;
      3)
        echo "Nginx1.17 is installed"
        break
      ;;
      4)
        break
          ;;
      *)
        echo "1-4"
      esac
    done
    ;;
  2)
    while true
    do
      echo -e "
      1.Install php-5.5
      2.Install php-5.7
      3.Install php-7.2
      4.return"
      read -p "please input num" num
      case $num in
      1)
        echo "php-5.5 is installed"
        break
      ;;
      2)
        echo "php-5.7 is installed"
        break
      ;;
      3)
        echo "php-7.2 is installed"
        break
      ;;
      4)
        break
    ;;
      *)
        echo "1-4"
      esac
    done
    ;;
  3)
    exit
    ;;
  *)
    echo "1-3"
  esac
done
函数脚本:
#!/bin/bash
menu(){
  echo -e "
  1.Install Nginx
  2.Install PHP
  3.mysql
  4.Quit"
}
nginx(){
    while true
        do
          echo -e "
          1.Install Nginx1.15
          2.Install Nginx1.16
          3.Install Nginx1.17
          4.return"
          read -p "please input num" num
          case $num in
          1)
            echo "Nginx1.15 is installed"
            break
          ;;
          2)
            echo "Nginx1.16 is installed"
            break
          ;;
          3)
            echo "Nginx1.17 is installed"
            break
          ;;
          4)
            break
              ;;
          *)
            echo "1-4"
          esac
        done
}
php(){
    while true
    do
      echo -e "
      1.Install php-5.5
      2.Install php-5.7
      3.Install php-7.2
      4.return"
      read -p "please input num" num
      case $num in
      1)
        echo "php-5.5 is installed"
        break
      ;;
      2)
        echo "php-5.7 is installed"
        break
      ;;
      3)
        echo "php-7.2 is installed"
        break
      ;;
      4)
        break
    ;;
      *)
        echo "1-4"
      esac
    done
}
mysql(){
    while true
    do
      echo -e "
      1.Install mysql-5.5
      2.Install mysql-5.7
      3.Install mysql-7.2
      4.return"
      read -p "please input num" num
      case $num in
      1)
        echo "mysql-5.5 is installed"
        break
      ;;
      2)
        echo "mysql-5.7 is installed"
        break
      ;;
      3)
        echo "mysql-7.2 is installed"
        break
      ;;
      4)
        break
    ;;
      *)
        echo "1-4"
      esac
    done
}
main(){
  while true
  do
    menu
    read -p "please input num" num
    case $num in
    1)
      nginx
      ;;
    2)
      php
      ;;
    3)
      mysql
      ;;
  4)
    exit
    ;;
    *)
      echo "1-3"
    esac
  done
}
main
4.3 编写跳板机脚本
#!/bin/bash
memu(){
echo"
    ===================
    |   1.lb-5        |
    |   2.lb-6        |
    |   3.web-7       |
    |   4.web-8       |
    |   5.exit        |
    ===================
"
trap "" HUP INT QUIT TSTP
while true
do
    memu
    read -p "请输入需要登陆的主机:" num
    case $num in
        1)
            ssh root@10.0.0.5
            ;;
        2)
            ssh root@10.0.0.6
            ;;
        3)
            ssh root@10.0.0.7
            ;;
        4)
            ssh root@10.0.0.8
            ;;
        5)
            exit
            ;;
        *)
            continue
    esac
done
综合练习题-将用户登陆注册功能修改为函数版本
需求:
把ATM机的用户登陆注册用函数,case,while,continue实现所有功能
脚本:
#!/bin/bash
name_list=bank.txt
log=log.txt
time=$(date)
menu(){
    echo "
    ===========
    1.登陆
    2.注册
    ===========
    "
    read -p "请选择需要的操作:" menu
}
check_login_name(){
    read -p "请输入用户名:" name
    grep -wo "${name}" ${name_list} >> /dev/null 2>&1
    if [ $? != 0 ];then
        echo "用户名不存在,请重新输入"
        check_login_name
    fi
}
check_login_pass(){
    read -p "请输入密码:" passwd_input
    passwd_user=$(awk -F":" "/^${name}\:/"'{print $2}' ${name_list})
    #passwd_user=$(sed -rn "s#${name}:(.*)#\1#g"p bank.txt)
    if [ ${passwd_input} == ${passwd_user} ];then
       echo "登陆成功!"
       echo "${time} ${name} 登陆成功!" >> ${log}
       exit
    else
       echo "密码错误,请重新输入"
       echo "${time} ${name} 登陆失败!" >> ${log}
       check_login_pass
    fi
}
check_regist_name(){
    read -p "请输入注册用户名:" name
    grep -wo "${name}" ${name_list} >> /dev/null 2>&1
    if [ $? = 0 ];then
       echo "用户名已存在,再选一个吧"
       check_regist_name
    fi
}
check_regist_pass(){
    read -p "请输入密码:" passwd1
    read -p "请再次输入密码:" passwd2
    if [ ${passwd1} == ${passwd2} ];then
       echo "${name}:${passwd1}" >> ${name_list}
       if [ $? == 0 ];then
          echo "注册成功,请登录"
          echo "${time} ${name} 注册成功!" >> ${log}
          main
       else
          echo "注册失败,请联系管理员"
          echo "${time} ${name} 注册失败!" >> ${log}
          exit
       fi
    else
       echo "两次输入的密码不一致,请重新输入"
       check_regist_pass
    fi
}
main(){
    while true
    do
        menu
        case ${menu} in
        1)
            check_login_name
            check_login_pass
            ;;
        2)
            check_regist_name
            check_regist_pass
            ;;
        *)
            echo "请选择1-2的数字"
            main
    esac
    done
}
main
综合练习练习题-用户登录注册函数改写
#!/bin/bash
#定义登录函数
check_login(){
  read -p "请输入用户名:" input_username
  check_name=$(grep "^$input_username:" name.txt |wc -l)
  if [ $check_name == 0 ];then
     echo "账户名不存在"
     exit
  fi
  read -p "请输入密码:" input_passwd
  pass=$(awk -F: "/^${input_username}:/"'{print $2}' name.txt)
  if [ $pass == $input_passwd ];then
     echo "登录成功!"
  else
     echo "账号密码错误!"
     exit
  fi
}
#定义注册函数
check_regist(){
  read -p "请输入用户名:" input_username
  if [ -z "$input_username" ];then
     echo "用户名不能为空,请重新输入"
     exit
  fi
  check_format=$(echo $input_username|egrep '[^0-9a-Z]+'|wc -l )
  if [ $check_format != 0 ];then
     echo "输入的用户名不能包含特殊字符"
     exit
  fi
  check_name=$(grep "^$input_username:" name.txt |wc -l)
  if [ $check_name != 0 ];then
     echo "账户名已存在,再选一个吧"
     exit
  fi
  input_username_lenth=$(echo ${input_username}|wc -L)
  if [ "$input_username_lenth" -lt 4 -o "$input_username_lenth" -gt 8 ];then
     echo "注册的账号名小于4为并且不能大于8位"
     exit
  fi
  read -p "请输入密码:" input_passwd
  check_format=$(echo $input_passwd|egrep '[^0-9a-Z]+'|wc -l )
  if [ $check_format != 0 ];then
     echo "输入的密码不能包含特殊字符"
     exit
  fi
  input_passwd_lenth=$(echo $input_passwd|wc -L)
  if [ "$input_passwd_lenth" -le 4 -o "$input_passwd_lenth" -gt 8 ];then
     echo "注册的密码不能小于4位并且不能大于8位"
     exit
  fi
  read -p "请再次输入密码:" input_passwd_check
  if [ "$input_passwd" != "$input_passwd_check" ];then
     echo "两次输入的密码不一致"
     exit
  fi
  echo "${input_username}:${input_passwd}" >> name.txt
  echo "注册成功!"
}
#定义菜单函数
menu(){
  echo -e '
  ===========
  1.注册
  2.登录
  ==========='
  read -p "请输入1-2:" num
}
#定义主函数
main(){
  menu
  case $num in
  1)
    check_login
    ;;
  2)
    check_regist
    ;;
  *)
    echo "请输入1-2"
  esac
}
#调用主函数
main
综合练习题-检查服务端口是否开启
exec < /scripts/ip-ports.txt
while read line
do
    count=0
    nc -w 10 -z $line >> /tmp/ip.log 2>&1
    if [ $? -ne 0 ];then
      for i in {1..3}
    do
            nc -w 10 -z $line >> /tmp/ip.log 2>&1
      if [ $? -ne 0 ];then
         count=$[ ${count}+1 ]
      else
         break
      fi
      if [ $count -eq 3 ];then
         sleep 3
             echo "生产服务器${line}连接不通"|/usr/local/bin/mailx -v -s "test" xxxx@qq.com >> /tmp/cron.log 2>&1
            fi
    done
  fi
done
更新: 2024-12-12 08:37:02