Navigation überspringen
Seiteninhalt:
Shell script with getopts example
#!/bin/bash
###############################################################################
PROGRAM_NAME="bash script template"
SCRIPT_VERSION="0.1a"
###############################################################################
# copy(l)eft 2019 http://harald.ist.org/
###############################################################################
DEBUG=false
###############################################################################
# INIT
###############################################################################
trap cleanup SIGINT                         # Handles aborting with ^C
# Colored output
TEXT_UNDERLINE="$(tput smul)"
TEXT_endUNDERLINE="$(tput rmul)"
TEXT_STANDOUT="$(tput smso)"                # Inverse colors on my terminal
TEXT_endSTANDOUT="$(tput rmso)"
TEXT_DIM="$(tput dim)"
TEXT_BOLD="$(tput bold)"
TEXT_BLINK="$(tput blink)"
TEXT_REVERSE="$(tput rev)"
TEXT_RED="$(tput setaf 1)"
TEXT_GREEN="$(tput setaf 2)"
TEXT_YELLOW="$(tput setaf 3)"
TEXT_BLUE="$(tput setaf 4)"
TEXT_MAGENTA="$(tput setaf 5)"
TEXT_CYAN="$(tput setaf 6)"
TEXT_WHITE="$(tput setaf 7)"
TEXT_RESET="$(tput sgr0)"
ESC=$(echo -e "\e")
SCRIPT_NAME=$(basename $0)
#
# Execution continues at bottom of script near "SCRIPT ENTRY POINT"
#
###############################################################################
# HELPERS
###############################################################################
debug() {
        ($DEBUG) && echo -e "Debug: $1"
}
error() {
        exit_code=$1
        shift                           # Remove $1 from argument list
        echo "Error: $@"                # Echo the rest to ERROUT
        exit $exit_code
}
function do_as_su()
{
        # Command needs to be executed as root
        # do_as_su <command line>
        if [ "$(whoami)" = "root" ] ; then
                $@
        else
                DECL=$(declare -f $1)
                cmd=$1
                shift
                params=$@
                sudo bash -c "$DECL; $cmd $params"
        fi
}
###############################################################################
# CLEAN UP
###############################################################################
cleanup() {
        # Clean up, when ^C was pressed
        echo "Aborting, cleaning up."
}
###############################################################################
# DISPLAY HELP
###############################################################################
display_help() {
        echo "${TEXT_BOLD}${PROGRAM_NAME} ${TEXT_RESET}v${SCRIPT_VERSION}"
        echo "Usage: $SCRIPT_NAME [-h] [-s|-v] [-f file] [-V var=val] [item(s)]"
        ($VERBOSE_HELP) && cat << EOF
Switches:
        -f file,                Name of file
        -F=file, --file=file
        -h, --help              Display verbose help and terminate execution
        -s, --silent            Be silent
        -v, --verbose           Be extra verbose about what is going on
        -V name=value,          Change a preset value, names are case sensitive
        --var name=value
Objects (Items)
        obj1, obj2
        item1, item2, item3
Examples:
        $SCRIPT_NAME -f test.out
        $SCRIPT_NAME --file=test.out
        $SCRIPT_NAME -v FILE_NAME=test.out
        $SCRIPT_NAME item1
EOF
}
###############################################################################
# MAIN FUNCTION
###############################################################################
# getopts can't handle "--long-opts", so all long option names have to be
# converted into the short version, before we can process them. Since we can't
# manipulate the $@ variable, the substitution is done outside, see
# SCRIPT ENTRY POINT.
known_items()
{        # Finds $1 in list, items may contain white space
        grep -F -q -x "$1" << EOF 2> /dev/null
item1
item2
item3
EOF
        ### [ $? -ne 0 ] && error 1 \"$1\" not in items.
}
known_objects()
{        # Finds $1 in list, no white space allowed
        echo "$KNOWN_OBJECTS" | grep -F -q -w "$1"
}
main() {
        # Set initial state for command line switches
        VERBOSITY=1                     # Default verbosity
        VERBOSE_HELP=false              # Full help when --help is given
        FILE_NAME=default.out           # Test parameter for -f and -v
        KNOWN_OBJECTS="obj1 obj2"       # Test objects
        while getopts $GETOPTS_LIST param ; do
                debug "OPTARG='$OPTARG'"
                debug "OPTIND=$OPTIND"
                debug "param=$param"
                case $param in
                f)        FILE_NAME="$OPTARG" ;;
                F)        eval "FILE_NAME$OPTARG" ;;
                h)        VERBOSE_HELP=true ; display_help ; exit 0 ;;
                s)        VERBOSITY=0 ;;
                v)        VERBOSITY=2 ;;
                V)        eval $OPTARG 2>/dev/null ;;
                \?)        error 2 "Unknown option \"-$OPTARG\"." ;;
                :)        error 3 "Option \"-$OPTARG\" needs an argument." ;;
                *)        error -1 "You should never read this." ;;
                esac
        done
        [ $OPTIND -eq 1 ] && display_help ; exit 0   # Show short help
        # Remaining arguments are objects/items
        shift $(( OPTIND - 1 ))   # Remove switches from stack
        for argument in $@ ; do
                known_items   "$argument" && echo "Found item '$argument'"
                known_objects "$argument" && echo "Found object '$argument'"
        done
        [ $VERBOSITY -ge 1 ] && echo "FILE_NAME='$FILE_NAME'"
        [ $VERBOSITY -ge 2 ] && echo "Done."
        exit 0
}
###############################################################################
# SCRIPT ENTRY POINT (Execution starts here) Before we can process the command
# line arguments with getopts, we have to replace --long-opts with their short
# counterparts, and create a modified parameter list to pass on to  main()
###############################################################################
# List of long switches and their short counterparts: The first character is
# the short switch for the long one. Like -V and --list-vars"
GETOPTS_LIST=':f:F:hsuvV:'
SWITCH_ALIASES="Ffile hhelp ssilent vverbose Vvar"
long_to_short() {
        argument=$1
        for alias in $SWITCH_ALIASES ; do
                short=-${alias:0:1}
                long=${alias/ *}
                long=--${long:1}
                argument=${argument//$long/$short}
        done
        ARGUMENTS="$ARGUMENTS $argument"
}
ARGUMENTS="" ; for A in "$@" ; do long_to_short $A ; done ; main $ARGUMENTS
#EOF
	
	Content Management:
	μCMS α1.6