Unset an environment variable for a single command
BashUnixEnvironment VariablesBash Problem Overview
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?
Bash Solutions
Solution 1 - Bash
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 - Bash
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 - Bash
For anyone intending to run a command with none of their environment variables, you can do so by running:
env -i somecommand
Solution 4 - Bash
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 function
> Signed-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 nonempty value
), 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
) &&
...