In a GNU/Linux bash shell, I am using a command to identify and save all my user defined variables at a specific point in time for debugging purposes (I source the file later):

declare | grep '^[[:lower:]]' | grep -v '^colors' | sort > ${output_dir}/env_variables.tmp

I am aware that this is bad practice as I am "programming by coincidence", trusting that all system variables (except colors) will begin with an upper case letter -- I would like to come up with a better way.

I have also considered saving a version of my current env variables before running the script, and then simply differencing the env variables in the child shell with it. This seems as hack-ish as my current attempt, so I was wondering if is there a way to filter variables by date or user defined, or any other criteria to identify those that are newly created by a certain child shell?

2 Answers 2


No, there's no way to filter variables by date or who owned it. You COULD set all existing variables to read-only and then later you use declare -p to filter those out. But a more common way to solve this is to prefix all your vairables with __project_ (where project is whatever). The variables get lengthy, but that seems to be the safest way.

Your idea of saving the variables on startup isn't a bad one at all. You can save just the names with

 declare |awk -F= '/=/ { print $1 }' >tmpfile.$$.shvars

Or back to the read-only idea:

 while read var ; do declare -r var; done < tmpfile.$$.shvars

Now you declare yours and later, when you are done:

 declare -p |awk '$2 !~ /^.r$/ { print $3 }' |cut -d= -f1

gets you the list of your variables. The downside is, all those variables are now read-only that shouldn't be.

  • +1 for the use of the process ID in the name -- did not think of that but is very obvious to do so now. Thanks!
    – mlegge
    Commented May 8, 2015 at 20:48
  • If you're paranoid, you use mktemp :) ... but $$-$PPID is far simpler and statistically sound.
    – Otheus
    Commented May 8, 2015 at 21:10

In shell, when you set a variable (both environment variable or unexported parameters) there is no difference going forward between that new variable and any that were already set before. Hence, (variations on) the two solutions you have thought of, which are:

  • Use a naming convention to describe which ones you are interested in (uppercase vs. lowercase)
  • Take a before & after snapshot

are about as well as you can possibly do.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .