web-dev-qa-db-ja.com

Bash関数内でgetoptsを使用する

.bash_profileで定義した関数内でgetoptsを使用したいと思います。考えは、この関数にいくつかのフラグを渡して、その動作を変更したいです。

コードは次のとおりです。

function t() {
    echo $*
    getopts "a:" OPTION
    echo $OPTION
    echo $OPTARG
}

このように呼び出すと:

t -a bc

私はこの出力を取得します:

-a bc
?
 

どうしましたか?手動でシフトおよび解析せずに値bcを取得したいです。関数内でgetoptsを正しく使用するにはどうすればよいですか?

編集:コードスニペットを修正して、$ OPTARGを試してみましたが、無駄になりました

編集#2:OK、コードは問題ないことがわかりました、私のシェルは何らかの形で台無しにされました。新しいウィンドウを開くと解決しました。 arg値は実際には$ OPTARGにありました。

41
Magnus

@Ansgarが指摘しているように、オプションへの引数は${OPTARG}が、関数内でgetoptsを使用する場合に注意する必要があるのはこれだけではありません。また、${OPTIND}は、設定を解除するか、localを宣言することによって関数に対してローカルになります。そうしないと、関数を複数回呼び出したときに予期しない動作が発生します。

t.sh

#!/bin/bash

foo()
{
    foo_usage() { echo "foo: [-a <arg>]" 1>&2; exit; }

    local OPTIND o a
    while getopts ":a:" o; do
        case "${o}" in
            a)
                a="${OPTARG}"
                ;;
            *)
                foo_usage
                ;;
        esac
    done
    shift $((OPTIND-1))

    echo "a: [${a}], non-option arguments: $*"
}

foo
foo -a bc bar quux
foo -x

実行例:

$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
foo: [-a <arg>]

コメントアウトした場合# local OPTIND、これはあなたが代わりに得るものです:

$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
a: [bc], non-option arguments:

それ以外は、その使用法は関数の外部で使用される場合と同じです。

86

getopts Shell関数内での使用の簡単な例を次に示します。

#!/usr/bin/env bash
t() {
  local OPTIND
  getopts "a:" OPTION
  echo Input: $*, OPTION: $OPTION, OPTARG: $OPTARG
}
t "$@"
t -a foo

出力:

$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo

@ Adrianが指摘したlocal OPTIND(またはOPTIND=1)は、シェルがOPTINDを自動的にリセットしないため、 getoptsへの複数の呼び出しman bash)。

getoptsの基本構文は次のとおりです。

getopts OPTSTRING VARNAME [ARGS...]

デフォルトでは、引数を指定しないことは、「$ @」で明示的に呼び出すことと同等です:getopts "a:" opts "$@"

問題がある場合、これらはgetoptsがチェックするために使用される変数です。

  • OPTIND-処理される次の引数のインデックス、
  • OPTARG-変数は、getoptsで見つかったオプションの引数に設定されます。
  • OPTERR(POSIXではない)-0または1に設定して、Bashがgetoptsによって生成されたエラーメッセージを表示するかどうかを示します。

さらに詳しくは、 Small getopts tutorial The Bash Hackers Wikiをご覧ください。

10
kenorb

引数は変数$OPTARGに保存されます。

function t() {
  echo $*
  getopts "a:" OPTION
  echo $OPTION
  echo $OPTARG
}

出力:

$ t -a bc
-a bc
a
bc
5
Ansgar Wiechers