You can store the list of variables at the beginning of the script and compare it with the value somewhere during the script. Beware that the output of commands like set
isn't built to be unambiguous: something like set | sed 's/=.*//'
doesn't work with variables whose values contain newlines. (In bash, it actually does for string variables, but not for arrays, and it also displays function code.) I think that the following snippet reliably lists the currently defined variables (in alphabetical order, to boot):
variables=$(tmp=$(declare -p +F); declare () { echo "${2%%=*}"; }; eval "$tmp")
Thus, set initial_variables=…
at the beginning of the script, and compare with the later value. You can use something other than echo
to act on the list directly.
initial_variables=" $(tmp=$(declare -p +F); declare () { echo "${2%%=*}"; }; eval "$tmp") "
…
( tmp=$(declare -p +F)
declare () {
case "$initial_variables" in
*" $2 "*) :;; # this variable was present initially
*) eval "set -- \"\$$2\" \"\$2\""; echo "locally defined $2=$1";;
esac
}
)
typeset
, probably it can do this, but I don't believe there is a posix portable method of doing so. Of course the simple solution is to track the variables you set in your script ... in your script... If your parent shell isbash
, by the way, that would explain all of your unwanted env. some more simple shells will not have this issue - especially if invoked likeenv - script
. – mikeserv Dec 9 '14 at 8:09