82

いくつかのスクリプトのラッパーとしてシェル スクリプトを設計したいと考えています。myshell.sh使用するパラメータを指定getoptsし、残りのパラメータを同じ順序で指定されたスクリプトに渡したいと思います。

次のように実行された場合myshell.sh

myshell.sh -h hostname -s test.sh -d waittime param1 param2 param3

myshell.sh param1 param2 -h hostname param3 -d waittime -s test.sh

myshell.sh param1 -h hostname -d waittime -s test.sh param2 param3

上記のすべては次のように呼び出すことができるはずです

test.sh param1 param2 param3

でオプション パラメータを利用し、 myshell.sh 残りのパラメータを基になるスクリプトにポストすることは可能ですか?

4

9 に答える 9

112

OPに似たことをしたかったのですが、ここここに必要な関連情報を見つけました

基本的に、次のようなことをしたい場合:

script.sh [options] ARG1 ARG2

次に、次のようにオプションを取得します。

while getopts "h:u:p:d:" flag; do
case "$flag" in
    h) HOSTNAME=$OPTARG;;
    u) USERNAME=$OPTARG;;
    p) PASSWORD=$OPTARG;;
    d) DATABASE=$OPTARG;;
esac
done

そして、次のように位置引数を取得できます。

ARG1=${@:$OPTIND:1}
ARG2=${@:$OPTIND+1:1}

詳しい情報と詳細は、上記のリンクから入手できます。

それが役立つことを願っています!!

于 2012-11-15T15:04:13.007 に答える
27

opts と args を混在させる:

ARGS=""
echo "options :"
while [ $# -gt 0 ]
do
    unset OPTIND
    unset OPTARG
    while getopts as:c:  options
    do
    case $options in
            a)  echo "option a  no optarg"
                    ;;
            s)  serveur="$OPTARG"
                    echo "option s = $serveur"
                    ;;
            c)  cible="$OPTARG"
                    echo "option c = $cible"
                    ;;
        esac
   done
   shift $((OPTIND-1))
   ARGS="${ARGS} $1 "
   shift
done

echo "ARGS : $ARGS"
exit 1

結果:

bash test.sh  -a  arg1 arg2 -s serveur -c cible  arg3
options :
option a  no optarg
option s = serveur
option c = cible
ARGS :  arg1  arg2  arg3
于 2016-10-22T10:20:30.057 に答える
3

getoptsparam1-nオプションの組み合わせを解析しません。

他のように param1-3 をオプションに入れる方がずっと良いです。

さらに、 shflagsなどの既存のライブラリを使用できます。かなりスマートで使いやすいです。

最後の方法は、getopts を使用せずにパラメーターを解析する独自の関数を作成し、case構築を通じてすべてのパラメーターを繰り返すだけです。これは最も難しい方法ですが、お客様の期待に正確に応える唯一の方法です。

于 2012-07-31T15:21:19.687 に答える
2

私は、getoptsオプションと位置パラメーターを完全に組み合わせるために拡張できる方法を 1 つ考え出しました。アイデアは、、、 などにgetopts見つかった位置パラメータの呼び出しと割り当てを交互に行うことです。n1n2n3

parse_args() {
    _parse_args 1 "$@"
}

_parse_args() {
    local n="$1"
    shift

    local options_func="$1"
    shift

    local OPTIND
    "$options_func" "$@"
    shift $(( OPTIND - 1 ))

    if [ $# -gt 0 ]; then
        eval test -n \${n$n+x}
        if [ $? -eq 0 ]; then
            eval n$n="\$1"
        fi

        shift
        _parse_args $(( n + 1 )) "$options_func" "$@"
    fi
}

次に、OPの場合、次のように使用できます。

main() {
    local n1='' n2='' n3=''
    local duration hostname script

    parse_args parse_main_options "$@"

    echo "n1 = $n1"
    echo "n2 = $n2"
    echo "n3 = $n3"
    echo "duration = $duration"
    echo "hostname = $hostname"
    echo "script   = $script"
}

parse_main_options() {
    while getopts d:h:s: opt; do
        case "$opt" in
            d) duration="$OPTARG" ;;
            h) hostname="$OPTARG" ;;
            s) script="$OPTARG"   ;;
        esac
    done
}

main "$@"

実行すると、次の出力が表示されます。

$ myshell.sh param1 param2 -h hostname param3 -d waittime -s test.sh
n1 = param1
n2 = param2
n3 = param3
duration = waittime
hostname = hostname
script   = test.sh

単なる概念実証ですが、誰かにとって役立つかもしれません。

注:を使用する 1 つの関数が使用parse_argsする別の関数を呼び出しparse_args 外側の関数が eg を宣言している場合、落とし穴がありますが、内側の関数はそうでlocal n4=''はなく 4 つ以上の位置パラメーターが内側の関数に渡されます。

于 2014-08-31T20:48:48.753 に答える
1

オプションと位置パラメーターの混合を簡単に処理する簡単な方法をマッシュアップしました ($@ には位置パラメーターのみを残します)。

#!/bin/bash
while [ ${#} -gt 0 ];do OPTERR=0;OPTIND=1;getopts "p:o:hvu" arg;case "$arg" in
        p) echo "Path:   [$OPTARG]" ;;
        o) echo "Output: [$OPTARG]" ;;
        h) echo "Help"              ;;
        v) echo "Version"           ;;
    \?) SET+=("$1")                                           ;;
    *) echo "Coding error: '-$arg' is not handled by case">&2 ;;
esac;shift;[ "" != "$OPTARG" ] && shift;done
[ ${#SET[@]} -gt 0 ] && set "" "${SET[@]}" && shift

echo -e "=========\nLeftover (positional) parameters (count=$#) are:"
for i in `seq $#`;do echo -e "\t$i> [${!i}]";done

出力例:

[root@hots:~]$ ./test.sh 'aa bb' -h -v -u -q 'cc dd' -p 'ee ff' 'gg hh' -o ooo
Help
Version
Coding error: '-u' is not handled by case
Path:   [ee ff]
Output: [ooo]
=========
Leftover (positional) parameters (count=4) are:
        1> [aa bb]
        2> [-q]
        3> [cc dd]
        4> [gg hh]
[root@hots:~]$
于 2015-08-03T02:41:52.403 に答える
-1

UNIX のオプション処理にはいくつかの標準があり、シェル プログラミングでgetoptsは、それらを実施するための最良の方法です。ほぼすべての現代言語 (perl、python) には、 のバリアントがありgetoptsます。

これは簡単な例です:

command [ options ] [--] [ words ]
  1. 各オプションは、ダッシュで始まる-必要があり、単一の文字で構成されている必要があります。

  2. GNU プロジェクトでは、長いオプションが導入されました。これは、2 つのダッシュで始まり、--単語全体が続き--long_optionます。AST KSH プロジェクトには、長いオプションもサポートする getopts が-ありますfind(1)

  3. オプションは、引数を期待する場合と期待しない場合があります。

  4. ダッシュ () で始まらない単語は、-オプション処理を終了します。

  5. 文字列--はスキップする必要があり、オプション処理を終了します。

  6. 残りの引数は、位置パラメーターとして残されます。

Open Group には次のセクションがあります。Utility Argument Syntax

Eric Raymond の The Art of Unix Programmingには、伝統的な UNIX のオプション文字の選択とその意味に関する章があります。

于 2012-07-31T22:30:20.047 に答える