Unset an environment variable for a single command

BashUnixEnvironment Variables

Bash 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 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

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
) &&
...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionskeptical scientistView Question on Stackoverflow
Solution 1 - BashJB.View Answer on Stackoverflow
Solution 2 - BashqwertzguyView Answer on Stackoverflow
Solution 3 - BashTravisView Answer on Stackoverflow
Solution 4 - BashVonCView Answer on Stackoverflow