The =
symbol is not a metacharacter.
Let's first start with the first mention of variable assignment: Section 3.4 Shell Parameters:
A parameter is an entity that stores values. It can be a name
, a
number [for positional parameters $0
, $1
, etc.], or one of the special characters listed below. A variable is a
parameter denoted by a name
. A variable has a value and zero or more
attributes. [...]
A parameter is set if it has been assigned a value. The null string is
a valid value. Once a variable is set, it may be unset only by using
the unset
builtin command.
A variable may be assigned to by a statement of the form
name=[value]
If value is not given, the variable is assigned the null string. All
values undergo tilde expansion, parameter and variable expansion,
command substitution, arithmetic expansion, and quote removal
(detailed below).
(the text in square bracket is my addition).
And there are no mentions of name
going through any expansions.
By the way, a name
is defined as:
A word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names. Also referred to as an identifier.
If we carry on reading a bit, we get to Section 3.7.1 Simple Command Expansion, where we read:
When a simple command is executed, the shell performs the following
expansions, assignments, and redirections, from left to right.
- The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later
processing.
- The words that are not variable assignments or redirections are expanded (see Shell
Expansions).
If any words remain after expansion, the first word is taken to be the
name of the command and the remaining words are the arguments.
- Redirections are performed as described above (see Redirections).
- The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic
expansion, and quote removal before being assigned to the variable.
And again, only the value undergoes expansions.
Now going through POSIX specs, Section 2.10.2 Shell Grammar Rules mentions:
[Assignment preceding command name]
a. [When the first word]
If the TOKEN does not contain the character '=', rule 1 is applied. Otherwise, 7b shall be applied.
b. [Not the first word]
If the TOKEN contains an unquoted (as determined while applying rule 4 from Token Recognition) character that is not
part of an embedded parameter expansion, command substitution, or
arithmetic expansion construct (as determined while applying rule 5
from Token Recognition):
If the TOKEN begins with '=', then rule 1 shall be applied.
If all the characters in the TOKEN preceding the first such form a valid name (see XBD Name), the token
ASSIGNMENT_WORD shall be returned.
Otherwise, it is unspecified whether rule 1 is applied or ASSIGNMENT_WORD is returned.
c. Otherwise, rule 1 shall be applied.
Assignment to the name within a returned ASSIGNMENT_WORD token shall
occur as specified in Simple Commands.
where a valid name is defined as:
In the shell command language, a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit.