It depends on the Bash version, but as of 2024-03
, it is about POSIX overall 1:
...uppercase letters, digits, and the <underscore> ( '_' )...
Example
$ printf '%s\n' "$BASH_VERSION";
5.1.16(1)-release
$ ABC-DEF=1;
ABC-DEF=1: command not found
$ n='ABC_DEF';
$ "$n=1";
ABC_DEF=1: command not found
$ declare ABC-DEF=1;
-bash: declare: `ABC-DEF=1': not a valid identifier
$ declare 'ABC-DEF=1';
-bash: declare: `ABC-DEF=1': not a valid identifier
$ export 'ABC-DEF=1';
-bash: export: `ABC-DEF=1': not a valid identifier
$ n='ABC-DEF';
$ "$n"=1;
ABC-DEF=1: command not found
$ declare -- "$n=1";
-bash: declare: `ABC-DEF=1': not a valid identifier
$ n='ABC_DEF';
$ declare -- "$n"=1;
$ declare -p -- "$n";
declare -- ABC_DEF="1"
$ n='ABC_DEF';
$ declare -- n1='ABC_DEF_1';
$ declare -- "$n"=1;
$ declare -- "$n1"=2;
$ declare -p "$n" "$n1";
declare -- ABC_DEF="1"
declare -- ABC_DEF_1="2"
$ set | grep ABC;
ABC_DEF=1
ABC_DEF_1=2
_=ABC_DEF_1
n=ABC_DEF
n1=ABC_DEF_1
References
1 POSIX.1-2017
(i.e. IEEE Std 1003.1-2017
)
...
These strings have the form name=value; names shall not contain
the character '='. For values to be portable across systems conforming
to POSIX.1-2017, the value shall be composed of characters from the
portable character set (except NUL and as indicated below). There is
no meaning associated with the order of strings in the environment. If
more than one string in an environment of a process has the same name,
the consequences are undefined.
Environment variable names used by the utilities in the Shell and
Utilities volume of POSIX.1-2017 consist solely of uppercase letters,
digits, and the <underscore> ( '_' ) from the characters defined in
Portable Character Set and do not begin with a digit. Other characters
may be permitted by an implementation; applications shall tolerate the
presence of such names. Uppercase and lowercase letters shall retain
their unique identities and shall not be folded together. The name
space of environment variable names containing lowercase letters is
reserved for applications. Applications can define any environment
variables with names from this name space without modifying the
behavior of the standard utilities. Note: Other applications may have
difficulty dealing with environment variable names that start with a
digit. For this reason, use of such names is not recommended anywhere.
...
Source
Related
${this-that}
POSIXly means "the value of variablethis
if it is set, and if it is not set the actual stringthat
". This long-standard and very widely-used form couldn't work if a varname can include hyphen. – dave_thompson_085 Mar 16 '24 at 23:16