How to list all non-environment variables in bash?
GNU Parallel includes env_parallel
. Part of env_parallel
lists all variables for the supported shells.
For bash
this code is:
_names_of_VARIABLES() {
compgen -A variable
}
_bodies_of_VARIABLES() {
typeset -p "$@"
}
So given all variables we need to figure out which ones are set by the user. We can do that by hardcoding all variables set by a given version of bash
, but that would not be very future proof, because bash
may set more variables in future versions (Is $BASH_MYVAR
set by the user or by a future version of bash
?).
So instead env_parallel
asks you to define a clean environment, and run env_parallel --session
in that. This will set $PARALLEL_IGNORED_NAMES
by listing the names defined before (using the code above).
When later run in an environment where the user has set variables, it is easy to take the difference between the clean environment and the current environment.
env_parallel --session
makes it possible to define a clean environment for every session, but if you prefer to have a reference environment that can be used across sessions, simply save the list of variables to a file. So:
# In clean envronment
compgen -A variable > ~/.clean-env-vars
# In environment with user defined vars
compgen -A variable | grep -Fxvf ~/.clean-env-vars
For example:
#!/bin/bash
# In clean envronment
compgen -A variable > ~/.clean-env-vars
myvar=4
yourvar=3
# In environment with user defined vars
compgen -A variable | grep -Fxvf ~/.clean-env-vars
# This prints:
# myvar
# yourvar
# PIPESTATUS (which is set when running a pipe)
Add this to your ~/.bashrc
pre () {
set -o posix;set > /tmp/tmp-original-envs
}
post () {
set -o posix;set > /tmp/tmp-new-envs
diff /tmp/tmp-original-envs /tmp/tmp-new-envs | grep -v BASH_LINENO | grep -v FUNCNAME | grep '>'
}
Then run pre
before your modifications and post
afterward
Example:
[localhost]$ pre
[localhost]$ test=new
[localhost]$ post
> test=new
[localhost]$