If I add the colon
(:
) builtin shell command after an assignment, the variable gets assigned to the empty string (""
). Why does it behave like that? I expected it to have no effect.
set -vx
MyVar1='my var 1' : colon comment here # *** !!! This gets assigned to empty string!!!
MyVar2='my var 2' # hash comment here; this is fine
echo "MyVar1 = [$MyVar1]" # EXPECTED: 'my var 1'; ACTUAL: '' (empty string). Why?
echo "MyVar2 = [$MyVar2]" # As expected.
: (a colon)
: [arguments]
Do nothing beyond expanding arguments and performing redirections. The return status is zero.
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html
$# is the number of positional parameters passed to the script, shell, or shell function. This is because, while a shell function is running, the positional parameters are temporarily replaced with the arguments to the function. This lets functions accept and use their own positional parameters.
$$ is the pid (process id) of the shell interpreter running your script. It's different for each process running on a system at the moment, but over time the pid wraps around, and after you exit there will be another process with same pid eventually.As long as you're running, the pid is unique to you.
:
is a built-in command which returns successfully (a shorthand version of true
).
When you do a variable assignment on the same line as a command, the assignment is only valid for the duration of the command (this is typically used to run commands with temporary environment variables set).
So when you run:
MyVar1='my var 1' : colon comment here
You are:
:
colon
, comment
and here
(these are dropped by the command)MyVar1='my var 1'
(this has no effect on the command)This behaviour is described in the spec:
A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.
...
If no command name results, variable assignments shall affect the current execution environment. Otherwise, the variable assignments shall be exported for the execution environment of the command and shall not affect the current execution environment (except for special built-ins).
As pointed out in the comments (thanks!), :
is one of the special built-ins, which means that in a standards-compliant shell, the assignment should affect the current execution environment. By default, Bash doesn't comply with the spec in this sense, although you can make it do so by invoking it as sh
(on systems where it is the default shell) or by using bash --posix
:
$ bash -c 'foo=bar :; echo $foo'
$ sh -c 'foo=bar :; echo $foo'
bar
$ bash --posix -c 'foo=bar :; echo $foo'
bar
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With