How to run a program in a clean environment in bash?

I want to run a program in an empty environment (i.e. with no envariables set). How to do this in bash?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can do this with env:

env -i your_command

Contrary to comments below, this does completely clear out the environment, but it does not prevent your_command setting new variables. In particular, running a shell will cause the /etc/profile to run, and the shell may have some built in settings also.

You can check this with:

env -i env

i.e. wipe the environment and then print it. The output will be blank.

Method 2

A “clean” bash environment may be had with

$ env -i bash --noprofile --norc
  • The env -i command executes the command given to it on the command line without transferring any of the exported environment variables of the old shell environment to the environment of the executed program.
  • The --noprofile option stops bash from reading the system-wide or personal shell initialization scripts that would otherwise be read for a login shell.
  • The --norc option stops bash from reading the personal shell initialization scripts that would otherwise be read for an interactive shell.

Method 3

env -i somecommand runs a command in an empty environment, as ams has already mentioned.

A lot of programs rely on some important environment variables, so you may want to retain them:

env -i HOME="$HOME" LC_CTYPE="${LC_ALL:-${LC_CTYPE:-$LANG}}" PATH="$PATH" USER="$USER" somecommand

Alternatively, you could log in into a small login-time environment.

ssh localhost somecommand

Method 4

While the accepted answer is correct, what you usually want to do is to:

env -i HOME="$HOME" bash -l -c "printenv; and any other commands"

This gives you bare but functional bash (same as you’d get when login in non-interactive mode). This for example sets the language, timezone, HOME, etc.

Edit: Added HOME="$HOME" based on excellent answer here: https://unix.stackexchange.com/a/451389/100093

Method 5

The problem with most answers here is that env -i clears HOME, so even if you run bash -l on the inside, it won’t read your .bash_profile etc. If what you’re looking for is a shell that acts as if you had just done a fresh login, you’d want this instead:

env -i HOME="$HOME" bash -l -c 'your_command'

Example:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123

Method 6

If you want to ensure a script has a clean environment you can alter the shebang line like this little example illustrates:

#!/usr/bin/env -S -i bash
env

which displays its environment like this

PWD=/home/myuser/mydir
SHLVL=1
_=/usr/bin/env

Here, we run the bash shell through env which takes an -i argument that instructs it to clean the environment. The -S is required when passing multiple arguments on shebang lines.

Method 7

To answer balki’s comment (and answering my own question in the process :-):

% echo Environment in calling shell: vars: $(env |wc -l); echo; ./du; echo; cat du
Environment in calling shell: vars: 43

==> This is the environment: vars: 5
PATH="$PATH"
PWD=/Users/nick
SHLVL=1
SOMETHING_TO_KEEP="$USER"
_=/usr/bin/env
==> The end.

#!/usr/bin/env -i SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh

echo "==> This is the environment: vars:" $(/usr/bin/env | /usr/bin/wc -l)
/usr/bin/env
echo "==> The end."


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x