Как использовать getopt в командной строке удара только с долгими опциями?

Если Ваш хост Кактусов освободит возможность соединения месту назначения, или если Ваш сервер Кактусов понизится, то Вы окажетесь с разрывами в своих хранилищах RRD в течение тех периодов и очевидно полученными графиками. Поскольку SNMP является протоколом момента времени, без кэширования или истории, и опросами Кактусов по умолчанию через SNMP и обновляет RRD с текущими данными.

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

Веб-сайт Кактусов содержит многочисленные сценарии, которые могли быть основанием для Вашего эластичного набора датчиков.

12
21.10.2014, 15:39
2 ответа

getopt прекрасно справляется с отсутствием коротких вариантов. Но вы должны сказать ему, что у вас нет коротких опционов. Это причуда синтаксиса - из руководства:

Если в первой части не найдено опции -o или --options, то в качестве строки short options используется первый параметр второй части.

Это то, что происходит в вашем тесте: getopt -l longkey -- --long-key foo рассматривает --long-key как список опций -egklnoy и foo как единственный аргумент. Используйте

getopt -o '' -l long-key -- "$@"

например,

$ getopt -l long-key -o '' -- --long-key foo
 --long-key -- 'foo'
$ getopt -l long-key -o '' -- --long-key --not-recognized -n foo
getopt: unrecognized option '--not-recognized'
getopt: invalid option -- 'n'
 --long-key -- 'foo'
14
27.01.2020, 19:55

Не знаю о getopt , но встроенная функция getopts может использоваться для обработки только таких длинных параметров, как это:

while getopts :-: o
do  case "$o$OPTARG" in
(-longopt1) process ;;
(-longopt2) process ;;
esac; done

Конечно, как есть, это не сработает, если предполагается, что у длинных опций есть аргументы. Хотя это можно сделать, но, как я узнал, работая над этим. Хотя я изначально включил его сюда, я понял, что для длинных опций он не очень полезен. В данном случае это было только сокращение моих полей case (match) на один предсказуемый символ. Теперь, что я знаю, это то, что он отлично подходит для коротких опций - он наиболее полезен, когда он перебирает строку неизвестной длины и выбирает отдельные байты в соответствии со своей строкой опций.Но когда опция - это аргумент, вы мало что делаете с комбинацией для var do case $ var в . Я думаю, что лучше не усложнять.

Я подозреваю, что то же самое можно сказать и о getopt , но я не знаю достаточно об этом, чтобы сказать с уверенностью. Учитывая следующий массив arg, я продемонстрирую свой собственный небольшой синтаксический анализатор arg, который зависит в первую очередь от отношения оценки / присваивания, которое я оценил для псевдонима и $ ((shell = math)) .

set -- this is ignored by default --lopt1 -s 'some '\'' 
args' here --ignored   and these are ignored \
--alsoignored andthis --lopt2 'and 

some "`more' --lopt1 and just a few more

Это строка аргумента, с которой я буду работать. Теперь:

aopts() { env - sh -s -- "$@"
} <<OPTCASE 3<<\OPTSCRIPT
acase() case "\$a" in $(fmt='
        (%s) f=%s; aset "?$(($f)):";;\n'
        for a do case "$a" in (--) break;;
        (--*[!_[:alnum:]]*) continue;;
        (--*) printf "$fmt" "$a" "${a#--}";;
        esac;done;printf "$fmt" '--*' ignored)
        (*) aset "" "\$a";;esac
shift "$((SHIFT$$))"; f=ignored; exec <&3 
OPTCASE
aset()  {  alias "$f=$(($f${1:-=$(($f))+}1))"
        [ -n "${2+?}" ] && alias "${f}_$(($f))=$2"; }
for a do acase; done; alias
#END
OPTSCRIPT

Это обрабатывает массив arg одним из двух разных способов в зависимости от того, передаете ли вы ему один или два набора аргументов, разделенных разделителем - . В обоих случаях это относится к последовательностям обработки массива arg.

Если вы назовете это так:

: $((SHIFT$$=3)); aopts --lopt1 --lopt2 -- "$@"

