In Bash, we can set an environment variable for a single command this way:
FOO=bar somecommand
What if we want to unset a variable for a single command?
In Bash, we can set an environment variable for a single command this way:
FOO=bar somecommand
What if we want to unset a variable for a single command?
Technically, they're not environment variables until someone exports them. But you can at least set them to empty:
FOO= some command
If removing them from the environment is enough, you can use env:
env -u FOO somecommand
(unset FOO; some command). But anyway, I consider empty environment variables to be different from absent environment variables, so I wouldn't use the FOO= some command approach.FOO=bar by itself does not set an environment variable, unless FOO is exported.export isn't particularly visible in the shell in which is was performed. (Of course, you can see the difference with declare -p.) Regardless of how you feel about empty and absent variables, bash doesn't really distinguish between them either, unless you set -u -- and if you do, a lot of standard scripts will break.For anyone intending to run a command with none of their environment variables, you can do so by running:
env -i somecommand
Option -i is: "-i, --ignore-environment: start with an empty environment"
This is tricky when "somecommand" is a shell function.
One-shot environment variable assignments, such as 'FOO' in "FOO=bar cmd", exist only during the invocation of 'cmd'.
However, if 'cmd' happens to be a shell function, then 'FOO' is assigned in the executing shell itself, and that assignment remains until the process exits (unless explicitly unset).
Since this side-effect of "FOO=bar shell_func" is unlikely to be intentional, it should be avoided.
To further illustrates how the FOO= aCommand is dangerous, consider Git 2.26 (Q1 2020), which avoids "FOO= shell_function (unsetting FOO just for one command).
See commit d6509da, commit a7fbf12, commit c7973f2 (26 Dec 2019) by Jonathan Nieder (artagnon).
(Merged by Junio C Hamano -- gitster -- in commit c7372c9, 30 Jan 2020)
fetch test: avoid use of "VAR= cmd" with a shell functionSigned-off-by: Jonathan Nieder
Just like assigning a nonempty value, assigning an empty value to a shell variable when calling a function produces non-portable behavior: in some shells, the assignment lasts for the duration of the function invocation, and in others, it persists after the function returns.
Use an explicit subshell with the
envvarexported to make the behavior consistent across shells and crystal clear.All previous instances of this pattern used "
VAR=value" (with nonemptyvalue), which is already diagnosed automatically by "make test-lint" since a0a630192d (t/check-non-portable-shell: detect "FOO=bar shell_func", 2018-07-13).
For example, instead of:
GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch
Use a subshell:
(
GIT_TEST_PROTOCOL_VERSION= &&
export GIT_TEST_PROTOCOL_VERSION &&
trace_fetch client origin to_fetch
) &&
...