Why does shell builtin colon command ":" after variable assignment on same line cause empty string value to be assigned? Why does shell builtin colon command ":" after variable assignment on same line cause empty string value to be assigned? shell shell

Why does shell builtin colon command ":" after variable assignment on same line cause empty string value to be assigned?


: 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:

  • running the command :
  • passing arguments colon, comment and here (these are dropped by the command)
  • with the temporary variable assignment 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