использование '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на continueпросто приводит к зависанию myscr -orи .myscr -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

Обратите внимание, что при первом параметре, который не соответствует ни одному конкретному случаю, разбор параметра остановится, поэтому a ./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, которые не являются одними из длинных, вы можете рекурсивно вызывать ту же функцию для каждой буквы из case *)... Вам нужен флаг, если вы только что обработали $1как длинный параметр. Однако в этом случае вы подвергаете свой скрипт некорректному поведению из-за опечатки (например, если я напишу -overrider I will process-o -v -e -r -d`...)

Связанный контент