Unset an environment 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?
Solution 1:
Technically, they're not environment variables until someone export
s 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
Solution 2:
env -u FOO somecommand
This will remove the environment variable FOO
from the somecommand
process' environment.
And to unset multiple variables:
env -u FOO -u FOO2 somecommand
Solution 3:
For anyone intending to run a command with none of their environment variables, you can do so by running:
env -i somecommand
Solution 4:
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
envvar
exported 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
) &&
...