'case $1 in' を使用してコマンド オプションを読み取ります - ダッシュの後の複数のフラグ、および異常なフラグの処理方法?

'case $1 in' を使用してコマンド オプションを読み取ります - ダッシュの後の複数のフラグ、および異常なフラグの処理方法?

長いオプションと短いフラグの両方を使用する bash スクリプトを作成しています。長いオプションが必要なので、 は使用できませんgetopts。次のコードを使用してみました。

while test -n "$1"; do
  case "$1" in
        -o|--override)  NO_CHANGE=yes;shift 1;;
        -r|--reset)     OV_RESET=yes;shift 1;;
        -h|--help)      hthemehelp;shift 1;;
        *)              break;;
  esac
done

myscr -o -rこれは、または のように呼び出すと機能しますmyscr -hが、 を試しても、myscr -orプログラムは通常の動作を実行し、 を実行すると、myscr -or -hに到達する前にループを終了します-h。 を に置き換えると、breakがハングします。continuemyscr -ormyscr -or -h

答え1

これを試着してサイズを確認してください:

#!/bin/bash
pleasereset=1
while test -n "$1"; do
   pleaseshift=0
   [[ pleasereset -eq 1 ]] && thisvar=$1 && pleasereset=0;
   case "$thisvar" in
      -o*|--override) echo "override!"; pleaseshift=1;;
      -r*|--reset) echo "reset!"; pleaseshift=1;;
      -h*|--help) echo "help!"; pleaseshift=1;;
      *) break ;;
   esac
   if [[ "$pleaseshift" = "1" ]];
   then
      testvar=${thisvar##-}
      if [[ ${#testvar} -gt 1 ]] && [[ ! ${thisvar} = --* ]];
      then
         thisvar=-$( echo "$testvar" | cut -c 2- )
      else
         shift 1; pleasereset=1;
      fi
   fi
done

特定のケースに一致しない最初のパラメータでは、パラメータの解析が停止するため、 は./foobar.sh -o --help -s -rを処理しないことに注意してください-r。 これは、行をエラー処理に変更することで調整できますが、 !*) break;;を忘れずに挿入してください。pleaseshift=1

答え2

必要な行を追加するだけで十分かもしれません:

while test -n "$1"; do
  case "$1" in
        -or|-ro)        OV_RESET=yes;NO_CHANGE=yes;shift 1;;
        -o|--override)  NO_CHANGE=yes;shift 1;;
        -r|--reset)     OV_RESET=yes;shift 1;;
        -h|--help)      hthemehelp;shift 1;;
        *)              break;;
  esac
done

または、より複雑な方法として、case関数内にブロックを配置し、shift 1そのブロックから抜けるがwhile内には入れておくという方法もあります。
倍増オプション ( -or、、-oh長いオプションの 1 つでない場合は、... の各文字に対して同じ関数を再帰的に呼び出すことができます。長いオプションとしてcase *)処理した場合はフラグが必要です$1。ただし、この場合、誤植が原因でスクリプトの動作が悪くなります (例: -overrider I will process-o -v -e -r -d` と記述した場合...)

関連情報