A contrived example… given
FOO="/foo/bar/baz"
this works (in bash)
BAR=$(basename $FOO) # result is BAR="baz"
BAZ=${BAR:0:1} # result is BAZ="b"
this doesn’t
BAZ=${$(basename $FOO):0:1} # result is bad substitution
My question is which rule causes this [subshell substitution] to evaluate incorrectly? And what is the correct way, if any, to do this in 1 hop?
First off, note that when you say this:
the first bit in the construct for
BAZisBARand not the value that you want to take the first character of. So even if bash allowed variable names to contain arbitrary characters your result in the second expression wouldn’t be what you want.However, as to the rule that’s preventing this, allow me to quote from the bash man page:
Then a bit later:
And later when it defines the syntax you’re asking about:
So the rules as articulated in the manpage say that the
${foo:x:y}construct must have a parameter as the first part, and that a parameter can only be a name, a number, or one of the few special parameter characters.$(basename $FOO)is not one of the allowed possibilities for a parameter.As for a way to do this in one assignment, use a pipe to other commands as mentioned in other responses.