1

Я делаю сценарий 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 .

2 ответа2

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 !

0

Может быть, достаточно добавить строку, которую вы хотите, так:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .