Ответ 1
Прежде всего, обратите внимание, что, когда вы это говорите:
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.
Таким образом, правила, сформулированные в manpage, говорят о том, что конструктор ${foo:x:y}
должен иметь параметр в качестве первой части и что параметр может быть только именем, числом или одним из нескольких символов специальных параметров. $(basename $FOO)
не является одной из разрешенных возможностей для параметра.
Что касается способа сделать это в одном задании, используйте канал для других команд, как указано в других ответах.