На пепел, тире и баш, когда я бегу
$ echo ab$
это возвращается
ab$
Это поведение определяется POSIX или это просто общее соглашение в POSIX-совместимых оболочках? Я не смог найти ничего на странице POSIX Shell Command Language, где упоминается такое поведение.
$
приобретает ли особое значение, если это последний символ в слове? Там нет единого специального значения, назначенного$
; он используется для введения нескольких, но различных расширений, таких как расширение параметров${...}
, подстановка команд$(...)
и арифметические выражения$((...))
. В некоторых оболочках вводятся дополнительные контексты, такие какksh
вариант подстановки командx=${ echo foo; echo bar;}
(который отличается от стандартного$(...)
тем, что не выполняет команды в подоболочке).ab$
нет символа, следующего за$
ним, «следовал» ли он за нулевым символом в исходной входной строке или пробелом в регистре какecho ab$ foo
; Оригинальный пробел без кавычек был распознан и отброшен после анализа.Ответы:
$
сам по себе не имеет специального значения (tryecho $
), только в сочетании с другим символом после него и формированием расширения, например,$var
(или${var}
)$(util)
,,$((1+2))
.$
Получает свой «особенный» , что означает , как определение расширения в стандарте POSIX в разделе Токен распознавания :Итак, если
$
расширение не формируется, вступают в силу другие правила синтаксического анализа:Это охватывает вашу
ab$
строку.В случае одинокого
$
(«новое слово» будет$
само собой):Значение генерируемого слова содержащего ,
$
который не является стандартным расширением явно определяется как определенно с помощью POSIX.Также обратите внимание, что
$
это последний символ$$
, но это также и переменная, которая содержит PID текущей оболочки. Вbash
,!$
может вызвать расширение истории (последний аргумент предыдущей команды). Таким образом, в общем, нет,$
не без значения в конце слова без кавычек, но в конце слова это, по крайней мере, не означает стандартное расширение.источник
В зависимости от конкретной ситуации, это либо явно не определено (так что реализации могут делать, как они будут), либо должно происходить так, как вы заметили. В вашем точном сценарии
echo ab$
, POSIX предписывает вывод «абы $» , что вы наблюдали и это не определенно . Краткое резюме всех различных случаев в конце.Есть два элемента: сначала разбить на слова, а затем интерпретировать эти слова.
токенизации
Токенизация POSIX требует, чтобы a
$
не было началом действительного расширения параметра , подстановки команды или арифметической подстановки, чтобы считаться литеральной частьюWORD
создаваемого токена. Это связано с тем, что правило 5 («Если текущий символ не заключен в кавычки$
или`
, оболочка должна идентифицировать начало любых кандидатов на расширение параметра, замену команды или арифметическое расширение из их вводных последовательностей символов без кавычек:$
или${
,$(
или`
, и$((
, соответственно» ) не применяется, поскольку ни одно из этих расширений не является жизнеспособным. Расширение параметра требует, чтобы там отображалось действительное имя, а пустое имя недопустимо.Поскольку это правило не применимо, мы продолжаем следовать, пока не найдем то, которое применимо. Два кандидата - № 8 («Если предыдущий символ был частью слова, текущий символ должен быть добавлен к этому слову.») И № 10 («Текущий символ используется в качестве начала нового слова».) , которые применяются к
echo a$
иecho $
соответственно.Существует также третий случай формы,
echo a$+b
которая проходит через ту же трещину, поскольку+
это не имя специального параметра. К этому мы вернемся позже, так как он запускает разные части правил.Таким образом, спецификация требует, чтобы
$
синтаксически она считалась частью слова, и затем она может быть дополнительно обработана.Расширение слова
После того, как входные данные были проанализированы таким образом, с
$
включенным в слово, расширения слова применяются к каждому из прочитанных слов. Каждое слово обрабатывается индивидуально .Указано, что :
«Не указано» - это конкретный термин, означающий, что
В вашем примере
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
команде как часть его аргумента. Это требование соответствия на оболочке.источник
echo $
Также будет буквальным и полностью указан?echo "$"
иecho "a b$"
падают?