Я хочу вызвать myscript
файл следующим образом:
$ ./myscript -s 45 -p any_string
или
$ ./myscript -h #should display help
$ ./myscript #should display help
Мои требования:
getopt
здесь, чтобы получить входные аргументы- проверить, что
-s
существует, если не вернуть ошибку - проверьте, что значение после
-s
45 или 90 - проверьте, что
-p
существует и есть ли строка ввода после - если пользователь вводит
./myscript -h
или просто./myscript
отображает справку
Я пробовал пока этот код:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Но с этим кодом я получаю ошибки. Как это сделать с Bash и getopt
?
-s
, сделать его позиционное аргумент:./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
на самом деле есть опция (то есть ваша программа может продолжаться, если ее нет). В этом случае./myscript 45 -p any_string
. (Я думаю, что онgetopt
может обрабатывать смешанные опции и позиционные аргументы, тогда какbash
встроенная командаgetopts
требует, чтобы все позиционные аргументы были помещены после опций.)Ответы:
Пример работы:
источник
usage()
действительно вернуть 1?-h
него он должен возвращаться0
, при нажатии на несуществующий флаг он должен возвращаться>0
(для простоты я не делал различий между этими случаями, и никто не заставляет вас печатать текст использования в последнем случае) , Я видел программы, которые всегда возвращаются!= 0
, хотя и включаются-h/--help
. Может быть, мне следует обновить фрагмент на тот случай, если люди используют его как шаблон (надеюсь, нет)?getopts
') дизайн, нет такой вещи как "необязательные аргументы" сgetopts
. Синтаксический анализатор просто не может знать, является ли следующий токен аргументом текущей опции или самой опцией, поскольку это-p
может быть предполагаемое значение. Вы можете обойти это, если абсолютно уверены, что параметр option не может выглядеть как другой допустимый параметр, да, но можно сказать, что есть причина, по которой необязательные аргументы не определены в POSIX.bash
лексеру в определении переменных. Во многих случаях они не нужны, и тот факт, что я всегда ими пользуюсь, является лишь вопросом стиля персонального кодирования. На мой взгляд, легче (и красивее) просто всегда использовать их, а не вспоминать правила синтаксического анализа в отношении неоднозначности. Почти то же самое, почему пишутif (foo) { bar; }
вместо языкаif (foo) bar;
C-стиля (эстетика и / или избегание глупых ошибок).Проблема с оригинальным кодом заключается в том, что:
h:
ожидает параметр, где он не должен, поэтому измените его на простоh
(без двоеточия)-p any_string
, вам нужно добавитьp:
в список аргументовВ основном
:
после опции означает, что она требует аргумента.Основной синтаксис
getopts
: (см .man bash
:):где:
OPTSTRING
строка со списком ожидаемых аргументов,h
- проверить вариант-h
без параметров; выдает ошибку по неподдерживаемым параметрам;h:
- проверить опцию-h
с параметром; выдает ошибки по неподдерживаемым параметрам;abc
- проверка опций-a
,-b
,-c
; выдает ошибки по неподдерживаемым параметрам;:abc
- проверка опций-a
,-b
,-c
; заставляет замолчать ошибки на неподдерживаемых опциях;Примечания: Другими словами, двоеточие перед опциями позволяет вам обрабатывать ошибки в вашем коде. Переменная будет содержаться
?
в случае неподдерживаемой опции,:
в случае пропущенного значения.OPTARG
- устанавливается текущее значение аргумента,OPTERR
- указывает, должны ли Bash отображать сообщения об ошибках.Таким образом, код может быть:
Пример использования:
Смотрите: Учебник по маленьким getopts на Bash Hackers Wiki
источник
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Он учитывает только один символ пробела перед параметром буквы, удаляет знак # из комментария и добавляет «-» перед параметром буквы, делая его более понятным для команды.:
права, пока не увидел эти заметки. Нам нужно добавить:
к опциям, где мы ожидаем аргумент.использование
getopt
Почему Гетопт?
Чтобы проанализировать разработанные аргументы командной строки, чтобы избежать путаницы и уточнить параметры, которые мы анализируем, чтобы читатель команд мог понять, что происходит.
Что такое getopt?
getopt
используется для разбиения (разбора) параметров в командных строках для упрощения анализа с помощью процедур оболочки и для проверки допустимых параметров. Для этого он используетgetopt(3)
подпрограммы GNU .getopt
может иметь следующие типы опций.Примечание. В этом документе при объяснении синтаксиса:
КАК ИСПОЛЬЗОВАТЬ
getopt
?Синтаксис: первая форма
Примеры:
Здесь h, v, t - параметры, а -h -v -t - то, как параметры должны быть заданы в командной строке.
В необязательном параметре значение не может иметь разделение пробелов с помощью опции. Так, в примере "-t123" -t это опция 123, это значение.
Синтаксис: вторая форма
Здесь после того, как Getopt делится на пять частей
Примеры
Синтаксис: третья форма
Здесь после того, как Getopt делится на пять частей
Примеры
GETOPT_OPTIONS
getopt_options изменяет способ анализа параметров командной строки.
Ниже приведены некоторые из getopt_options
Опция: -l или --longoptions
Например,
--name=Karthik
это длинная опция, отправляемая в командной строке. В getopt использование длинных опций похоже наПоскольку имя: указано, опция должна содержать значение
Опция: -a или --alternative
Пример, вместо того, чтобы
--name=Karthik
вы могли использовать просто-name=Karthik
Полный пример скрипта с кодом:
Запуск этого файла сценария:
источник
Пример, упакованный с
getopt
(мой дистрибутив вставил его/usr/share/getopt/getopt-parse.bash
) выглядит так, как будто он охватывает все ваши случаи:источник
Я знаю, что на этот вопрос уже дан ответ, но для протокола и для тех, кто имеет те же требования, что и я, я решил опубликовать этот связанный ответ. Код заполнен комментариями для объяснения кода.
Обновленный ответ:
Сохраните файл как
getopt.sh
:Тогда вы можете использовать это так:
Старый ответ:
Недавно мне нужно было использовать общий подход. Я столкнулся с этим решением:
Я не тестировал это грубо, поэтому у меня могли быть некоторые ошибки там.
источник
getopts
функцию, добавьтеlocal OPTIND OPTARG
к функцииgetopts
POSIX 7 пример
Также стоит проверить пример из стандарта: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
И тогда мы можем попробовать это:
Протестировано в Ubuntu 17.10,
sh
тире 0.5.8.источник
«getops» и «getopt» очень ограничены. Хотя «getopt» предлагается вообще не использовать, он предлагает длинные варианты. Где в качестве "getopts" разрешены только односимвольные опции, такие как "-a", "-b". Есть несколько недостатков при использовании любого из них.
Итак, я написал небольшой скрипт, который заменяет «getopts» и «getopt». Это начало, возможно, его можно улучшить.
Обновление 08-04-2020 : я добавил поддержку дефисов, например, "--package-name".
источник