• bash编程之case语句,函数


    bash脚本编程:之case语句
     
    条件测试:
    0: 成功
    1-255: 失败
     
    命令:
    [ expression ]
    [[ expression ]]
    test expression
     
    exPression:
    整数测试:
    -gt, -ge, -lt, -le, -eq, -ne
    字符串:
    >, < , >=, <=, ==, !=, =~, -z, -n
    文件:
    -e, -f, -d, -b, -c, -h, -S, -s, -a, -p, -r, -w, -x
     
    多分支的if语句:
    if boolean_expression1; then
    suite1
    elif boolean_expression2; then
    suite2
    ...
    elif boolean_expressionn; then
    suiten
    else
    else_suite
    fi
     
    练习:写一个脚本,接受如此格式
    script.sh {start|stop|restart|status}
    1、如是start,那么创建/var/lock/subsys/script.sh,显示启动成功;
    2、如果参数是stop,则删除/var/lock/subsys/script.sh,显示停止成功
    3、如果restart,则删除,再创建,显示成功;
    4、如果status, 如果文件存在,则显示running,否则,显示stopped
     
    #!/bin/bash
    #
    myService=`basename $0`
    lockFile="/var/lock/subsys/$myService"
     
    [ $# -lt 1 ] && echo "Usage: $myService {start|stop|restart|status}" && exit 4
     
    if [ "$1" == 'start' ]; then
            touch $lockFile
            echo "Starting $myService OK"
    elif [ "$1" == 'stop' ]; then
            rm -f $lockFile
            echo "Stopping $myService OK"
    elif [ "$1" == 'restart' ]; then
            rm -f $lockFile
            touch $lockFile
            echo "Restarting $myService OK"
    elif [ "$1" == 'status' ]; then
            if [ -f $lockFile ]; then
                    echo "$myService is running"
            else
                    echo "$myService is stopped"
            fi
    else
            echo "Usage: $myService {start|stop|restart|status}"
            exit 3
    fi
     
     
    case语句的语法格式:
    case expression in
    pattern1)
    suite1 
    ;;
    pattern2)
    suite2
    ;;
    ...
    patternn)
    suiten
    ;;
    *)
    other_suite
    ;;
    esac
     
    上述脚本的case实现:
     
    #!/bin/bash
    #
    myService=`basename $0`
    lockFile="/var/lock/subsys/$myService"
     
    [ $# -lt 1 ] && echo "Usage: $myService {start|stop|restart|status}" && exit 4
     
    case $1 in
    'start')
            touch $lockFile
            echo "Starting $myService OK"
            ;;
    'stop')
            rm -f $lockFile
            echo "Stopping $myService OK"
            ;;
    'restart')
            rm -f $lockFile
            touch $lockFile
            echo "Restarting $myService OK"
            ;;
    'status')
            if [ -f $lockFile ]; then
                    echo "$myService is running"
            else
                    echo "$myService is stopped"
            fi
            ;;
    *)
            echo "Usage: $myService {start|stop|restart|status}"
            exit 3
            ;;
    esac
     
     
    case中各pattern可以使用模式:
    a|b: a或者b
    *:匹配任意长度的任意字符;
    ?:匹配任意单个字符;
    [-]:范围匹配
     
    [a-z])
    [0-9])
     
    练习:写一个简单脚本
    1、提示用户输入一个任意字符;
    2、能判断此字符是数字、字母或特殊字符;
     
    #!/bin/bash
    #
    while true; do
    read -p "Enter a char: " char
     
    [[ "$char" == 'quit' ]] && break
     
    case $char in
    [a-z])
            echo "letter"
            ;;
    [0-9])
            echo "digit"
            ;;
    *)
            echo "special"
            ;;
    esac
    done
     
     
    练习:写一个脚本,能对/etc/目录进行打包备份,备份位置为/backup/etc-日期.后缀
    1、显示如下菜单给用户:
    xz) xz compress
    gzip) gzip compress
    bip2) bzip2 compress
    2、根据用户指定的压缩工具使用tar打包压缩;
    3、默认为xz;输入错误则需要用户重新输入;
     
    #!/bin/bash
    #
    [ -d /backup ] || mkdir /backup
     
    cat << EOF
    Plz choose a compress tool:
     
    xz) xz compress
    gzip) gzip compress
    bip2) bzip2 compress
    EOF
     
    while true; do
      read -p "Your option: " option
      option=${option:-xz}
     
      case $option in
      xz)
        compressTool='J'
        suffix='xz'
        break ;;
      gzip)
        compressTool='z'
        suffix='gz'
        break ;;
      bzip2)
        compressTool='j'
        suffix='bz2'
        break ;;
      *)
        echo "wrong option." ;;
      esac
    done
     
    tar ${compressTool}cf /backup/etc-`date +%F-%H-%M-%S`.tar.$suffix /etc/*
     
    练习:写一个脚本,完成如下功能
    说明:此脚本能够为指定网卡创建别名,指定地址;使用格式:mkethalias.sh -v|--verbose -i|--interface ethX
    1|-i选项用于指定网卡;
    2、如果网卡存在:在命令行,请用户指定一个别名;
    3、让用户指定IP和掩码;
    4、用户可以同时使用-v或--verbose选项:如果使用了,则在配置完成后,显示配置结果;否则,则不予显示;
     
    #!/bin/bash
    #
    debug=0
     
    while [ $# -ge 1 ]; do
      case $1 in
      -i|--interface)
        ethcard="$2"
        shift 2 ;;
      -v|--verbose)
        debug=1
        shift
        ;;
      *)
        echo "Wrong options or arguments."
        echo "Usage: `basename $0` [-v|--verbose] -i|--interface Interface"
        shift $#
        ;;
      esac
    done
     
    # echo "Interface: $ethcard , Verbose Flag: $debug "
     
    ! ifconfig $ethcard &> /dev/null && echo "No this interface..." && exit 3
     
    read -p "Enter an alias: " ethAlias
     
    read -p "Enter IP: " ipAddr
     
    read -p "Mask: " netMask
     
    ifconfig $ethAlias $ipAddr netmask $netMask
     
    [ $debug -eq 1 ] && ifconfig $ethAlias
     
     
    bash脚本编程之函数
    模块化编程的工具
     
    函数:function,功能组件
     
    可被调用:函数有函数名
    函数出现的地方,而自动被替换成函数定义的代码
     
    函数定义
     
     
    语法:
    FuncName() {
    函数体
    }
     
    function FuncName {
    函数体
    }
     
     
    函数有两种返回值:
    正常返回的数据:
    函数中的打印语句,如echo或print
    函数中命令的执行结果
    执行状态返回值:
    取决于函数中执行的最后一条语句
    自定义:return N
     
    函数可以接受参数:
    在函数体可以使用类似脚本调用位置参数一样的参数
    $1, $2, ...
    $#
    $*, $@
     
     
    #!/bin/bash
    #
    function ShowUserInfo {
      [ $# -lt 1 ] && return 6
      grep "^$1>" /etc/passwd | cut -d: -f3,7
    }
     
    function main {
    while true; do
      read -p "Plz enter a user name: " userName
     
      if [ "$userName" == 'quit' ]; then
            echo "Quit"
            exit 0
      fi
     
      if ! id $userName &> /dev/null; then
        echo "No such user, please again."
        continue
      fi
      ShowUserInfo $userName
    done
    }
     
    main
     
     
    练习:写一个脚本,完成如下功能
    1、显示如下菜单
    disk) show disk info
    mem) show memory info
    cpu) show cpuinfo
    2、显示用户选定的内容;
     
    #!/bin/bash
    #
    ShowMenu() {
    cat << EOF
    disk) show disk info
    mem) show memory info
    cpu) show cpuinfo
    EOF
    }
     
    main() {
    ShowMenu
    read -p "Plz choose an option: " option
    case $option in
    disk)
       df -h
       ;;
    mem)
       free -m
       ;;
    cpu)
      cat /proc/cpuinfo
      ;;
    *)
      echo "Wrong option"
    esac
    }
     
    main
     
    如果在函数中使用变量:变量作用域
    在函数中使用了在主程序中声明的变量,重新赋值会直接修改主程序中的变量;
    如果不期望函数与主程序中的变量冲突,函数中使用变量都用local修饰;即使用局部变量;
    在函数中使用了在主程序中没有声明的变量,在函数执行结束后即被撤消,无论是否使用local修饰符;
     
     
    如果想把脚本的全部位置参数,统统传递给脚本中某函数使用,怎么办?
    使用$*传递
     
     
     
     
     
    练习:写一个脚本,判定172.16.0.0网络内有哪些主机在线,在线的用绿色显示,不在线的用红色显示;要求,编程中使用函数;
     
    C类网:ping NetAdd.HostAdd
    B类网:ping NetAadd.NetAadd.HostAdd.HostAdd
     
    CnetPing() {
    for i in {1..254}; do
    ping -c 1 -w 1 $1.$i
    }
     
    # CnetPing 192.168.10
     
    BnetPing() {
    for j in {0.255}; do
    CnetPing $1.$j
    done
    }
     
    AnetPing() {
    for m in {0..255}; do
    BnetPing $1.$m
    done
    }
     
    netType=`echo $1 | cut -d'.' -f1`
     
    if [ $netType -gt 0 -a $netType -le 126 ]; then
    AnetPing $1
    elif [ $netType -ge 128 -a $netType -le 191 ]; then
      BnetPing $1
    elif [ $netType -ge 192 -a $netType -le 223 ]; then
    CnetPing $1
    else
    echo "Wrong"
    exit 3
    fi
     
     
     
    练习:写一个脚本,完成如下功能(使用函数):
    1、提示用户输入一个可执行命令;
    2、获取这个命令所依赖的所有库文件(使用ldd命令);
    3、复制命令至/mnt/sysroot/对应的目录中
    解释:假设,如果复制的是cat命令,其可执行程序的路径是/bin/cat,那么就要将/bin/cat复制到/mnt/sysroot/bin/目录中,如果复制的是useradd命令,而useradd的可执行文件路径为/usr/sbin/useradd,那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;
    4、复制各库文件至/mnt/sysroot/对应的目录中,其要求命令;
     
    #!/bin/bash
    #
    target=/mnt/sysroot
     
    clearCmd() {
      if which $cmd &> /dev/null; then
            cmdPath=`which --skip-alias $cmd`
      else
            echo "No such command"
            return 5
      fi
    }
     
    cmdCopy() {
            cmdDir=`dirname $1`
            [ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}
            [ -f ${target}${1} ] || cp $1 ${target}${cmdDir}
    }
     
    libCopy() {
            for lib in `ldd $1 | grep -o "/[^[:space:]]{1,}"`; do
                    libDir=`dirname $lib`
                    [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
                    [ -f ${target}${lib} ] || cp $lib ${target}${libDir}
            done
    }
     
    while true; do
      read -p "Enter a command: " cmd
      if [ "$cmd" == 'quit' ] ;then
            echo "quit"
            exit 0
      fi
      clearCmd $cmd
      [ $? -eq 5 ] && continue
     
      cmdCopy $cmdPath
      libCopy $cmdPath
    done
     
     
     
     
    练习:写一个脚本,完成如下功能(使用函数):
    1、脚本使用格式:
    mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefile
    2、如果文件事先不存在,则创建;且前几行内容如下所示:
    #!/bin/bash
    # Description: script description
    # Author: script author
    #
    3、如果事先存在,但不空,且第一行不是“#!/bin/bash”,则提示错误并退出;如果第一行是“#!/bin/bash”,则使用vim打开脚本;把光标直接定位至最后一行
    4、打开脚本后关闭时判断脚本是否有语法错误
    如果有,提示输入y继续编辑,输入n放弃并退出;
    如果没有,则给此文件以执行权限;
     
    arguParse() {
     
    }
     
     
     
     
     
     
     
  • 相关阅读:
    css3新单位vw、vh、vmin、vmax的使用介绍
    vue中的css作用域、vue中的scoped坑点
    vue组件中的样式属性:scoped,解决在父组件中无法修改子组件样式问题
    修改elementUI组件样式无效的问题研究
    Javascript里面的时间处理:将时间戳或时间对象转成字符串格式
    详解vue父组件传递props异步数据到子组件的问题
    vue父组件异步传递prop到子组件echarts画图问题踩坑总结
    父组件中调用子组件的方法和属性
    Echarts使用dataset数据集管理数据
    Echarts的legend改变图例图标为自定义图片
  • 原文地址:https://www.cnblogs.com/as007012/p/10009148.html
Copyright © 2020-2023  润新知