Каковы хорошие привычки для разработки аргументов командной строки?

При разработке приложения я начал задаваться вопросом - как мне проектировать аргументы командной строки?

Многие программы используют формулу, такую ​​как -argument value или /argument value . Решение, которое пришло мне в голову, было аргументом : value . Я думал, что это хорошо, потому что без белых пробелов нет возможности перепутать ценности и аргументы. Также легко разбить строку на две на первом слева символа : .

Мои вопросы:

  1. Является популярной формулой -argument value лучше, чем аргумент : значение (более читаемый, более простой для записи, без ошибок, проще понять разработчиками-разработчиками)?
  2. Существуют ли какие-то общеизвестные правила, которым я должен следовать при разработке аргументов командной строки (кроме, если он работает, это нормально)?

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

Мы работаем над приложением, которое будет использоваться в общественных местах (сенсорные тотемы, таблицы). Приложения написаны с использованием Qt Quick 5 (C ++, QML, JS). У устройств будет установлен Windows 8.1 /10. Мы предоставим интерфейсный интерфейс для управления устройствами. Однако некоторые продвинутые администраторы могут захотеть настроить приложение самостоятельно. Это не очень важно со стороны бизнеса, но поскольку я согласен с тем, что Kilian Foth сказал, что я не хочу, чтобы мое приложение было больно для пользователя. Не найдя в Интернете то, что я хочу, я спросил здесь.


Для более продвинутых пользователей Stack Exchange: я хотел, чтобы этот вопрос был общим. Может быть, он подходит для вики сообщества (я не знаю, может ли существующий вопрос быть преобразован с ответами). Поскольку я хочу, чтобы этот вопрос зависел от операционной системы и языка программирования, ответы, представленные здесь, могут стать ценным уроком для других разработчиков.

164 голоса | спросил Filip Hazubski 15 Jam1000000amFri, 15 Jan 2016 11:25:07 +030016 2016, 11:25:07

5 ответов


217

В системах POSIX (например, Linux, MacOSX), по крайней мере, для программ, запущенных в терминале оболочки (например, большинство из них), я бы рекомендовал использовать Соглашения о кодировании GNU (в котором также перечислены общие имена аргументов) и посмотрите Руководства по утилитам POSIX , даже для проприетарного программного обеспечения:

  • всегда обрабатывать - версию и - help (даже /bin /true принимает их!!). Я проклинаю авторов программного обеспечения, не понимая - help , я их ненавижу (потому что prog --help является первой командой . Я пытаюсь новая программа)! Часто - help можно сокращать как -h

  • Введите - help список всех параметров (если у вас их слишком много), в этом случае укажите наиболее распространенные и явно обратитесь к некоторым страницам man или некоторому URL-адресу) и значениям по умолчанию для параметров и, возможно, важным (и программным) переменным среды. Покажите эти списки опций при ошибке аргумента параметра.

  • принять -a короткий аргумент (одна буква) и иметь некоторый эквивалент - long-argument , поэтому -a2 < code> - long-argument = 2 , - long-argument 2 ; конечно, у вас могло бы быть (для редко используемых опций) некоторое имя - only-long-argument ; для модальных аргументов без дополнительных опций -cf обычно обрабатывается как -c -f и т. д., поэтому ваше предложение -argument: value является странным, и я не рекомендую это делать.

  • используйте GLIBC getopt_long или лучше (например, argp_parse , в OCaml это Arg , ...)

  • часто используют - для стандартного ввода или вывода (если вы не можете этого сделать, обработайте /dev /stdin & amp; /dev /stdout даже в нескольких операционных системах, не имеющих их)

  • имитировать поведение подобных программ , повторно используя большинство своих условных опций; в частности -n для сухого запуска (Ã la make ), -h для справки, -v для подробностей , и т. д.

  • использовать - как разделитель между опциями & amp; файл или другие аргументы

  • , если ваша программа использует isatty для тестирования, чем stdin является терминалом (и ведет себя «в интерактивном режиме» в этом случае) интерактивный режим, аналогично, если ваша программа имеет интерфейс GUI (и тесты getenv («DISPLAY») на рабочем столе X11), но также могут использоваться в пакетной или командной строке.

  • Некоторые программы (например, gcc ) принимают непрямые списки аргументов, поэтому @ somefile.txt означает чтение программных аргументов из somefile.txt код>; это может быть полезно, когда ваша программа может принимать очень много аргументов (больше, чем ваш код ядра )

Кстати, вы даже можете добавить некоторые автозавершения для своей программы и обычных оболочек (например, bash или zsh )

Некоторые старые команды Unix (например, dd или даже sed ) имеют странные аргументы команды для исторической совместимости. Я бы порекомендовал не следовать их вредным привычкам (если вы не сделаете их более подходящим вариантом).

Если ваше программное обеспечение представляет собой серию связанных программ командной строки, вдохнитесь из git (который вы, безусловно, используете в качестве инструмента разработки ), который принимает git help и git --help и имеет много команд git и git - help

