Автоматический анализ параметров getopts в динамические переменные с тем же именем в bash

У меня есть сценарий bash, который я написал, скажем, с тремя параметрами командной строки, bib, bob и boo... и я хочу прочитать параметры пользователя в переменной bash с тем же именем, что я делаю следующим образом:

PARSED_OPTIONS=$(getopt -n $0  --long "bib:,bob:,boo:"  -- "$@")

eval set -- "$PARSED_OPTIONS";

while true; do
  case "$1" in

  --bib)
  bib=$2
  shift 2;;

  --bob)
  bob=$2
  shift 2;;

  --boo)
  boo=$2
  shift 2 ;;

  --)
  shift
  break;;

  esac
done

Все работает нормально, пока все хорошо...

Но теперь я хочу расширить это до списка многих опций, и поэтому вместо того, чтобы писать длинный оператор case, было бы действительно неплохо иметь возможность каким-то образом перебирать список опций и автоматически передавать опции в переменную. , что-то в этом роде

opts="bib:,bob:,boo:," 

PARSED_OPTIONS=$(getopt -n $0  --long $opts -- "$@")

for arg in `echo $opts | tr , " "` ; do 
  eval set -- "$PARSED_OPTIONS";
  while true; do

    case "$1" in
      --${arg})
      declare $arg=$2
      shift 2
      ;;
      --)
      shift
      break;;
    esac
  done
done

Я использую оператор объявления, чтобы передать аргумент в динамическую переменную с тем же именем (см. имена переменных в Bash второе решение), и это решение для выполнения цикла по спискам, разделенным запятыми Перейти через переменную оболочки, разделенную запятыми, но здесь я получаю бесконечный цикл. Я думаю, потому что 2 неиспользуемых параметра разрешены, поскольку они находятся в списке PARSED_OPTIONS, но тогда они не отсекаются в цикле, поскольку ищется только "arg"... Я не вижу очевидного способа обойти это, но Я уверен, что есть один.


person Adrian Tompkins    schedule 13.02.2019    source источник


Ответы (1)


Я понял, что у меня была команда сдвига все еще внутри оператора case, поэтому она не завершалась. Мне также нужно было убрать двоеточие : из аргумента, так что вот мой автоматический поиск аргумента для скрипта bash, который работает:

# specify an arbitrary list of arguments:

opts=bib:,bob:,boo:

PARSED_OPTIONS=$(getopt -n $0  --long "${opts}"  -- "$@")

for arg in ${opts//,/ } ; do 
  var=${arg//:} # remove the colon
  eval set -- "$PARSED_OPTIONS";
  while true ; do
    case "$1" in
      --${var})
      declare ${var}=$2
      ;;
    --)
      break
      ;;
    esac
    shift 2
  done
done

Итак, если вы попробуете test_script --boo 3 --bib hello --bob lkkfrfrfr

echo $bib $bob $boo

должен дать

hello lkkfrfrfr 3
person Adrian Tompkins    schedule 13.02.2019