Как bash знает, где заканчиваются имена переменных?

Учитывая:

myvar=Hello
  • echo $myvar → Показывает Hello (до сих пор).
  • echo $myvar#world → показывает Hello#world (почему? Я думал, что будет жаловаться, что здесь нет такой переменной, называемой myvar#world)
  • echo ${myvar#world} → показывает только Hello (опять же, почему?)

Ответы

Ответ 1

Второй случай разбивается на три части:

[echo] [$myvar][#world]
 1      2       3

Часть 1 - это команда, часть 2 - это параметр, а часть 3 - строковый литерал. Параметр останавливается на r, так как # не может быть частью имени переменной (# недопустимы в именах переменных.)

Синтаксический анализатор оболочки распознает начало имени параметра с помощью $, а конец - любым символом, который не может быть частью имени переменной. Обычно в имени переменной допускаются только буквы, цифры и символы подчеркивания, все остальное сообщает оболочке, что вы закончили с указанием имени переменной.

Все они распечатывают $myvar, а затем шесть буквенных символов:

echo $myvar world
echo $myvar?world
echo $myvar#world

Если вы хотите поместить символы, которые могут быть частью параметра непосредственно после параметра, вы можете включить фигурные скобки вокруг имени параметра, например:

myvar=hello
echo ${myvar}world

который печатает:

helloworld

Ваш третий случай - удаление подстроки, за исключением без соответствия. Чтобы заставить его сделать что-то интересное, попробуйте это вместо:

myvar="Hello World"
echo ${myvar#Hello }

который просто печатает World.

Ответ 2

переменные не могут содержать "#", поэтому оболочка знает, что она не является частью переменной.

Конструкция ${myvar # world} фактически является строковым манипулятором, описанным ниже:

# является действующим модификатором строки, который удаляет первую часть строки, соответствующую "миру". Поскольку в myvar нет мира, совместимого со строками, это просто эхо обратно "привет"