Почему консольные приложения начинают аргументы с:
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
часто упоминаются как 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