Его первым делом будет написать функцию acase () , которая будет выглядеть так:

acase() case "$a" in 
    (--lopt1) f=lopt1; aset "?$(($f)):";;
    (--lopt2) f=lopt2; aset "?$(($f)):";;
    (--*) f=ignored; aset "?$(($f)):";;
    (*) aset "" "$a";;esac

И рядом с shift 3 . Подстановка команд в определении функции acase () оценивается, когда вызывающая оболочка создает входные документы функции, но acase () никогда не вызывается и не определяется в вызывающей оболочке. . Хотя, конечно, он вызывается в подоболочке, и таким образом вы можете динамически указывать интересующие параметры в командной строке.

Если передать ему массив без разделителей, он просто заполнит acase () совпадениями для всех аргументов, начинающихся со строки - .

Функция выполняет практически всю свою обработку в подоболочке - итеративно сохраняет каждое из значений arg в псевдонимах, которым присвоены ассоциативные имена. По завершении он распечатывает каждое значение, которое было сохранено с псевдонимом , который указан в POSIX для печати всех сохраненных значений, указанных таким образом, чтобы их значения можно было повторно ввести в оболочку. Итак, когда я делаю ...

aopts --lopt1 --lopt2 -- "$@"

Его вывод выглядит так:

...ignored...
lopt1='8'
lopt1_1='-s'
lopt1_2='some '\'' args'
lopt1_3='here'
lopt1_4='and'
lopt1_5='just'
lopt1_6='a'
lopt1_7='few'
lopt1_8='more'
lopt2='1'
lopt2_1='and

some "`more'

При просмотре списка аргументов он проверяет совпадение с блоком case. Если он находит там совпадение, он выдает флаг - f = optname . Пока он снова не найдет допустимую опцию, он будет добавлять каждый последующий аргумент в массив, который он строит на основе текущего флага. Если одна и та же опция указана несколько раз, результаты складываются и не отменяются. Все, что не в регистре, или любые аргументы, следующие за игнорируемыми параметрами, присваиваются массиву игнорируемого .

Выходные данные защищены оболочкой для автоматического ввода оболочкой, поэтому:

eval "$(: $((SHIFT$$=3));aopts --lopt1 --lopt2 -- "$@")"

... должно быть совершенно безопасно. Если по какой-либо причине небезопасен , то вам, вероятно, следует отправить отчет об ошибке сопровождающему вашей оболочки.

Он назначает два типа значений псевдонима для каждого совпадения. Во-первых, он устанавливает флаг - это происходит независимо от того, предшествует ли параметр несовпадающим аргументам. Таким образом, любое появление - flag в списке аргументов вызовет flag = 1 . Это не составляет - - flag --flag --flag просто получает flag = 1 . Это значение имеет приращение - для любых аргументов, которые могут следовать за ним.Его можно использовать как индексный ключ. После выполнения eval выше я могу сделать:

printf %s\\n "$lopt1" "$lopt2"

... получить ...

8
1

Итак:

for o in lopt1 lopt2
do list= i=0; echo "$o = $(($o))"
        while [ "$((i=$i+1))" -le "$(($o))" ]
        do list="$list $o $i \"\${${o}_$i}\" "
done; eval "printf '%s[%02d] = %s\n' $list";  done

OUTPUT

lopt1 = 8
lopt1[01] = -s
lopt1[02] = some ' args
lopt1[03] = here
lopt1[04] = and
lopt1[05] = just
lopt1[06] = a
lopt1[07] = few
lopt1[08] = more
lopt2 = 1
lopt2[01] = and

some "`more

И для аргументов, которые не совпадают, я бы заменил игнорируется в приведенном выше для ... в поле , чтобы получить:

ignored = 10
ignored[01] = this
ignored[02] = is
ignored[03] = ignored
ignored[04] = by
ignored[05] = default
ignored[06] = and
ignored[07] = these
ignored[08] = are
ignored[09] = ignored
ignored[10] = andthis
1
27.01.2020, 19:55

Теги

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