3

I know that I can pass an env variable to a command by prepending it like this:

env_variable=value command

but today I accidentally put && between the variable and the command:

env_variable=value && command exactly
                    ^
                    ^

and I got curious how is it different to the correct way. I know that you can use && to chain commands together. But what's interesting is that the command didn't receive the variable, why? I'd be grateful if anyone explained how exactly the second variant is different from the first one and why the command didn't see the variable. Thanks

2
  • They're different syntaxes that do different things, both documented in the fine manual. This is like wondering which of a += 2 or a *= 2 is the "correct" one.
    – user313992
    Commented Feb 19, 2020 at 18:57
  • 1
    rekated unix.stackexchange.com/q/97302/72456 Commented Feb 19, 2020 at 19:29

2 Answers 2

6
foo=bar && somecmd

is pretty much the same as (since the assignment isn't likely to fail)

foo=bar; somecmd

which is the same as (on separate lines)

foo=bar
somecmd

which is the assignment of a shell variable called foo, and then running a command somecmd. If foo is not exported (shell variables aren't by default), then it's not presented in the environment of somecmd. But you could use within the same shell.

See, e.g.

1
  • though note that if the assignment involved a command substitution, i.e. foo=$(somecmd) && othercmd, then it would be the success or failure of somecmd that the && would test.
    – ilkkachu
    Commented Jul 19, 2022 at 18:19
2

You can chain commands in one line via && such that they are executed sequentially - provided that all previous commands run successfully. Each runs in the shell as-is and doesn't modify the shell. Thus each gets the environment variables from the shell it is running in.

$ LC_ALL=C && commandB

--> execute LC_ALL=C, and if it returns 0 to shell, then execute commandB (with default shell environment)

$ LC_ALL=C commandA

--> set variable LC_ALL to C and execute commandA with these changes to the environment (effectively making this one command)

6
  • thanks, I know that all, my question is different. updated the question Commented Feb 19, 2020 at 16:50
  • (s)he answered your question. if you use && the command will not "see" the env var. If you don't it will.
    – schaiba
    Commented Feb 19, 2020 at 16:53
  • @schaiba, if you use && the command will not "see" the env var, yeah, I noticed that, that's why I'm asking this question, I want to know why Commented Feb 19, 2020 at 16:57
  • 1
    Because, as answered, "Each runs in the shell as-is and doesn't modify the shell. Thus each gets the environment variables from the shell it is running in." In other words, per the example above, LC_ALL=C will run in one shell, while commandB will run in the other, each one with its own env vars.
    – schaiba
    Commented Feb 19, 2020 at 17:02
  • 3
    It's not strictly to do with subshells. The two commands either side of && are set up and executed as different processes (unless, as in this case, one is a built-in). The specific case here is (from the GNU Bash guide) ::: The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described in Shell Parameters. These assignment statements affect only the environment seen by that command. Commented Feb 19, 2020 at 18:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .