What is the purpose of the : (colon) GNU Bash builtin?

前端 未结 12 880
梦如初夏
梦如初夏 2020-11-22 14:01

What is the purpose of a command that does nothing, being little more than a comment leader, but is actually a shell builtin in and of itself?

It\'s slower than inse

12条回答
  •  眼角桃花
    2020-11-22 14:18

    Self-documenting functions

    You can also use : to embed documentation in a function.

    Assume you have a library script mylib.sh, providing a variety of functions. You could either source the library (. mylib.sh) and call the functions directly after that (lib_function1 arg1 arg2), or avoid cluttering your namespace and invoke the library with a function argument (mylib.sh lib_function1 arg1 arg2).

    Wouldn't it be nice if you could also type mylib.sh --help and get a list of available functions and their usage, without having to manually maintain the function list in the help text?

    #!/bin/bash
    
    # all "public" functions must start with this prefix
    LIB_PREFIX='lib_'
    
    # "public" library functions
    lib_function1() {
        : This function does something complicated with two arguments.
        :
        : Parameters:
        : '   arg1 - first argument ($1)'
        : '   arg2 - second argument'
        :
        : Result:
        : "   it's complicated"
    
        # actual function code starts here
    }
    
    lib_function2() {
        : Function documentation
    
        # function code here
    }
    
    # help function
    --help() {
        echo MyLib v0.0.1
        echo
        echo Usage: mylib.sh [function_name [args]]
        echo
        echo Available functions:
        declare -f | sed -n -e '/^'$LIB_PREFIX'/,/^}$/{/\(^'$LIB_PREFIX'\)\|\(^[ \t]*:\)/{
            s/^\('$LIB_PREFIX'.*\) ()/\n=== \1 ===/;s/^[ \t]*: \?['\''"]\?/    /;s/['\''"]\?;\?$//;p}}'
    }
    
    # main code
    if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
        # the script was executed instead of sourced
        # invoke requested function or display help
        if [ "$(type -t - "$1" 2>/dev/null)" = function ]; then
            "$@"
        else
            --help
        fi
    fi
    

    A few comments about the code:

    1. All "public" functions have the same prefix. Only these are meant to be invoked by the user, and to be listed in the help text.
    2. The self-documenting feature relies on the previous point, and uses declare -f to enumerate all available functions, then filters them through sed to only display functions with the appropriate prefix.
    3. It is a good idea to enclose the documentation in single quotes, to prevent undesired expansion and whitespace removal. You'll also need to be careful when using apostrophes/quotes in the text.
    4. You could write code to internalize the library prefix, i.e. the user only has to type mylib.sh function1 and it gets translated internally to lib_function1. This is an exercise left to the reader.
    5. The help function is named "--help". This is a convenient (i.e. lazy) approach that uses the library invoke mechanism to display the help itself, without having to code an extra check for $1. At the same time, it will clutter your namespace if you source the library. If you don't like that, you can either change the name to something like lib_help or actually check the args for --help in the main code and invoke the help function manually.

提交回复
热议问题