Я не уверен, имеете ли Вы в виду -
или --
, таким образом, вот некоторая информация об обоих:
-
стенография, которую некоторые программы принимают для обращения к STDIN
, стандартный вход программы. Таким образом, в конвейере как echo foo | cat -
(хотя -
является на самом деле ненужным в этом экземпляре), cat
получает "нечто" и новую строку как ее вход от STDIN
.
--
указывает на конец аргументов. В программах, которые имеют дело с файлами, это часто означает, что то, что следует, только будет именами файлов и не, скажем, параметрами командной строки. В таком экземпляре это используется, чтобы попытаться обойти имена файлов, которые похожи на опции (например, если Вам назвали файл -e
и программа также принимает a -e
аргумент). Другой способ обойти это состоит в том, чтобы сделать что-то как command ./-e
, который на самом деле более совместим через программы, поскольку это не требует, чтобы базовая программа реализовала обработку --
.
Это дает вам возможность устанавливать/выбирать $0
при использовании встроенного скрипта. В противном случае $0
было бы просто bash
.
Тогда вы можете сделать, например:
$ bash -c 'wc -c < "${1?}"' getlength foo
4
$ bash -c 'wc -c < "${1?}"' getlength bar
getlength: bar: No such file or directory
$ bash -c 'wc -c < "${1?}"' getlength
getlength: 1: parameter null or not set
Не все оболочки, которые использовались для этого. Панцирь Борна делал. Панцирь Korn (и Альмквист) выбрал первый параметр в $1
. POSIX в конечном итоге пошла по пути Борна, поэтому ksh
и ash
производные вернулись к этому позже (подробнее об этом на http://www.in-ulm.de/~mascheck/various/find/#shell). Это означало, что долгое время для sh
(которая в зависимости от системы была основана на оболочке Борна, Альмквиста или Корна), вы не знали, идет ли первый аргумент в $0
или $1
, поэтому для переносимости нужно было делать что-то вроде:
sh -c 'echo foo in "$1"' foo foo
Или:
sh -c 'shift "$2"; echo txt files are "$@"' tentative-arg0 3 2 *.txt
К счастью, POSIX указал новое поведение, где первый аргумент уходит в $0
, так что теперь мы можем переносить:
sh -c 'echo txt files are "$@"' meaningful-arg0-for-error *.txt
Это поведение определено POSIX :
sh -c имя_команды [аргумент ...]
Считывать команды из операнда command_string. Установите значение специального параметра 0 (см. Специальные параметры ) из значения операнда имя_команды и позиционных параметров ($ 1, $ 2 и т. Д.) Последовательно из оставшихся операндов аргументов.
Что касается того, почему вам нужно такое поведение: это сглаживает разрыв между скриптом и строкой -c
. Вы можете напрямую конвертировать между ними без каких-либо изменений в поведении. Другие области полагаются на то, что они идентичны.
Это также соответствует тому, как в целом работают программные аргументы: в конечном итоге это сводится к вызову одной из функций exec
, в которой первым предоставленным аргументом также является $ 0
, и одинаково часто этот аргумент совпадает с исполняемым файлом, который вы запускаете. Однако иногда вам нужна особая ценность, и другого способа получить ее просто не будет. Учитывая, что аргумент существует, он должен соответствовать чему-то, и пользователь должен иметь возможность установить, что это такое.
Эта последовательность (и, вероятно, историческая случайность) приводит к ситуации, которую вы обнаружите.