В редких случаях вы также можете использовать argv [0] (используя символические ссылки в вашей программе), например. bash , вызываемый как rbash , имеет другое поведение ( ограниченный ). Но я обычно не рекомендую это делать; это может иметь смысл, если ваша программа может использоваться в качестве интерпретатора сценариев, используя shebang , т.е. #! в первой строке интерпретируется execve (2) . Если вы делаете такие трюки, обязательно запишите их, в том числе в сообщениях - help .

Помните, что в POSIX оболочка аргументы для подстановки ( до запуска вашей программы!), поэтому избегайте использования символов (например, * или $ ) или ~ ) в параметрах, которые должны быть экранированы оболочкой.

В некоторых случаях вы можете встроить интерпретатор, например GNU guile или Lua в своем программном обеспечении (не изобретайте собственный язык программирования Turing-complete , если вы не эксперт в языках программирования). Это имеет глубокие последствия для дизайна вашего программного обеспечения (так что следует подумать о начале!). Затем вы легко сможете передать какой-либо скрипт или какое-то выражение этому интерпретатору. Если вы примете этот интересный подход, тщательно сработайте свое программное обеспечение и его интерпретируемые примитивы; у вас может быть какое-то странное пользовательское кодирование больших сценариев для вашей вещи.

В других случаях вы можете позволить своим продвинутым пользователям загружать плагин в ваш (используя динамическую загрузку методов Ã la dlopen & amp; dlsym ). Опять же, это очень важное дизайнерское решение (так тщательно определяйте и документируйте интерфейс плагина), и вам нужно будет определить соглашение для передачи параметров программы этим плагинам.

Если ваше программное обеспечение является сложным, сделайте его приемлемым файлы конфигурации (дополнительно или заменяйте аргументы программы) и, вероятно, есть способ проверить (или просто проанализировать) эти файлы конфигурации, не запуская весь код. Например, агент передачи почты (например, Exim или Postfix) является довольно сложным, и полезно иметь возможность «полусушить» его запуск (например, наблюдение за тем, как он обрабатывает какой-либо заданный адрес электронной почты без фактической отправки электронной почты).


Обратите внимание, что /option - это Windows или VMS. Было бы безумным в системах POSIX (потому что иерархия файлов использует / как разделитель каталогов, а также потому, что оболочка выполняет флешинг). Весь мой ответ в основном касается Linux (и POSIX).


P.S. Если возможно, сделайте свою программу бесплатной программой , вы получите улучшения от некоторых пользователей и amp; разработчики (и добавление новой опции программы часто являются одной из самых простых вещей для добавления в существующее бесплатное программное обеспечение). Кроме того, ваш вопрос зависит от много от предполагаемой аудитории : игра для подростков или браузер для бабушки, вероятно, не нуждается в том же типе и количестве опций, что и компилятор, или сетевого инспектора для системных администраторов центров обработки данных, или программного обеспечения САПР для микропроцессорных архитекторов или для разработчиков мостов. Инженер, знакомый с программированием и amp; scripting, вероятно, любит гораздо больше, имея множество настраиваемых опций, чем ваша бабушка, и, вероятно, может захотеть запустить ваше приложение без X11 (возможно, в задаче crontab )).

ответил Basile Starynkevitch 15 Jpm1000000pmFri, 15 Jan 2016 12:40:25 +030016 2016, 12:40:25
67

Тот факт, что формат формата данных является популярным , является его преимуществом.

Вы можете легко увидеть, что использование = или: или даже '' в качестве разделителя представляет собой тривиальные различия, которые могут быть преобразованы друг в друга с помощью компьютера с минимальными усилиями. Что было бы большим усилием для человека, чтобы помнить «Теперь посмотрим, эта редко используемая программа ограничивала вещи с помощью : или с помощью = «Хммм ...»

Другими словами, для любви к Богу не отклоняйтесь от чрезвычайно укоренившихся условностей без веской причины. Люди будут помнить вашу программу как «ту, у которой странный и раздражающий синтаксис cmdline», а не «тот, который сохранил мою эру колледжа».

ответил Kilian Foth 15 Jam1000000amFri, 15 Jan 2016 11:32:17 +030016 2016, 11:32:17
28

В словах непрофессионала

Когда в Риме делай то, что делают римляне.

  • Если ваше приложение CLI предназначено для Linux /Unix, используйте соглашение -p value или - значение параметра . В Linux есть инструменты для синтаксического анализа таких параметров и флагов.

Обычно я делаю что-то вроде этого:

  while [[$ #> 0]]
делать
ключ = "$ 1"
case $ key в
    --dummy)
    # это флаг, что-то здесь
    ;;
    --audit_sessiones)
    # это флаг, что-то здесь
    ;;
    --destination_path)
    # это параметр значения ключа
    # значение всегда находится в $ 2,
    # вы должны перейти, чтобы перейти к следующей итерации
    путь = $ 2
    сдвиг
    ;;
    *)
    # неизвестный вариант
    ;;
