StevieD
StevieD

Reputation: 7433

Prevent bash variables from polluting environment

I have a script that compiles a .bashrc file. It tests if certain commands are available. It generates variables like so:

command -v cheat 2>&1 >/dev/null
HAS_CHEAT=$?

command -v git 2>&1 >/dev/null
HAS_GIT=$?

Other files in the script will take or not take certain actions if these variables are set.

The problem I'm having is that after .bashrc is loaded, my environment is polluted with these variables. I'd like to not have to unset each and every variable manually. Wondering if there is a better way to do it.

Upvotes: 1

Views: 556

Answers (3)

Mike Holt
Mike Holt

Reputation: 4602

Just to add another possible way of doing things, you could use an associative array, which would keep everything in one place and prevent littering the namespace with a bunch of separate variables.

declare -A HAS=()

command -v cheat 2>&1 >/dev/null
HAS[CHEAT]=$?

command -v git 2>&1 >/dev/null
HAS[GIT]=$?

Then later on when you're done using these values, you can just unset the whole array:

unset HAS

Upvotes: 0

Socowi
Socowi

Reputation: 27205

You can encapsulate your variables inside a function and declare them as local:

main() {
  command -v git 2>&1 >/dev/null
  local HAS_GIT=$?
}
main

In your case you probably don't need these variables at all. If you have one if, you can write:

if command -v git 2>&1 >/dev/null; then
  # case in which you have git
else
  # case in which you don't have git
fi

If you need the status code at multiple locations I would call the same command multiple times. This may be a bit slower but bash isn't that fast to begin with. Also, I find if command way cleaner than if [ "$var" = 0 ].

has() {
   command -v "$@" 2>&1 >/dev/null
}

if has git; then
  # case in which you have git
fi
# lots of code
if ! has git; then
  # case in which you don't have git
fi

Upvotes: 4

Gordon Davisson
Gordon Davisson

Reputation: 125728

Give the variables a unique prefix (like "HAS_" in the above), and then at the end run this:

unset "${!HAS_@}"

This form of indirect expansion (with the ! and @) gives a list of variables with names that start with the specified prefix.

Note: I don't think this'll work in any shell other than bash.

Upvotes: 5

Related Questions