A 2 line strategy using comm
, compgen -v
and Process Substitution...
ENVVARS="$(compgen -v)"
:
<script>
:
comm -1 -3 <(sort <<< "$ENVVARS") <(compgen -v | sort)
From comm --help
...
Usage: comm [OPTION]... FILE1 FILE2
Compare sorted files FILE1 and FILE2 line by line.
With no options, produce three-column output. Column one contains
lines unique to FILE1, column two contains lines unique to FILE2, and
column three contains lines common to both files.
-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
The comm
command allows us to "subtract" the set of environment variables passed to the script from the total set present at the end of the script to leave us with just those created by the script.
Options -1 and -3 discard all but the variables created in this script (which are lines in "file 2"). Bash Process Substitution <(...)
is used to list and sort the variables and then treat the output as a file.
Note that variables declared local to functions are not included as they are outside the scope of the main script.
The same technique could be used to list variables created inside a function. However, the convention of naming such variables beginning with the underscore (_)
and adding the underscore prefix to the compgen
call in such cases may be more desirable...
LOCALVARS="$(compgen -v _)"
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
.