Когда вы пишете бит разбора командной строки вашего кода, вы указываете, какие параметры принимают аргументы, а какие нет. Например, в сценарии оболочки, принимающем -hпараметр (например, для справки) и -aпараметр, который должен принимать аргумент, вы делаете
opt_h=0 # default value
opt_a=""
while getopts 'a:h' opt; do
case $opt in
h) opt_h=1 ;;
a) opt_a="$OPTARG" ;;
esac
done
echo "h: $opt_h"
echo "a: $opt_a"
a:hНемного говорит : «Я ожидаю , чтобы разобрать два варианта, -aи-h , и -aдолжен принимать аргумент» (это :после того, aчто говорит парсер , который -aпринимает аргумент).
Следовательно, никогда не возникает двусмысленности в том, где заканчивается опция, где начинается ее значение и где начинается другая.
Запуск это:
$ bash test.sh -h -a hello
h: 1
a: hello
$ bash test.sh -h -ahello
h: 1
a: hello
$ bash test.sh -hahello
h: 1
a: hello
Вот почему вы в большинстве случаев не должны писать свой собственный анализатор командной строки для анализа параметров.
В этом примере есть только один сложный случай. Разбор обычно останавливается на первой не-опции, поэтому если у вас есть вещи в командной строке , которая выглядит как варианты:
$ bash test.sh -a hello -world
test.sh: illegal option -- w
test.sh: illegal option -- o
test.sh: illegal option -- r
test.sh: illegal option -- l
test.sh: illegal option -- d
h: 0
a: hello
Следующее решает, что:
$ bash test.sh -a hello -- -world
h: 0
a: hello
-- сигналы конец параметров командной строки, а -worldбит остается для программы , чтобы сделать все , что хочет с (это в одной из позиционных переменных).
То есть, кстати, как вы удаляете файл, который имеет тире в начале своего имени файла с rm .
РЕДАКТИРОВАТЬ :
Утилиты, написанные на C, getopt()(объявленные в unistd.h), работают примерно так же. На самом деле, насколько нам известно, bashфункция getoptsможет быть реализована с помощью вызова функции библиотеки Cgetopt() . Perl, Python и другие языки имеют похожие библиотеки синтаксического анализа командной строки, и, скорее всего, они выполняют их анализ аналогичным образом.
Некоторые из этих getoptи getoptподобных библиотечных подпрограмм также обрабатывают «длинные» опции. Им обычно предшествует double-dash ( --), а длинные опции, которые принимают аргументы, часто делают это после знака равенства, например, --block-size=SIZEопция [некоторых реализаций] duутилиты (которая также позволяет-B SIZE указывать одно и то же).
Руководства по причинам часто пишутся так, чтобы показать пробел между короткими опциями и их аргументами, вероятно, для удобства чтения.
РЕДАКТИРОВАТЬ : Действительно старые инструменты, такие как ddи tarутилиты, имеют опции без черточек перед ними. Это чисто по историческим причинам и для обеспечения совместимости с программным обеспечением, которое полагается на них для работы именно таким образом. tarУтилита получила возможность принимать варианты с прочерками в более поздние времена. Руководство BSD для tarвызова опций старого стиля для «связанных флагов».