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

Это довольно просто, используя Json.NET :

dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

Также using Newtonsoft.Json.Linq:

dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

Документация: Запрос JSON с динамическим

375
задан codeforester 22 March 2019 в 05:26
поделиться

5 ответов

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

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

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

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

<час>

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

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

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

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

279
ответ дан Bill Karwin 22 March 2019 в 15:26
поделиться
  • 1
    У меня была та же проблема, но в OSX она вставляет " n" вместо разрыва строки? Я проверил другие сообщения с той же проблемой, но я не мог понять, как зафиксировать ее? Кому-либо нравится? – JM88 27 February 2014 в 04:21

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

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

11
ответ дан Nietzche-jou 22 March 2019 в 15:26
поделиться

Встроенное 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 "$0: error - unrecognized option $1" 1>&2; exit 1;;
    (*)  break;;
    esac
    shift
done

# Process remaining non-option arguments
...

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

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

148
ответ дан Jonathan Leffler 22 March 2019 в 15:26
поделиться

Взгляните на shFlags , которая является переносимой библиотекой оболочки (то есть: sh, bash, dash, ksh, zsh в Linux, Solaris и т. Д.).

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

Вот простая Hello, world! с использованием shFlag :

#!/bin/sh

# source shflags from current directory
. ./shflags

# define a 'name' command-line string flag
DEFINE_string 'name' 'world' 'name to say hello to' 'n'

# parse the command-line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"

# say hello
echo "Hello, ${FLAGS_name}!"

Для ОС с расширенным getopt, который поддерживает длинные параметры (например, Linux), вы можете:

$ ./hello_world.sh --name Kate
Hello, Kate!

Для остальных вы должны использовать короткий параметр:

$ ./hello_world.sh -n Kate
Hello, Kate!

Добавить новый флаг так же просто, как добавить новый DEFINE_ вызов .

33
ответ дан 22 November 2019 в 23:49
поделиться
#!/bin/bash
while getopts "abc:d:" flag
do
  case $flag in
    a) echo "[getopts:$OPTIND]==> -$flag";;
    b) echo "[getopts:$OPTIND]==> -$flag";;
    c) echo "[getopts:$OPTIND]==> -$flag $OPTARG";;
    d) echo "[getopts:$OPTIND]==> -$flag $OPTARG";;
  esac
done

shift $((OPTIND-1))
echo "[otheropts]==> $@"

exit

.

#!/bin/bash
until [ -z "$1" ]; do
  case $1 in
    "--dlong")
      shift
      if [ "${1:1:0}" != "-" ]
      then
        echo "==> dlong $1"
        shift
      fi;;
    *) echo "==> other $1"; shift;;
  esac
done
exit
8
ответ дан 22 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

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