В зависимости от конкретной ситуации, это либо явно не определено (так что реализации могут делать, как они будут), либо должно происходить так, как вы заметили. В вашем точном сценарии echo ab$
, POSIX предписывает вывод «абы $» , что вы наблюдали и это не определенно . Краткое резюме всех различных случаев в конце.
Есть два элемента: сначала разбить на слова, а затем интерпретировать эти слова.
токенизации
Токенизация POSIX требует, чтобы a $
не было началом действительного расширения параметра , подстановки команды или арифметической подстановки, чтобы считаться литеральной частью WORD
создаваемого токена. Это связано с тем, что правило 5 («Если текущий символ не заключен в кавычки $
или `
, оболочка должна идентифицировать начало любых кандидатов на расширение параметра, замену команды или арифметическое расширение из их вводных последовательностей символов без кавычек: $
или ${
, $(
или `
, и $((
, соответственно» ) не применяется, поскольку ни одно из этих расширений не является жизнеспособным. Расширение параметра требует, чтобы там отображалось действительное имя, а пустое имя недопустимо.
Поскольку это правило не применимо, мы продолжаем следовать, пока не найдем то, которое применимо. Два кандидата - № 8 («Если предыдущий символ был частью слова, текущий символ должен быть добавлен к этому слову.») И № 10 («Текущий символ используется в качестве начала нового слова».) , которые применяются к echo a$
и echo $
соответственно.
Существует также третий случай формы, echo a$+b
которая проходит через ту же трещину, поскольку +
это не имя специального параметра. К этому мы вернемся позже, так как он запускает разные части правил.
Таким образом, спецификация требует, чтобы $
синтаксически она считалась частью слова, и затем она может быть дополнительно обработана.
Расширение слова
После того, как входные данные были проанализированы таким образом, с $
включенным в слово, расширения слова применяются к каждому из прочитанных слов. Каждое слово обрабатывается индивидуально .
Указано, что :
Если после символа «без кавычек» следует символ, который не является одним из следующих:
- Числовой символ
- Имя одного из специальных параметров (см. Специальные параметры )
- Допустимый первый символ имени переменной
- A
<left-curly-bracket>
('{')
-
<left-parenthesis>
результат не уточняется.
«Не указано» - это конкретный термин, означающий, что
- Соответствующая оболочка может выбрать любое поведение в этом случае
- Соответствующее приложение не может полагаться на какое-либо конкретное поведение
В вашем примере echo ab$
, то $
не следует любому символ , так что это правило не применяется , и неопределенный результат не вызывается. Расширение $
не вызывается, поэтому оно буквально присутствует и распечатывается.
Там , где она будет применяться в нашем третьем случае сверху: echo a$+b
. Здесь $
следует +
, что не является число, специальный параметр ( @
, *
, #
, ?
, -
, $
, !
, или 0
), начало переменного имени (подчеркивания или буквенным от портативного набора символов ), или один из кронштейнов. В этом случае поведение не определено: соответствующая оболочка может изобрести специальный параметр, называемый +
раскрытием , и соответствующее приложение не должно предполагать, что оболочка этого не делает . Оболочка может делать все что угодно, в том числе сообщать об ошибке.
Например, zsh, в том числе в своем режиме POSIX, интерпретируется $+b
как « b
набор переменных » и заменяет 1 или 0 вместо него. Он также имеет расширения для ~
и =
. Это соответствующее поведение.
Это может произойти и в другом месте echo "a$ b"
. Опять же, оболочке разрешено делать, как она хочет, и вы, как автор сценария, должны избегать $
буквального вывода. Если нет, это может сработать, но вы не можете на это полагаться. Это абсолютная буква спецификации, но я не думаю, что такого рода детализация была задумана или рассмотрена.
В итоге
echo ab$
: буквальный вывод, полностью указан
echo a$ b
: буквальный вывод, полностью указан
echo a$ b$
: буквальный вывод, полностью указан
echo a$b
: расширение параметра b
, полностью указано
echo a$-b
: расширение специального параметра -
, полностью указано
echo a$+b
: неопределенное поведение
echo "a$ b"
: неопределенное поведение
В $
конце слова вам разрешается полагаться на поведение, и оно должно рассматриваться буквально и передаваться echo
команде как часть его аргумента. Это требование соответствия на оболочке.
$
приобретает ли особое значение, если это последний символ в слове? Там нет единого специального значения, назначенного$
; он используется для введения нескольких, но различных расширений, таких как расширение параметров${...}
, подстановка команд$(...)
и арифметические выражения$((...))
. В некоторых оболочках вводятся дополнительные контексты, такие какksh
вариант подстановки командx=${ echo foo; echo bar;}
(который отличается от стандартного$(...)
тем, что не выполняет команды в подоболочке).