getoptsを使って変数を設定する

getoptsを使って変数を設定する

bash関数のパラメータを解析するためにgetoptsを使用したいと思います。

while getopts ${shortopts} arg; do

ところで、変数値の設定に問題があります。呼び出されるまたはmyfunc -v8myfunc -v 8設定されるvb予想値8

myfunc -v 8
vb, arg:   ;  OPTARG: 8
vb: 8

ただし、コマンドを再実行するmyfunc -v 21

myfunc -v 21
vb: 1

これがオプションを処理する方法です。

myfunc
{
  local vb=1

  local arg
  local shortopts="Vuhv:"

  while getopts ${shortopts} arg; do
    case ${arg} in
      # ........................................................
      ("V")
        printf "%s\n" "V01 Jul 2021 Wk27"
        return
        ;;
      ("u")
        printf "%s\n" "-V, -u, -h"
        return
        ;;
      ("h")
        printf "%s\n" "Prints status returned by getopt."
        printf "%s\n" "-V  Displays version"
        printf "%s\n" "-u  Displays usage"
        printf "%s\n" "-h  Displays help."
        printf "%s\n" "-v, -vNUM  Sets verbosity level."

        printf "%s\n" "Example: getopt-status --"
        return
        ;;
      ("v")
        vb="$OPTARG" 
        printf '%s\n' "vb, arg: $arg  ;  OPTARG: $OPTARG"
        ;;
      :)
        echo "Current argument value, OPTARG: -$OPTARG" >&2
        echo "Must supply an argument to -$OPTARG" >&2
        ;;
      ?)
        printf "%s\n" "Invalid option, OPTARG: $OPTARG"
        ;;
    esac
  done

  echo "vb: $vb"

}

答え1

ilkkachuと他の人が述べたように、そこにはいくつかのバグがあります。関数の終了コードが返されるので、関数内で動作しreturnます。localreturn

以下は、アイデアを提供する最小限の例です。

#!/usr/bin/env bash

die(){ echo >&2 "$@"; exit 1; }
usage(){ echo >&2 "usage: $0 [-u] [-v num] "; exit 0; }

shortopts=":Vuhv:"
while getopts "$shortopts" opt; do
        case $opt in
        u)      usage ;;
        v)      case $OPTARG in
                ''|*[!-0-9]*) die "invalid number $OPTARG" ;;
                *) val=$OPTARG ;;
                esac
                ;;
        :)      die "argument needed to -$OPTARG" ;;
        *)      die "invalid switch -$OPTARG" ;;
        esac
done
shift $((OPTIND - 1))

echo value="$val"

いくつかの注意:

オプション文字列の最初の文字が(コロン)の場合、前にオプション文字がないため通常は意味がなく、getoptsは「自動エラー報告モード」に切り替えます。効率的なスクリプトでは、迷惑なメッセージで邪魔されることなくエラーを直接処理できるため、一般的に望むものです。

もっと見る:https://wiki.bash-hackers.org/howto/getopts_tutorial

答え2

getopts関数に使用すると、〜しなければならないOPTARG特にローカライズOPTIND

あなたはできます

myfunc() {
    local OPTIND OPTARG
    ...

getopts初期化を担当します。

関連情報