Прежде всего, обратите внимание, что когда вы говорите это:
BAR=$(basename $FOO) # result is BAR="baz"
BAZ=${BAR:0:1} # result is BAZ="b"
, первый бит в конструкции для BAZ
равен BAR
, а не значение , которое вы хотитевзять первый символ.Поэтому, даже если bash разрешил именам переменных содержать произвольные символы, ваш результат во втором выражении не будет тем, что вы хотите.
Однако, что касается правила, которое это предотвращает, позвольте мне процитировать со страницы руководства bash:
DEFINITIONS
The following definitions are used throughout the rest of this docu‐
ment.
blank A space or tab.
word A sequence of characters considered as a single unit by the
shell. Also known as a token.
name A word consisting only of alphanumeric characters and under‐
scores, and beginning with an alphabetic character or an under‐
score. Also referred to as an identifier.
Затем немного позже:
PARAMETERS
A parameter is an entity that stores values. It can be a name, a num‐
ber, or one of the special characters listed below under Special Param‐
eters. A variable is a parameter denoted by a name. A variable has a
value and zero or more attributes. Attributes are assigned using the
declare builtin command (see declare below in SHELL BUILTIN COMMANDS).
И позже, когда он определяет синтаксис, о котором вы спрашиваете:
${parameter:offset:length}
Substring Expansion. Expands to up to length characters of
parameter starting at the character specified by offset.
Итак, правила какв man-странице сказано, что конструкция ${foo:x:y}
должна иметь параметр в качестве первой части, и что параметром может быть только имя, число или один из немногих символов специальных параметров.$(basename $FOO)
не является одной из разрешенных возможностей для параметра.
Что касается способа сделать это в одном назначении, используйте конвейер для других команд, как упомянуто в других ответах.