getopt, getopts или парсинг руководства - что использовать, когда я хочу поддерживать и короткие и долгие опции?

Вы, вероятно, хотите использовать настройки ServerAlive для этого. Они не требуют никакой конфигурации на сервере и могут быть установлены на командной строке, если Вы желаете.

ssh -o ServerAliveInterval=5 -o ServerAliveCountMax=1 $HOST

Это будет отправлять ssh сообщение проверки активности каждые 5 секунд, и если оно прибывает время для отправки другой проверки активности, но ответ на последний не был получен, затем соединение завершается.

Критическое различие между ServerAliveInterval и TCPKeepAlive слой, в котором они работают.

  • TCPKeepAlive воздействует на уровень TCP. Это отправляет пустому TCP пакет ACK. Брандмауэры могут быть настроены для игнорирования этих пакетов, поэтому при прохождении через брандмауэра, который отбрасывает неактивные соединения, они не могут поддержать соединение.
  • ServerAliveInterval воздействует на ssh слой. Это на самом деле отправит данные через ssh, таким образом, пакет TCP будет иметь зашифрованные данные в, и брандмауэр не может сказать, является ли это проверка активности или законный пакет, таким образом, они работают лучше.
32
29.01.2013, 13:37
4 ответа

Если бы это должно быть портативно к диапазону Нельдов, необходимо было бы придерживаться POSIX sh. И AFAIU там у Вас просто нет выбора, но прокручивающегося аргумента, обрабатывающего вручную.

9
27.01.2020, 19:37

getopt по сравнению с getopts кажется, религиозная проблема. Что касается аргументов против getopt в Bash FAQ:

  • "getopt не может обработать строки пустых аргументов", кажется, относится к известной проблеме с дополнительными аргументами, на которые она похожа getopts не поддерживает вообще (по крайней мере, от чтения help getopts для Bash 4.2.24). От man getopt:

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

Я не знаю где"getopt не может обработать [...] споры со встроенным пробелом", прибывает из, но давайте протестируем его:

  • test.sh:

    #!/usr/bin/env bash
    set -o errexit -o noclobber -o nounset -o pipefail
    params="$(getopt -o ab:c -l alpha,bravo:,charlie --name "$0" -- "$@")"
    eval set -- "$params"
    
    while true
    do
        case "$1" in
            -a|--alpha)
                echo alpha
                shift
                ;;
            -b|--bravo)
                echo "bravo=$2"
                shift 2
                ;;
            -c|--charlie)
                echo charlie
                shift
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Not implemented: $1" >&2
                exit 1
                ;;
        esac
    done
    
  • выполненный:

    $ ./test.sh -
    $ ./test.sh -acb '   whitespace   FTW   '
    alpha
    charlie
    bravo=   whitespace   FTW   
    $ ./test.sh -ab '' -c
    alpha
    bravo=
    charlie
    $ ./test.sh --alpha --bravo '   whitespace   FTW   ' --charlie
    alpha
    bravo=   whitespace   FTW   
    charlie
    

Похож на проверку и помощника мне, но я уверен, что кто-то покажет, как я полностью неправильно понял предложение. Конечно, проблема мобильности все еще стоит; необходимо будет решить, сколько времени стоит инвестировать в платформы с более старым или никаким доступным Bash. Моя собственная подсказка должна использовать YAGNI, и инструкции KISS - Только разрабатывают для тех определенных платформ, которые Вы знаете, будут используемыми. Переносимость кода Shell обычно переходит к 100%, как время разработки переходит к бесконечности.

26
27.01.2020, 19:37
  • 1
    OP упомянул потребность быть портативным на многие платформы Unix в то время как getopt Вы заключаете в кавычки, здесь является определенным для Linux. Отметьте это getopt не часть bash, это даже не утилита GNU, и на Linux поставляется с пакетом util-linux. –  Stéphane Chazelas 29.01.2013, 14:45
  • 2
    , который имеет Большинство платформ getopt, только AFAIK Linux идет с тем, который поддерживает долгие опции или пробелы в аргументах. Другие только поддерживали бы синтаксис System V. –  Stéphane Chazelas 29.01.2013, 14:55
  • 3
    getopt традиционная команда, которая прибывает из System V задолго до того, как Linux когда-либо выпускался. getopt никогда не стандартизировался. Ни один из POSIX, Unix или Linux (LSB), когда-либо стандартизированный getopt команда. getopts указан во всех трех, но без поддержки долгих опций. –  Stéphane Chazelas 29.01.2013, 15:08
  • 4
    Только для добавления к этому обсуждению: это не традиционное getopt. Это - разновидность linux-utils, как обозначено @StéphaneChazelas. Это имеет опции прежней версии, которые отключат синтаксис, описанный выше, в особенности состояния страницы справочника "GETOPT_COMPATIBLE вынуждают getopt использовать первый формат вызова, как указано в РЕЗЮМЕ". Однако, если можно ожидать, что целевые системы, чтобы иметь этот пакет установили, это - полностью способ пойти, поскольку исходный getopt ужасен, и getopt Bash является очень ограниченным –  n.caillou 18.05.2017, 18:15

Существует этот getopts_long, записанный как функция оболочки POSIX, которую можно встроить в сценарии.

Обратите внимание что Linux getopt (от util-linux) работы правильно если не в традиционном режиме и поддержках, долгие опции, но, вероятно, не опция для Вас, если необходимо быть портативными к другим Нельдам.

Последние версии ksh93 (getopts) и zsh (zparseopts) имейте встроенную поддержку парсинга долгих опций, которые могли бы быть опцией для Вас, поскольку это доступно для большинства Нельдов (хотя часто не установленный по умолчанию).

Другая опция состояла бы в том, чтобы использовать perl и Getopt::Long модуль, оба из которых должны быть доступными на большинстве Нельдов в наше время, любом путем записи целого сценария в perl или просто назовите жемчуг только, чтобы проанализировать опцию и подать извлеченную информацию к оболочке. Что-то как:

parsed_ops=$(
  perl -MGetopt::Long -le '

    @options = (
      "foo=s", "bar", "neg!"
    );

    Getopt::Long::Configure "bundling";
    $q="'\''";
    GetOptions(@options) or exit 1;
    for (map /(\w+)/, @options) {
      eval "\$o=\$opt_$_";
      $o =~ s/$q/$q\\$q$q/g;
      print "opt_$_=$q$o$q"
    }' -- "$@"
) || exit
eval "$parsed_ops"
# and then use $opt_foo, $opt_bar...

Посмотрите perldoc Getopt::Long поскольку, что это может сделать и как это отличается от других синтаксических анализаторов опции.

11
27.01.2020, 19:37

Вы можете использовать getoptв системах, которые его поддерживают, и использовать запасной вариант для систем, которые этого не делают.

Например,pure-getoptреализован в чистом Bash в виде капли -вместо GNU getopt.

0
27.01.2020, 19:37

Теги

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