If I do this:
SUMAN_DEBUG=foo echo $SUMAN_DEBUG
I get no output
but if I do:
SUMAN_DEBUG=foo && echo $SUMAN_DEBUG
then I get
"foo"
why is that?
If I do this:
SUMAN_DEBUG=foo echo $SUMAN_DEBUG
I get no output
but if I do:
SUMAN_DEBUG=foo && echo $SUMAN_DEBUG
then I get
"foo"
why is that?
[This answer is not correct. The problem is due to variable expansions occurring before variable assignments on the command line. See comments below. Also, this question was declared a duplicate and there is an excellent discussion in the original question. -gt]
SUMAN_DEBUG=foo
is a local environment variable assignment for a local variable that exists only for the command it prefaces. In your second case, there is no command because the &&
initiates a list of command where in your case, the first command is null (so the environment variable has no command to affect) and the second is executed but has no environment variable set for it.
You could add export
to the assignment so that the variable would become a global environment variable. But then it would persist after the list of commands is complete.
Another option is to put the entire command list in parenthesis to execute it in a subshell:
(export SUMAN_DEBUG=foo && echo $SUMAN_DEBUG)
In this case, the persistent environment variable would be set in a subshell and that environment would disappear when the subshell completed its work).
See the Bourne-again Shell Manual, lists section and the section on Environment for more.
In command line you need to separate commands using either ;
or &&
. Space it is just not a delimiter for CLI commands.
With &&
the second command will be executed if the first command exits successfully (exit code 0).
With ;
the second command will be executed no matter what is the exit status of first command.
Test:
# a1;echo hello
bash: a1: command not found
hello
# a1 && echo hello
bash: a1: command not found
In scripts the first command and the second command is separated by a new line \n
character, also recognized by bash.
export
:(SUMAN_DEBUG=foo && echo $SUMAN_DEBUG)
and keeps it in the scope of the command sequence – groovenectar Mar 27 '19 at 15:30SUMAN_DEBUG=foo
performs an assignment in the scope of the current shell (my terminology may be imprecise here). @groovenectar's answer seems like a way to go. Your solution withexport
is useful if the variable is intended to be referenced from a subshell (e.g. you invoke a script that expects that variable to be set). – tonytony Jul 26 '19 at 09:42echo
being a built-in results in slightly different precedence rules being invoked. – Greg Tarsa Jul 27 '19 at 15:06