ESAC
сдвиг
сделанный
 
  • Если ваше приложение CLI предназначено для Windows, используйте соглашения /flag и /flag: value .

  • Некоторые приложения, такие как Oracle, не используют. Утилиты Oracle используют PARAMETER = VALUE .

  • Мне нравится делать, помимо принятия параметров в командной строке, , предоставляя возможность использования файла parfile , который представляет собой файл пары ключ-значение, чтобы избежать длинных цепочек параметров , Для этого вы должны предоставить дополнительный параметр - parfile mifile.par . Очевидно, что если используется - parfile , все остальные параметры отбрасываются в пользу того, что находится внутри parfile.

  • Дополнительное предположение позволяет использовать некоторые пользовательские переменные среды , например, установка переменной среды MYAPP_WRKSPACE = /tmp будет лишним всегда устанавливать - wrkspace /tmp .

  • В Linux не забудьте добавить параметр автозавершения , что означает, что пользователи могут набирать половину переключателя, нажимают TAB , а затем оболочка завершает его для них.
ответил Tulains Córdova 15 Jpm1000000pmFri, 15 Jan 2016 15:03:06 +030016 2016, 15:03:06
18

Одна вещь, которая еще не появилась:

Попробуйте создать свое программное обеспечение из аргументов командной строки вверх. Значение:

Перед проектированием функциональности создайте пользовательский интерфейс.

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

Кроме того, проверьте docopt ( http://docopt.org/).

docopt - отличная помощь с этим на многих языках, особенно для python, где у вас сильно ограниченные парсеры с аргументами пользователя, такие как argparse, которые все еще считаются «ОК». Вместо того, чтобы иметь парсеры и подпарамеры и условные dicts, вы просто определяете синтаксическую справку , и все остальное.

ответил Florian Heigl 15 Jpm1000000pmFri, 15 Jan 2016 18:18:55 +030016 2016, 18:18:55
3

Некоторые ценные комментарии уже предоставлены (@Florian, Basile), но позвольте мне добавить ... OP говорит,

  

Мы предоставим интерфейсный интерфейс для управления устройствами. Однако некоторые продвинутые администраторы могут захотеть настроить приложение самостоятельно

Но также замечает:

  

Я не хотел, чтобы этот вопрос был специфичным для платформы или языка

Вы должны учитывать целевую аудиторию - продвинутых администраторов . На какой платформе они обычно работают - Win /Unix /Mac? И на какой платформе работает приложение? Следуйте всем правилам CLI, которые уже установлены для этой платформы. У ваших «продвинутых» администраторов нужен /нужен инструмент на основе графического интерфейса?

Вы хотите, чтобы интерфейс был согласованным внутри и с другими инструментами администрирования. Я не хочу останавливаться и думать, что это cmd -p <arg> или cmd -p: <arg> или cmd /p <Arg & GT; . Мне нужны цитаты, потому что есть пробел? Могу ли я cmd -p <val1> <val2> или cmd -p <val1> -p <val2> для нескольких целей? Являются ли они конкретными для заказа? Перегружаемые? Имеет ли cmd -p2 <arg> -p1 <arg> тоже работают? Есть ли ls -l -r -t dir1 dir2 == ls -trl dir1 dir2 ?

Для моих инструментов администрирования Unix я всегда поддерживал руководство, представленное Heiner's Shelldorado в сочетании с другими упомянутыми ссылками.

Также важно, чтобы разработка CLI заключалась в том, чтобы убедиться, что ваше приложение разработано для работы с аргументами командной строки так же, как и из графического интерфейса - то есть: нет бизнес-логики в графическом интерфейсе или использовать общую команду, вызванную как из GUI, так и из CLI.

Большинство инструментов администрирования на базе UNIX на самом деле сначала разрабатываются как инструменты командной строки, а предоставленный графический интерфейс просто упрощает «заполнение» параметров командной строки. Этот подход позволяет автоматизировать, использовать файлы ответов и т. Д. И управление отключением (меньше работает для меня!)

В качестве классического набора инструментов, используемого с этим подходом, Tcl /Tk . Не предлагать вам переключать инструменты; просто рассмотрите подход к дизайну от написания административного приложения на основе графического интерфейса для приложения в качестве инструмента командной строки; затем слоем GUI сверху для удобства. В какой-то момент вы, скорее всего, обнаружите, что графический интерфейс - это боль (и склонность к ошибкам), если вам нужно сделать несколько конфигураций и снова и снова вводить одни и те же параметры, и вы будете искать автоматизированный подход.

Помните, что ваш администратор, вероятно, должен ввести правильные значения в правильные поля в любом случае, так что сколько усилий вы производите в любом случае с GUI?

ответил Ian W 16 Jam1000000amSat, 16 Jan 2016 05:46:39 +030016 2016, 05:46:39

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132