Here are some workarounds:
$ comm -3 <(declare | sort) <(declare -f | sort)
breakdown:
declare
prints every defined variable (exported or not) and function.
declare -f
prints only functions.
comm -3
will remove all lines common to both. In effect this will remove the functions, leaving only the variables.
To only print variables which are not exported:
$ comm -3 <(comm -3 <(declare | sort) <(declare -f | sort)) <(env | sort)
Another workaround:
$ declare -p
This will only print the variables, but with some ugly attributes.
declare -- BASH="/bin/bash"
declare -ir BASHPID=""
declare -A BASH_ALIASES='()'
declare -a BASH_ARGC='()'
...
You can cut the attributes away using... cut:
$ declare -p | cut -d " " -f 3
One downside is that the value of IFS is interpreted instead of displayed.
compare:
$ comm -3 <(declare | sort) <(declare -f | sort)
...
IFS=$' \t\n'
...
$ declare -p | cut -d " " -f 3
...
IFS="
"
...
This makes it quite hard to use that output for further processing, because of that lone "
in one line. Perhaps some IFS-fu can be done to prevent this.
Yet another workaround, using compgen
:
$ compgen -v
The bash builtin compgen
was meant to be used in completion scripts. To this end, compgen -v
lists all defined variables. The downside: it lists only the variable names, not the values.
Here is a hack to also list the values.
$ compgen -v | while read var; do printf "%s=%q\n" "$var" "${!var}"; done
The advantage: it is a pure bash solution. The disadvantage: some values are messed up because of the interpretation through printf
. Also the subshell from the pipe and/or the loop add some extra variables.
_
, which are easy to get rid of:(set -o posix ; set | grep -v ^_)
– hyde Nov 24 '14 at 15:34set -o posix; set | sed -e '/^_/,$d'; set +o posix;
– Scott Apr 06 '15 at 21:52Setting the -o posix setting will affect the rest of your bash shell session, so it's best to do it in a new invocation like so:
bash -c "set -o posix; set | sed -e '/^_/,\$d';"
Or if you want to alias it to a new command, for instance "printset", then put this in your ~/.bashrc or ~/.bash_profile:
alias printset="bash -c \"set -o posix; set | sed -e '/^_/,\\\$d';\""
Then you can just run something like
– Scott Apr 06 '15 at 22:07printset | grep PATH
for instance(set -o posix; set)
. Without the brackets the behavior of the current Bash shell would be changed to match the Posix standard. (Dunno what that means but looks important.) With the brackets, the Bash remains unchanged. – John Red Sep 29 '16 at 09:37(POSIXLY_CORRECT= set)
– Nicolas Melay Apr 07 '18 at 13:28POSIXLY_CORRECT=y
and addsposix
to$SHELLOPTS
– Tom Hale Apr 16 '18 at 08:18