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

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

Почему консольные приложения начинают аргументы с:

a) one dash (myapp -arg1 123; ls -al)
b) two dashes (myapp --arg1 123; git push origin master --force)
c) without dashes at all (myapp 123; man ls)
d) without dashes but with the equal sign (myapp arg1=123; dd if=/dev/zero)

Разве нет стандартного соглашения? Даже среди стандартных приложений Linux все три случая a), b) и d) существуют одновременно. И сложно запомнить, когда следует использовать, например, -help, а когда --help.

решение1

Тире используется для обозначенияпараметры, которые изменяют поведение команды. Аргументы без дефисов обозначают основные параметры команды, часто это имена файлов.

Одиночные дефисы обычно вводят опции, состоящие всего из одной буквы. Несколько таких опций могут быть сгруппированы вместе, поэтому ls -a -lмогут быть сокращены до ls -al. Это было стандартное соглашение для большинства ранних команд Unix.

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

Иногда опция требует собственный параметр. Стили этого различаются: некоторые команды используют -o parameter, некоторые используют -oparameter, некоторые используют --option=parameter, а некоторые допускают несколько форм.

Есть также несколько команд, которые изобрели свои собственные, идеосинкразические стили аргументов. Это, как правило, очень старые команды, из тех, что были до того, как был достигнут консенсус по соглашениям об аргументах. Примерами этого являются tarи dd. findтакже необычна тем, что является старой командой, которая использовала полные варианты слов до того, как --было создано соглашение; ее аргументы фактически являются ее собственным языком, потому что ее потребности не вписываются в типичную command -options parametersпарадигму.

Другие причины различий между командами заключаются в том, что в Unix изначально не было библиотечной функции разбора аргументов. Функции getoptи getoptsбыли созданы только в самом начале его существования. Использование этих библиотек по сути заставляет вас следовать общепринятым практикам. Но старые программы делали свой собственный разбор аргументов ad hoc, и разные программисты принимали разные решения.

решение2

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

Прежде чем я расскажу об этом подробнее, я хочу прояснить терминологию. Прежде всего, то, что вы называете «опциями», на самом деле также является аргументами. Фактически, все, что вы вводите в командной строке, является аргументом (включая имя программы). Затем эти аргументы обычно сохраняются в массиве (называемом argvв C). Затем программа выбирает, как (или следует ли) анализировать эти аргументы и вести себя соответствующим образом. Теперь аргументы обычно принимают одну из трех форм:

  1. флаги (не принимают аргументов; просто включают или выключают поведение)
  2. переключатели (принимают аргумент; изменяют поведение на основе аргумента)
  3. параметры (простые данные, не предназначенные для изменения поведения)

1и 2часто упоминаются как OPTIONSи предназначены для изменения поведения программы, но оба появляются в разных стилях (как также упоминал Бармар). getoptБиблиотека C на самом деле допускает большую гибкость в этой области. Хотя соглашение заключается в том, чтобы опции были указаны либо как одна буква с предшествующим одним дефисом, либо как полное слово с предшествующими двумя дефисами, программы, написанные с использованием, на getoptсамом деле допускают, чтобы любое из следующего было эквивалентным (предполагая, helpчто задано hкак индекс):

-h, --h,--help

Однако -helpна самом деле не допускается getopt(поэтому, если инструмент использует -helpдля своего флага использования, то вы можете быть уверены, что он не был написан с помощью библиотеки getopt). Это происходит потому, что getoptинтерпретирует одиночный дефис как сигнал о списке объединенных опций, поэтому он интерпретирует -helpкак -h -e -l -p.

Кроме того, когда опции принимают аргументы (обычно называемые «optargs»), есть несколько способов их указать. Ниже — учитывая, что индекс для optравен o,и для этого optтребуется оптарг¹—все также эквивалентны:

-oParameter, -o Parameter, --opt=Parameter,--opt Parameter

Хотя эта getoptбиблиотека в настоящее время является широко используемым стандартом, многие инструменты, появившиеся до нее (например, tar), по-прежнему используют собственную настройку синтаксического анализа, поэтому она tar -xjfэквивалентна tar xjf.


TL;DR: getoptне всегда был рядом, поэтому программистам приходилось разбирать аргументы по-своему. Но новые инструменты обычно используют его, поэтому их поведение разумно и предсказуемо.


1 Существует недостаточно документированная возможность иметь опционы, которые могут принимать оптарг, но нетребоватьодин. Необязательные оптарги вызывают всевозможные раздражающие вещи и делают некоторые из наиболее распространенных способов указания опций недействительными (поскольку они были бы неоднозначными). К счастью, аргументы, которые принимают необязательный аргумент, не слишком распространены.

решение3

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

ls -l -h 
or
ls -lh

варианты начинаются с двух тире, обычно принимают слова, несколько вариантов не могут работать

ls --list --human

Связанный контент