オプションの終わりに対処する方法— getoptsで


9

getoptsを使用してbashスクリプトの引数を解析します

while getopts ":hd:" opt; do
  case $opt in
    d ) echo "directory = $OPTARG"; mydir="$OPTARG"; shift $((OPTIND-1)); OPTIND=1 ;;
    h ) helptext
      graceful_exit ;;
    * ) usage
      clean_up
      exit 1
  esac
done

exeparams="$*"

exeparams未解析のオプション/引数を保持します。exeparamsを使用して、スクリプト内で実行されるコマンドのオプションを保持したいので(スクリプト自体のオプションと重複する可能性があります)、スクリプトに渡されるオプションを終了するために-を使用します。私が通過した場合

myscript -d myscriptparam -- -d internalparam

exeparams 開催します

-- -d internalparam

--これらの引数を内部コマンドに渡すために、先頭を削除したいと思います。これを行うためのエレガントな方法はありますか、または--getopts なしで残りだけを保持する文字列を取得できますか?


ループのshift; OPTIND=1中に置くことgetoptsはおそらくそれを行うための最良の方法ではありません。オプションは2つしかなく、他のすべてのオプションではスクリプトを終了するだけなので、それはあなたのケースでのみ機能します。それ以外の場合はshift; OPTIND=1、すべてのオプションで必要になります。つまり、コードが重複することになります(悪い習慣)。shift $((OPTIND - 1))ループの終わりの直後に行うだけです。これは最も一般的な方法であり、おそらく最も効率的でもあります。
jw013

回答:


7

どうですか:

# ... getopts processing ...

[[ $1 = "--" ]] && shift
exeparams=("$@")

パラメータを保持するには配列を使用する必要があることに注意してください。これは、空白を含む引数を適切に処理します。配列を逆参照する"${exeparams[@]}"


1
これは、オプションの最後との間に引数がないこと--、つまり外部プログラムにscript foo -- bar渡さfoo -- barれることを前提としています。それは質問で明示的に述べられなかったので、私の答えはその仮定をしません。
jw013

OPが「今、先頭を削除したい-」と言っている場合を除いて
グレンジャックマン

それは例-- -d internalparamsです。いずれにせよ、私の答えはどちらの場合にも対処するのに十分一般的です。
jw013

14

組み込みのを使用しshiftます。最初に、getoptsスクリプトの通常の操作を行います。そのループが完了すると、

shift "$((OPTIND - 1))"

既に処理されたすべてのオプションをシフトアウトします。

そこから、オプションでない引数がある場合は、スクリプトの最初の部分(の前--)への処理を完了する必要があります。に遭遇したら--、後の部分(の-d internalparam後に続く部分--)のみが残るまでシフトアウトします。これを行う1つの方法(bash構文を使用):

while [[ $# -gt 0 ]]; do
    # process next argument
    case $1 in
    foo) # process foo
    ;;
    --) shift; break;; # found '--', discard it and exit loop
    *) # handle unrecognized argument
    ;;
    esac
    # not '--', so discard the argument and continue
    shift
done

最後に、渡すことができるオプション/引数の2番目のセットのみが残ります。残りのパラメータを別のコマンドに渡すために使用しないでください$*"$@"代わりに使用して、元の単語分割を保持します。

external_command "$@"

はい、ありがとう!しかし、どのように正確に見つけるの--ですか?
highsciguy 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.