shell 脚本参数非位置

use*_*986 3 shell

有没有办法将非位置参数提供给 shell 脚本?意思是明确指定某种标志?

. myscript.sh value1 value2
. myscript.sh -val1=value1 -val2=value2
Run Code Online (Sandbox Code Playgroud)

Ric*_*sen 5

您可以使用getopts,但我不喜欢它,因为它使用起来很复杂,而且它不支持长选项名称(无论如何都不是 POSIX 版本)。

我建议不要使用环境变量。名称冲突的风险太大了。例如,如果您的脚本根据ARCH环境变量的值做出不同的反应,并且它执行另一个脚本(您不知道)也对ARCH环境变量做出反应,那么您可能有一个难以发现的错误,它只会出现偶尔。

这是我使用的模式:

#!/bin/sh

usage() {
    cat <<EOF
Usage: $0 [options] [--] [file...]

Arguments:

  -h, --help
    Display this usage message and exit.

  -f <val>, --foo <val>, --foo=<val>
    Documentation goes here.

  -b <val>, --bar <val>, --bar=<val>
    Documentation goes here.

  --
    Treat the remaining arguments as file names.  Useful if the first
    file name might begin with '-'.

  file...
    Optional list of file names.  If the first file name in the list
    begins with '-', it will be treated as an option unless it comes
    after the '--' option.
EOF
}

# handy logging and error handling functions
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$*"; exit 1; }
usage_fatal() { error "$*"; usage >&2; exit 1; }

# parse options
foo="foo default value goes here"
bar="bar default value goes here"
while [ "$#" -gt 0 ]; do
    arg=$1
    case $1 in
        # convert "--opt=the value" to --opt "the value".
        # the quotes around the equals sign is to work around a
        # bug in emacs' syntax parsing
        --*'='*) shift; set -- "${arg%%=*}" "${arg#*=}" "$@"; continue;;
        -f|--foo) shift; foo=$1;;
        -b|--bar) shift; bar=$1;;
        -h|--help) usage; exit 0;;
        --) shift; break;;
        -*) usage_fatal "unknown option: '$1'";;
        *) break;; # reached the list of file names
    esac
    shift || usage_fatal "option '${arg}' requires a value"
done
# arguments are now the file names
Run Code Online (Sandbox Code Playgroud)