Использование getopts для обработки длинных и коротких параметров командной строки

Я хочу, чтобы с помощью моего скрипта оболочки вызывались длинные и короткие формы параметров командной строки.

Я знаю, что можно использовать getopts, но, как и в Perl, я не смог сделать то же самое с shell.

Любые идеи о том, как это можно сделать, чтобы я мог использовать такие параметры, как:

./shell.sh --copyfile abc.pl /tmp/
./shell.sh -c abc.pl /tmp/

. В приведенном выше описании обе команды означают одно и то же для моей оболочки, но с использованием getopts, Я не смог реализовать их?

378
задан 22.03.2019, 17:26

3 ответа

Существует три реализации, которые можно рассмотреть:

  • Bash, встроенный getopts. Это не поддерживает длинные имена опции с префиксом двойного тире. Это только поддерживает односимвольные опции.

  • реализация UNIX BSD автономных getopt команда (который является тем, что MacOS использует). Это не поддерживает долгие опции также.

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

<час>

Некоторые другие ответы показывают решение для использования удара, встроенного getopts для имитации долгих опций. То решение на самом деле делает короткую опцию, символ которой "-". Таким образом, Вы добираетесь "-" как флаг. Затем что-либо после этого становится OPTARG, и Вы тестируете OPTARG с вложенным case.

Это умно, но это идет с протестами:

  • getopts не может осуществить выбирать спецификацию. Это не может возвратить ошибки, если пользователь предоставляет недопустимую опцию. Необходимо сделать собственную проверку ошибок, поскольку Вы анализируете OPTARG.
  • OPTARG используется для длинного имени опции, которое усложняет использование, когда Ваша долгая опция сама имеет аргумент. Вы заканчиваете тем, что имели необходимость кодировать это сами как дополнительный случай.

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

279
ответ дан 04.10.2019, 13:46
  • 1
    Так. Каково межплатформенное, портативное решение? – troelskn 18.10.2009, 13:05
  • 2
    GNU Getopt, кажется, единственный выбор. На Mac, GNU установки getopt от macports. В Windows, I' d устанавливают GNU getopt с Cygwin. – Bill Karwin 18.10.2009, 18:23
  • 3
    По-видимому , ksh getopts может дескриптор долгие опции. – Tgr 24.07.2010, 04:13
  • 4
    @Bill +1, хотя также довольно просто создать getopt из источника ( software.frodo.looijaard.name/getopt) на Mac. Можно также проверить версию getopt, установленного в системе из сценариев с " getopt-T; $ эха? ". – Chinasaur 31.08.2011, 07:55
  • 5
    У меня была та же проблема, но в OSX она вставляет " n" вместо разрыва строки? Я проверил другие сообщения с той же проблемой, но я не мог понять, как зафиксировать ее? Кому-либо нравится? – JM88 14.10.2019, 17:21

Встроенное getopts не может сделать этого. Существует внешнее getopt (1) программа, которая может сделать это, но Вы только получаете его на Linux от util-linux пакет. Это идет со сценарием getopt-parse.bash в качестве примера.

существует также getopts_long записаны как функция оболочки.

11
ответ дан 04.10.2019, 13:46
  • 1
    getopts_long (выше) работ над Mac OS X 10.6 +? – David Andreoletti 16.01.2012, 14:57
  • 2
    Эти getopt был включен в версию 1.0 FreeBSD в 1993 и была часть FreeBSD с тех пор. По сути, это было принято из FreeBSD 4.x для включения в Apple' s проект Darwin. С OS X 10.6.8, страница справочника, включенная Apple, остается точным дубликатом страницы справочника FreeBSD. Таким образом да, it' s включенный в OS X и рты других операционных систем около Linux.-1 на этом ответе для дезинформации. – ghoti 27.03.2012, 17:41

Встроенное getopts команда тихо, AFAIK, ограниченный односимвольными опциями только.

существует (или используется, чтобы быть) внешняя программа getopt, которая реорганизовала бы ряд опций, таким образом, что было легче проанализировать. Вы могли адаптировать тот дизайн для обработки долгих опций также. Использование в качестве примера:

aflag=no
bflag=no
flist=""
set -- $(getopt abf: "$@")
while [ $# -gt 0 ]
do
    case "$1" in
    (-a) aflag=yes;;
    (-b) bflag=yes;;
    (-f) flist="$flist $2"; shift;;
    (--) shift; break;;
    (-*) echo "[110]: error - unrecognized option $1" 1>&2; exit 1;;
    (*)  break;;
    esac
    shift
done

# Process remaining non-option arguments
...

Вы могли использовать подобную схему с getoptlong команда.

Примечание, что фундаментальная слабость с внешним getopt программа является трудностью обработки споров с пробелами в них, и в сохранении тех пробелов точно. Поэтому встроенное getopts выше, хотя ограничено фактом, он только обрабатывает однобуквенные опции.

148
ответ дан 04.10.2019, 13:46

Теги

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