Can shell variable name include a hyphen or dash (-)?
I've never met a Bourne-style shell that allowed -
in a variable name. Only ASCII letters (of either case), _
and digits are supported, and the first character must not be a digit.
If you have a program that requires an environment variable that doesn't match the shell restrictions, launch it with the env
program.
env 'strange-name=some value' myprogram
Note that some shells (e.g. modern dash, mksh, zsh) remove variables whose name they don't like from the environment. (Shellshock has caused people to be more cautious about environment variable names, so restrictions are likely to become tighter over time, not more permissive.) So if you need to pass a variable whose name contains special character to a program, pass it directly, without a shell in between (env 'strange-name=some value' sh -c'…; myprogram'
may or may not work).
How to create shell variable with dashes?
I've never met a Bourne-style shell that allowed - in a variable name. Only ASCII letters (of either case), _ and digits are supported, and the first character must not be a digit.
If you have a program that requires an environment variable that doesn't match the shell restrictions, launch it with the env program.
env 'strange-name=some value' myprogram
Note that some shells (e.g. modern dash, mksh, zsh) remove variables whose name they don't like from the environment. (Shellshock has caused people to be more cautious about environment variable names, so restrictions are likely to become tighter over time, not more permissive.) So if you need to pass a variable whose name contains special character to a program, pass it directly, without a shell in between (env 'strange-name=some value' sh -c'…; myprogram' may or may not work).
https://unix.stackexchange.com/questions/23659/can-shell-variable-name-include-a-hyphen-or-dash
Why can't environment variables with dashes be accessed in bash 4.1.2?
The "why" is almost irrelevant: The POSIX standard makes it very clear that export
is only required to support arguments which are valid names, and anything with a dash is not a valid name. Thus, no POSIX shell is required to support exporting or expanding variable names with dashes, via indirect expansion or otherwise.
It's worth noting that ShellShock -- a major security bug caused by sloppy handling of environment contents -- is fixed in the bash 4.1 present in the current CentOS 6 updates repo; increased rigor in an area which spawned security bugs should be no surprise.
The remainder of this answer will focus on demonstrating that the new behavior of bash 4.1 is explicitly allowed, or even required, by POSIX -- and thus that the prior behavior was an undefined implementation artifact.
To quote POSIX on environment variables:
These strings have the form name=value; names shall not contain the character '='. For values to be portable across systems conforming to IEEE Std 1003.1-2001, 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 a process' environment has the same name, the consequences are undefined.
Environment variable names used by the utilities in the Shell and Utilities volume of IEEE Std 1003.1-2001 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.
Thus:
- Tools (including the shell) are required to fully support environment variable names with uppercase and lowercase letters, digits (except in the first position), and the underscore.
- Tools (including the shell) may modify their behavior based on environment variables with names that comply with the above and additionally do not contain lowercase letters.
- Tools (including the shell) should tolerate other names -- meaning they shouldn't crash or misbehave in their presence -- but are not required to support them.
Finally, shells are explicitly allowed to discard environment variable names which are not also shell variable names. From the relevant standard:
It is unspecified whether environment variables that were passed to the shell when it was invoked, but were not used to initialize shell variables (see Shell Variables) because they had invalid names, are included in the environment passed to execl() and (if execl() fails as described above) to the new shell.
Moreover, what defines a valid shell name is well-defined:
Name - 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.
Notably, only underscores (not dashes) are considered part of a valid name in a POSIX-compliant shell.
...and the POSIX specification for export
explicitly uses the word "name" (which it defined in the text quoted above), and describes it as applying to "variables" (shell variables, the restrictions on names for which are also subject to restrictions quoted elsewhere in this document):
The shell shall give the export attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands. If the name of a variable is followed by = word, then the value of that variable shall be set to word.
All the above being said -- if your operating system provides a /proc/self/environ
which represents the state of your enviroment variables at process startup (before a shell has, as it's allowed to do, potentially discarded any variables which don't have valid names in shell), you can extract content with invalid names like so:
# using a lower-case name where possible is in line with POSIX guidelines, see above
aws_access_key_id_var="AWS_${BUCKET_NAME}_ACCESS_KEY_ID"
while IFS= read -r -d '' var; do
[[ $var = "$aws_access_key_id_var"=* ]] || continue
val=${var#"${aws_access_key_id_var}="}
break
done </proc/self/environ
echo "Extracted value: $val"
how to declare variable name with - char (dash ) in linux bash script
Rename the variable name as follows:
SM_Read_only="Yes"
SM_write_only="No"
Please, don't use -
minus sign in variable names in bash, please refer to the answer, on how to set the proper variable name in bash.
However if you generate the code, based on others output, you can simply process their output with sed:
RESP=$(getValue SM_ Read-rule,Write-rule 2>${ERR_DEV}|sed "s/-/_/g")
RC=$?
eval "$RESP"
How to include dashes (or other special characters) in string concatenation?
Your code works as expected for me.
You don't even need to put the dash outside the quotes, this works also:
datap1="$var1$var2-$var1"
The case where you need to do something special is if the separator character is allowed as part of a variable name, e.g. underscore. If you write
datap1="$var1$var2_$var1"
it will try to find a variable named var2_
, and it will fail, so nothing will be substituted; the value will be var1var1
. You can put braces around the variable name to delimit it:
datap1="$var1${var2}_$var1"
How to repeat a dash (hyphen) in shell
This throws an error:
$ printf '-%.0s' {1..100}; echo ""
bash: printf: -%: invalid option
printf: usage: printf [-v var] format [arguments]
This works fine under bash
:
$ printf -- '-%.0s' {1..100}; echo ""
----------------------------------------------------------------------------------------------------
For other shells, try:
printf -- '-%.0s' $(seq 100); echo ""
The problem was the printf
expects that -
starts an option. As is common among Unix/POSIX utilities in this type of situation, --
signals to printf
to expect no more options.
What is a hyphen beside a shell variable
It's all explained in the Shell Parameter Expansion section of the manual:
${parameter:-word}
If
parameter
is unset or null, the expansion ofword
is substituted. Otherwise, the value ofparameter
is substituted.
Just before this there is:
Omitting the colon results in a test only for a parameter that is unset.
So:
${X-stuff}
expands to:
- The expansion of
$X
ifX
is set stuff
ifX
is unset.
Try it:
$ unset X
$ echo "${X-stuff}"
stuff
$ X=
$ echo "${X-stuff}"
$ X=hello
$ echo "${X-stuff}"
hello
$
Now your expansion is
${X-}
so you guess that it expands to the expansion of $X
if X
is set, and to the null string if X
is unset.
Why would you want to do this? to me it seems that this is a workaround the set -u
:
$ set -u
$ unset X
$ echo "$X"
bash: X: unbound variable
$ echo "${X-}"
$
Finally, your test
if [ -z "${X-}" ]
(note the quotes, they are mandatory) tests whether X
is nil (regardless of X
being set or not, even if set -u
is used).
Name variable from string in Dash
The only way to do this in dash
is to use eval
, but that is risky unless you know that your string is a valid identifier.
expr "$var" : '[_[:alpha:]][_[:alnum:]]\{0,\}$' && eval "$var=$value"
The call to expr
fails (or at least, is intended to fail) if the value of var
is anything other than a single valid identifier.
Related Topics
Random Alphanumeric String Linux Swift 3
Sed: Find Pattern Over Two Lines, Not Replace After That Pattern
Ada Compiler Crashes with "Ada Compiler Not Installed on This System." After Downgrading Gcc Version
Bash - Concatenating Variable on to Path
How to Run Ionic in the Background
Raspberry Pi Refusing Connection to Bottle Server
Undefined Reference to 'Pthread_Init' When Using -Lpthread Flag:
Serialport in Mono in Linux Not Responding to Datareceived Event
How to Identify the User Who Owns a Process from /Proc/Pid
Cuda 5.0: Replacement for Cutil.H
Python3 Unicodeencodeerror When Run via Synology Task Scheduler
Ha Proxy Simple Forwarding with Docker
How to Run a Cron Job at Every 5 Hour Interval
Sending Mail Body and Attachment Using Mailx - Linux
Reading Input from Keyboard with X64 Linux Syscalls (Assembly)
Syntax Error of ";; Unexpected" on Simple Init Script for Debian