I want to run a program in an empty environment (i.e. with no envariables set). How to do this in bash?
-
1Possibly related: How to get a clean environment in a ksh shell – rahmu Sep 25 '12 at 09:14
7 Answers
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.
-
4It doesn't completely clear out the environment:
echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.sh
prints/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
. – l0b0 Sep 24 '12 at 14:14 -
3However, it seems this is the closest you can get - It seems like variables like
PATH
,PWD
andSHLVL
are set automatically by Bash. +1. – l0b0 Sep 24 '12 at 14:31 -
3
-
5The PATH variable in the first commenter's script is not in the environment and therefore is not an environment variable. Bash apparently sets its own regular shell variable called PATH if there isn't one exported for it:
env -i bash --norc -c "declare -p PATH"
givesdeclare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
. Note the "-x" for exported (and therefore part of the environment) if you export it yourself:env -i bash --norc -c "export PATH; declare -p PATH"
givesdeclare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
– Binary Phile Jun 22 '18 at 18:42
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 stopsbash
from reading the system-wide or personal shell initialization scripts that would otherwise be read for a login shell.The
--norc
option stopsbash
from reading the personal shell initialization scripts that would otherwise be read for an interactive shell.

- 333,661
-
-
@PauloCarvalho Your system does not support
env -i
? What system are you on? – Kusalananda Jan 23 '18 at 10:13 -
Sorry, it works in the shell. I tried to put it in a script and somehow it threw an error. – Paulo Carvalho Feb 15 '18 at 09:56
-
@PauloCarvalho Sorry, I can't see what command you typed in or what the error you got was. – Kusalananda Feb 15 '18 at 10:05
-
Great - just what I was looking for.
env
to clean my environment, and--noprofile
to avoid sourcing /etc/profile and friends, and--norc
to avoid sourcing ~/.bashrc and friends. – Felipe Alvarez Mar 01 '18 at 00:01 -
In this case, even "standard" environment variables like
HOME
andUSER
are not set. Is there a way to do this without losing those variables? – codeforester Mar 15 '20 at 18:27
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

- 829,060
-
1Works when running the command on cmdline. How do I put this in shebang?, doesn't seem to work! – balki Nov 04 '13 at 17:16
-
Strange, my
env
doesn't support--
delimitation and doingenv -i FOO=bar -- env
attempts to run a command named--
. – antak Jul 27 '16 at 02:16 -
@antak That should be
env -i -- FOO=bar env
, actually. My bad. Not that the--
is useful since what follows it does not start with-
. – Gilles 'SO- stop being evil' Jul 27 '16 at 08:10 -
Didn't realize you could always ssh into localhost, that's kinda weird. What's the use case there. – c-o-d Mar 12 '17 at 16:04
-
@EdgarAroutiounian You can SSH to localhost if it's running an SSH server. Why would programmers go through the effort of forbidding it? – Gilles 'SO- stop being evil' Mar 12 '17 at 20:26
-
@EdgarAroutiounian an example use-case would be having a 'vanilla' environment set from the user's standard login environment, then within a script later being forced to make unknown changes to the running environment to accomodate required software (think system
module
s), then needing to return to the user's original environment. Instead of trying to parseenv
, it may be easier to justssh $USER@knownlocalhost somecommand
– user5359531 Jun 12 '17 at 23:05
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
-
1That doesn't quite work because
env -i
clearsHOME
, which meansbash -l
can't find your.bash_profile
etc. If you want a shell that's like what you'd get on a fresh login, you need an extra indirection to setHOME
first. – Elliott Slaughter Jun 22 '18 at 20:29 -
1See this answer: https://unix.stackexchange.com/a/451389/157340 – Elliott Slaughter Jun 22 '18 at 20:46
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
-
2Note that a login
bash
shell will run.bash_login
or.bash_profile
. To get a clean environment, use--noprofile
, or setHOME
to a directory that does not have those files. I suppose it depends on what you mean by "clean". – Kusalananda Jun 22 '18 at 20:43 -
1Yes, if you want a shell with literally nothing in it, just follow the original answer and do
env -i bash -c ...
. This answer is specifically when you want a shell that looks like you just did a fresh login on the machine. – Elliott Slaughter Jun 22 '18 at 20:46
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.

- 7,442
-
This works on bash 5.0.3 on my Debian 10.4 box, but RHEL 7.7 uses 4.2.46(2)-release and it doesn't work the same on bash 4. – JohnGH Jun 19 '20 at 23:25
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."

- 370
-
When I try this in my shebang line in CentOS 7.6, I get this error from env:
/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
– ScottJ Mar 05 '19 at 23:51 -
If I change the script to use the long argument
--ignore-environment
then I get this:/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
– ScottJ Mar 05 '19 at 23:53