Как извлечь неизвестные аргументы в рамках сценария оболочки?

Онейрический (для Linux Mint) устарел.

http://www.linuxmint.com/oldreleases.php

1
29.04.2015, 14:01
2 ответа

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

Хотя КШ поддерживает довольно мощный встроенный . Исходя из этого (и на ваши вполне сложные требования) я изложил возможное решение решение на основе KSH с следующим фрагментом кода:

while getopts ":[-][[n]:][99:verbose][s]" opt
do  case $opt in
    (n) n_arg=$OPTARG ;;
    (99) verbose=1 ;;
    (s) s=1 ;;
    (*) arg_rest+=( "${@:OPTIND-1:1}" ) ;;
    esac
done
shift OPTIND-1

printf "main opt(%s)=%s\n" "-n" "$n_arg"
printf "main opt(%s)=%s\n" "--verbose" "$verbose"
printf "main opt(%s)=%s\n" "-s" "$s"

function delegate
{
    while getopts ":[-][i][98:long]" opt
    do  case $opt in
        (i) int=1 ;;
        (98) long=1 ;;
        esac
    done
    shift OPTIND-1

    printf "func opt(%s)=%s\n" "-i" "$int"
    printf "func opt(%s)=%s\n" "--long" "$long"
}

printf "Delegate: '%s'\n" "${arg_rest[@]}"
delegate "${arg_rest[@]}"

Программа сначала анализирует все параметры, устанавливает внутренние переменные по мере необходимости и хранит Неизвестные варианты в массиве. Затем вы видите несколько printf для управления настройками. Затем определение функции, где остальные варианты должны быть делегированы; Функция может быть заменена командой. Наконец звонок функции (или соответствует некоторой другой команде) с остальными аргументами.

(для описания ksh ГУМКЦ Функции Функции вызов из сеанса KSH Getopts - Motortopts .)

​​Запуск этой программы производит этот вывод:

$ ksh ./getopts_script -s -n 23 --verbose -i --long
main opt(-n)=23
main opt(--verbose)=1
main opt(-s)=1
Delegate: '-i'
Delegate: '--long'
func opt(-i)=1
func opt(--long)=1



для внедрения оболочки функции Getopts, которая поддерживает длинные варианты, см. https://github.com/stephane-chazelas/misc-scripts/blob/master/getopts_long. Sh

1
27.01.2020, 23:50

Заманчиво попробовать getopt заказать заранее известные опции. К сожалению, он отвергает все неизвестные аргументы и немедленно прекращает парсинг.

Но пока опции не слишком сложны, можно обмануть бэшовых getopt. Некоторое вдохновение было взято из mkaurball. Под источником следуют пещеры.

#!/bin/bash

while [ $OPTIND -le $# ]
do
  if getopts ":sn:-:" argument
  then
    case $argument in
      s) echo "-$argument" ;;
      n) echo "-$argument with argument $OPTARG" ;;
      \?) pass+=("-$OPTARG") ;;
      -) lastarg=$((OPTIND - 1))
        case "${!lastarg}" in
          --verbose) echo "--verbose" ;;
          --*) pass+=("--$OPTARG") ;;
          *) echo "invalid argument: -"
            exit 1 ;;
        esac ;;
      :) echo "$OPTARG without argument"
        exit 1 ;;
    esac
  else
    pass+=("${!OPTIND}")
    let OPTIND++
  fi
done

echo pass: "${pass[@]}"
  • Необычно, что getopts не используется в качестве условия для , в то время как , что привело бы к остановке цикла, как только бы он не столкнулся с каким-либо позиционным параметром, то есть с чем угодно, что не является ни опцией, ни аргументом к ней. Вместо этого эти случаи добавляются в массив, собирающий параметры для pass on.
  • Спецификация параметров включает :-, что заставляет getopts рассматривать длинные опции -длинные в качестве короткой опции - с аргументом -длинные . Использование без осторожности, смешивание тире в середине короткой опции (как -s-n) может нарушить это, поэтому лучше проверить, действительно ли фактический параметр начинается с двух тире. Таким образом, подход будет неудачным, если обернутая программа хочет видеть опции типа -short-with-dashes в качестве опции.
  • Хотя по природе -etopts, двойные тире также проглатываются. Этого можно хотеть, но этого также можно избежать, вставив ["${!OPTIND}" != '--' ] && перед getopts
  • Разбор длинных аргументов оберткой может быть несколько затруднительным, так как они должны быть обработаны во вложенном случае.
0
27.01.2020, 23:50

Теги

Похожие вопросы