Sanitize environment with command or bash script?

Solution 1:

You can use env and a wrapper script:

#!/bin/bash
env -i /path/to/main_script.sh

From man env:

   -i, --ignore-environment
          start with an empty environment

You can also, of course, just run the script as env -i script.sh if you are running it by hand. Unfortunately as far as I can tell one can't use the script shebang to run bash through env like this; the shebang can only accept two parameters by definition as parsed by the kernel.

The other semi-reliable solution using env or exec -c (which does pretty much the same) that I can think of would be to use exec -c $0 to re-run the script with a clean environment if you detect it's not clean. Assuming $HOME is set in an unclean environment and is not set in a clean one (that's true in my install):

#!/bin/bash
[ "$HOME" != "" ] && exec -c $0
# rest of the script here

Solution 2:

Unset all environment variables bash linux

Command: env -i bash

Example, create local and environment variables, then reset to defaults:

el@defiant ~$ LOCAL_DOGE="such variable"
el@defiant ~$ ENVIRONMENT_DOGE="much code"
el@defiant ~$ export ENVIRONMENT_DOGE
el@defiant ~$ set | grep DOGE
ENVIRONMENT_DOGE='much code'
LOCAL_DOGE='such variable'
el@defiant ~$ env | grep DOGE
ENVIRONMENT_DOGE=much code
el@defiant ~$ env -i bash
el@defiant ~$ set | grep DOGE
el@defiant ~$ env | grep DOGE
el@defiant ~$

So wow, LOCAL_DOGE and ENVIRONMENT_DOGE are gone with one command.

Unset all environment variables bash linux, alternate way.

env - /bin/bash

Example:

el@defiant ~$ DOGE1="one"
el@defiant ~$ export DOGE2="two"
el@defiant ~$ set | grep DOGE
DOGE1=one
DOGE2=two
el@defiant ~$ env | grep DOGE
DOGE2=two
el@defiant ~$ env - /bin/bash
el@defiant ~$ set | grep DOGE
el@defiant ~$ env | grep DOGE

Solution 3:

This worked when I tried it:

for c in $(set | cut -d '=' -f 1); do unset $c; done

It spewed errors on the const variables, but I was able to ignore them.

Solution 4:

Here is a way to do this without starting a new shell, and that will work even with weird variable names (containing whitespace/newlines):

while IFS='=' read -rd '' name value ; do unset "$name" ; done < /proc/self/environ

The disadvantage is that it is Linux-specific, and relies on procfs being mounted.

This will unset all environment variables, even HOME and PATH. This may or may not be what you want.

Explanation: /proc/PID/environ contains the process's environment block, as a series of zero-delimited NAME=VALUE strings. We use a read loop, setting the field separator IFS to = so that we can split the name and value from each string. By setting the line delimiter (-d) to an empty string, we cause read to use the null character (the "first" character of a null-terminated string) to split lines. Then, just unset each name in turn (taking care to quote it).