zoukankan      html  css  js  c++  java
  • Bash编程(5) Shell方法

    shell的方法在相同的进程内执行,与调用它的脚本一致。对于方法来说,脚本中的所有变量均可见,且不需要执行export。方法中可以创建局部变量,且不影响正在调用的脚本。

     1. 定义语法

    (1) KornShell中的定义格式为:function name <复合命令>

    (2) Bourne shell中的定义格式为: name() <复合命令>

    (3) bash允许的格式:function name() <复合命令>

    一个参数设置方法的返回码,若没有参数,方法的退出码默认为执行的最后一个命令执行结果。

    local为shell中的内置命令,可用于限制方法(以及其子方法)中变量的作用域,但父进程中的变量不会改变。当参数扩展时,使用IFS而非空格将会导致分词。Bash4.0中, local和declare存在一个选项 -A,用于声明关联数组。

    例:判断ip是否有效

    ## 检测Ip是否有效
    isvalidip(){
        case $1 in
        "" | *[!0-9.]* | *[!0-9]) return 1 ;;  ## 空值、非法字符、不以数字结尾,均不符合Ip
        esac
    
        ## 将IFS设置为点号,但仅限于该方法中
        local IFS=.
    
        ## 将Ip设为位置参数,分词之后,每个元素变成了参数
        set -- $1
        
        ## 必须有4个参数,每个元素必须小于256,参数为空时,默认为666
        [ $# -eq 4 ] &&
        [ ${1:-666}  -le 255 ] && 
        [ ${2:-666}  -le 255 ] &&
        [ ${3:-666}  -le 255 ] &&
        [ ${4:-666}  -le 255 ] &&
    }

     使用source命令使脚本中的方法在当前shell中有效:. isvalidip

    $ for ip in 127.0.0.1 168.260.0.234 123.100.34.32 204.255.122.150
    > do
    >     if isvalidip "$ip"
    >     then
    >         printf "%15s: valid
    " "$ip"
    >     else
    >         printf "%15s: invalid
    " "$ip"
    >     fi
    > done
    
    127.0.0.1: valid
    168.260.0.234: invalid
    123.100.34.32: valid
    204.255.122.150: valid

     2. 复合命令

    复合命令可以是一组封装在( ... )或{ ... }中的命令,封装在(( ... ))或[[ ... ]]中的表达式,或者shell的关键词块(case, for, while, select, until)。

    例:检查有效整型

    valint()  #@ USAGE: valint INTEGER
        case ${1#-} in  ## 接收负数
            *[!0-9]*) echo false;; ## 包含非数字字符
            *) echo true;;
        esac

        若方法的主体由引号包含,则它将在子shell中执行,并且执行期间产生的变化在退出时不再有效。

    $ funky() (nam=nobody; echo "name = $name")
    name=Rempelstilskin
    $ funky
    name = nobody
    $ echo "name = $name"
    name = Rempelstilskin

    3. 获取结果

    1) 设置不同的退出码

    例:检验整型是否在特定范围

    rangecheck()  #@ USAGE: rangecheck int [low  [high]]
        if [ "$1" -lt ${2:-10} ];then ## 数值太小返回1,若无第二个参数,默认为10
            return 1
        elif [ "$1" -gt ${3:-20} ];then ## 数据太大返回0,若无第三个参数,默认为20
            return 2
        else
            return 0
        fi

    2) 打印结果

    例:打印环境变量信息

    uinfo()  #@ USAGE: uinfo [file]
    {
        printf "%12s: %s
    " 
            USER "${USER:-No value assigned }" 
            PWD "${PWD:-No value assigned}" 
            COLUMNS "${COLUMNS:-No value assigned}" 
            LINES "${LINES:-No value assigned}" 
            SHELL "${SHELL:-No value assigned}" 
            HOME "${HOME:-No value assigned}" 
            TERM "${TERM:-No value assigned}"
    } > ${1:-/dev/fd/1}

     3) 结果保存在多个变量中

    例:3个整数排序

    _max3()  #@ 对3个整数排序,并且分别保存在$_MAX3,$_MID3及$_MIN3中
    {
        [ $# -ne 3 ] && return 5
        [ $1 -gt $2 ] && { set -- $2 $1 $3; }
        [ $2 -gt $3 ] && { set -- $1 $3 $2; }
        [ $1 -gt $2 ] && { set -- $2 $1 $3; }
        _MAX3=$3
        _MID3=$2
        _MIN3=$1
        printf "%d	%d	%d
    " $_MAX3 $_MID3 $_MIN3
    }
    
    max3() #@ 对3个整数排序并保存在array中
    {
    declare -n _max3=${4:-_MAX3}  #@ 当命令行未提供变量名,则默认使用_MAX3
    (( $# < 3 )) && return 4
    (( $1 > $2 )) && set -- "$2" "$1" "$3"
    (( $2 > $3 )) && set -- "$1" "$3" "$2"
    (( $1 > $2 )) && set -- "$2" "$1" "$3"
    _max3=( "$3" "$2" "$1" )
    }

     4. 示例脚本 

    ##
    ##  设置默认
    ##
    prompt=" ==> "
    template='<!DOCTYPY html>
    <html lang="en">
      <head>
        <meta charset=utf-8>
        <title>%s</title>
        <link href=%s" rel="stylesheet">
      </head>
      <body>
        <h1>%s</h1>
        <div id=main></div>
      </body>
    </html>
    '
    
    ## 
    ##  定义shell函数
    ##
    die(){  #@ 描述:打印错误信息,并且以ERROR退出
        error=$1
        shift
        [ -n "$*" ] && printf "%s
    " "$*" >&2
        exit "$error"
    }
    
    usage(){  #@ 打印脚本使用用途
        printf "USAGE: %s HTMLFILE
    " "$progname"
    }
    
    version(){
        printf "%s version %s: " "$progname" "${version:-1}"
    }
    
    bashversion=${BASH_VERSION%%.*}
    if [ ${bashversion:-0} -ge 4 ];then
        ## bash4.x 的read有-i选项,用于提供一个初始值(如下的$3)
        readline(){
            read -ep "${2:-"$prompt"}" -i "$3" "$1"
        }
    elif [ ${BASHVERSION:-0} -ge 2 ];then
        readline(){
            history -s "$3"
            printf "Press up arror to edit default value: '%s'
    " "${2:-none}"
            read -ep "${2:-"$prompt"}" "$1"
        }
    else
        readline(){
            printf "Press enter for default of '%s'
    " "$3"
            printf "%s " "${2:-"$prompt"}"
            read
            eval "$1=${REPLY:-"$3"}"
        }
    fi
    
    if [ $# -ne 1 ];then
        usage
        exit 1
    fi
    
    filename=$1
    
    readline title "Page title: "
    readline h1 "Main headline: " "$title"
    readline css "Style sheet file: " "${filename%.*}.css"
    
    printf "$template" "$title" "$css" "$h1" > "$filename" 
    执行示例结果: 
    $ bash test.sh test
    Page title: hello
    Main headline: hello
    Style sheet file: test.css
    $ cat test
    <!DOCTYPY html>
    <html lang="en">
      <head>
        <meta charset=utf-8>
        <title>hello</title>
        <link href=test.css" rel="stylesheet">
      </head>
      <body>
        <h1>hello</h1>
        <div id=main></div>
      </body>
    </html>

     

  • 相关阅读:
    AX88772B 驱动移植
    USB 驱动之 usb_register 函数解析
    am335x USB 驱动框架记录
    warning: assignment from incompatible pointer type [enabled by default]
    WARNING: arch/arm/mach-omap2/built-in.o(.text+0x12cdc): Section mismatch in reference from the function mmc0_init() to the (unknown reference) .init.data:(unknown)
    Oracle11g客户端client的下载与安装
    sqlserver2008R2 评估期已过
    SQL2008 提示评估期已过的解决方法
    Windows下Oracle定时备份(全量备份)
    某客的《微信小程序》从基础到实战视频教程
  • 原文地址:https://www.cnblogs.com/mengrennwpu/p/10269576.html
Copyright © 2011-2022 走看看