One line env variable set behavior

14,059

Solution 1

[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.

Solution 2

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.

Share:
14,059

Related videos on Youtube

Alexander Mills
Author by

Alexander Mills

Updated on September 18, 2022

Comments

  • Alexander Mills
    Alexander Mills over 1 year

    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?

  • jordanm
    jordanm over 7 years
    A variable assignment is not a command. The reason for OP's behavior is because the expansion happens before the assignment.
  • Jeremie Bourgeois
    Jeremie Bourgeois about 5 years
    It looks like this also works well without the export: (SUMAN_DEBUG=foo && echo $SUMAN_DEBUG) and keeps it in the scope of the command sequence
  • tonytony
    tonytony almost 5 years
    I'm afraid that's wrong. The first one doesn't work because command arguments are expanded before variable assignment happens. The second one works because SUMAN_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 with export 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).
  • Greg Tarsa
    Greg Tarsa almost 5 years
    My answer is indeed wrong. Thanks for pointing it out. I re-ran my tests and realized that one of these forms sets the variable as a side-effect so that later tests showed it expanding because of leakage between test cases. I am still not satisfied with the generally accepted answer because I routinely pass variables to apps this way and it works. I wonder if echo being a built-in results in slightly different precedence rules being invoked.