2011-06-10 74 views
3

有沒有辦法將非位置參數提供給shell腳本? 含義顯式指定某種標誌?shell腳本參數非位置

. myscript.sh value1 value2 
. myscript.sh -val1=value1 -val2=value2 

回答

4

您可以使用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#*=}" "[email protected]"; 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 
3

做的最簡單的辦法是將它們作爲環境變量:

 
$ val1=value1 val2=value2 ./myscript.sh 

這不會csh的變種工作,但你可以,如果你正在使用這樣的外殼使用ENV。

2

實施例:

#!/bin/bash 
while getopts d:x arg 
do 
     case "$arg" in 
       d) darg="$OPTARG";; 
       x) xflag=1;; 
       ?) echo >&2 "Usage: $0 [-x] [-d darg] files ..."; exit 1;; 
     esac 
done 
shift $(($OPTIND-1)) 

for file 
do 
     echo =$file= 
done