В настоящее время я пишу скрипт Bash, который имеет следующие требования:
- он должен работать на самых разных платформах Unix / Linux
- он должен поддерживать как короткие, так и (GNU) длинные опции
Я знаю, что это getopts
было бы предпочтительным способом с точки зрения мобильности, но AFAIK это не поддерживает длинные варианты.
getopt
поддерживает длинные опции, но BashGuide настоятельно рекомендует:
Никогда не используйте getopt (1). getopt не может обрабатывать пустые строки аргументов или аргументы со встроенным пробелом. Пожалуйста, забудьте, что это когда-либо существовало.
Таким образом, есть возможность ручного разбора. Это подвержено ошибкам, производит довольно много стандартного кода, и мне нужно обрабатывать ошибки самостоятельно (я думаю, что getopt(s)
делать обработку ошибок самостоятельно).
Итак, что будет предпочтительным выбором в этом случае?
bash
shell-script
options
user-interface
getopts
helpermethod
источник
источник
Ответы:
Если он должен быть переносимым на ряд Unices, вам придется придерживаться POSIX sh. И AFAIU там у вас просто нет выбора, кроме как вручную обрабатывать аргументы.
источник
getopt
против,getopts
кажется, религиозная проблема. Что касается аргументов противgetopt
в Bash FAQ :«
getopt
не может обрабатывать пустые строки аргументов», по-видимому, относится к известной проблеме с необязательными аргументами, которая, по- видимому,getopts
вообще не поддерживается (по крайней мере из чтенияhelp getopts
Bash 4.2.24). Отman getopt
:Я не знаю, откуда взялась «
getopt
не могу обработать [...] аргументы со встроенным пробелом», но давайте проверим это:test.sh:
бег:
Выглядит как проверка и сопряжение для меня, но я уверен, что кто-то покажет, как я полностью неправильно понял предложение. Конечно проблема переносимости все еще остается; вам придется решить, сколько времени стоит инвестировать в платформы с более старой версией или без Bash. Мой собственный совет - использовать рекомендации YAGNI и KISS - разрабатывать только для тех конкретных платформ, которые, как вы знаете, будут использоваться. Переносимость кода оболочки обычно достигает 100%, а время разработки уходит в бесконечность.
источник
getopt
как вы цитируете здесь, это зависит от Linux. Обратите внимание, чтоgetopt
это не частьbash
, это даже не утилита GNU, а в Linux поставляется с пакетом util-linux.getopt
только Linux AFAIK, который поддерживает длинные опции или пробелы в аргументах. Другие будут поддерживать только синтаксис System V.getopt
это традиционная команда, пришедшая из System V задолго до того, как Linux был выпущен.getopt
никогда не был стандартизирован. Ни один из POSIX, Unix или Linux (LSB) никогда не стандартизировалgetopt
команду.getopts
указан во всех трех, но без поддержки длинных опций.getopt
. Это вкус linux-utils, как указано @ StéphaneChazelas. Он имеет устаревшие параметры, которые отключают синтаксис, описанный выше, в частности, состояния man-страницы «GETOPT_COMPATIBLE заставляет getopt использовать первый формат вызова, как указано в SYNOPSIS». Однако, если вы можете ожидать, что на целевых системах будет установлен этот пакет, то это совершенноЭтот getopts_long записан как функция оболочки POSIX, которую вы можете встроить в свой скрипт.
Обратите внимание, что Linux
getopt
(fromutil-linux
) работает правильно, когда не в традиционном режиме, и поддерживает длинные параметры, но, вероятно, не подходит для вас, если вам нужно переноситься на другие Unices.Последние версии ksh93 (
getopts
) и zsh (zparseopts
) имеют встроенную поддержку парсинга длинных опций, которые могут быть вам полезны, поскольку они доступны для большинства Unices (хотя часто не устанавливаются по умолчанию).Другим вариантом будет использование
perl
и егоGetopt::Long
модуля, который в настоящее время должен быть доступен в большинстве Unices, либо путем написания всего скрипта,perl
либо просто путем вызова perl просто для анализа опции и передачи извлеченной информации в оболочку. Что-то типа:Посмотрите,
perldoc Getopt::Long
что он может сделать и чем он отличается от других парсеров опций.источник
В каждом обсуждении по этому вопросу выделяется возможность писать код синтаксического анализа вручную - только тогда вы можете быть уверены в функциональности и переносимости. Я советую вам не писать код, который вы могли бы сгенерировать и сгенерировать с помощью простых в использовании генераторов кода с открытым исходным кодом. Используйте Argbash , который был разработан, чтобы дать окончательный ответ на вашу проблему. Это хорошо документированный генератор кода, доступный как приложение командной строки , онлайн или как образ Docker .
Я не советую использовать библиотеки bash, некоторые из них используют
getopt
(что делает их совершенно непереносимыми), и очень сложно объединить гигантский нечитаемый блоб оболочки с вашим скриптом.источник
Вы могли бы использовать
getopt
в системах, которые поддерживают это, и использовать запасной вариант для систем, которые этого не делают.Например
pure-getopt
, реализован в чистом Bash, чтобы быть заменой GNUgetopt
.источник