How do you determine whether shell variables are exported or not?
The most portable way is
export -p lists exported variables. This is usually like
declare -x, if your shell has
Bourne-style shells currently in use should support
export -p, as it is required by POSIX:
When -p is specified, export shall write to the standard output the names and values of all exported variables, in the following format:
"export %s=%s\n", <name>, <value>
if name is set, and:
"export %s\n", <name>
if name is unset.
The standard goes on to explain that the value of the variable is displayed in such a way that usually allows it to be used later on the right-hand side of
= in an assignment. This is to say that it may be quoted. Different shells may display them differently but with the same effect.
export -p works even in shells that have no
declare builtin, like Dash.
$ dash -c 'export -p | grep HOME=' # busybox sh and other ash give the same output. export HOME='/home/ek'
$ posh -c 'export -p | grep HOME=' # ksh93, mksh, lksh, and others give the same output. export HOME=/home/ek
I've piped the output to
grep for compactness but if you don't filter it then you get the full list of your exported variables. From your question, it sounds like that's what you might find most useful.
Some shells, like Bash, use a non-standard format unless explicitly instructed to behave in a POSIX-compliant manner. In Bash
export -p gives the same output as
declare -x by default.
$ bash -c 'export -p | grep HOME=' declare -x HOME="/home/ek"
$ bash -c 'POSIXLY_CORRECT= export -p | grep HOME=' export HOME="/home/ek"
$ bash -c 'set -o posix; export -p | grep HOME=' export HOME="/home/ek"
$ bash --posix -c 'export -p | grep HOME=' export HOME="/home/ek"
$ ln -s /bin/bash sh $ ./sh -c 'export -p | grep HOME=' # Invoking bash as sh also puts it in POSIX mode. export HOME="/home/ek"
Zsh shows a non-standard format even when POSIX compatibility is enabled:
$ zsh -c 'export -p | grep HOME=' typeset -x HOME=/home/ek
$ zsh -c 'emulate -R sh; export -p | grep HOME=' typeset -x HOME=/home/ek
$ ln -s /bin/zsh sh $ ./sh -c 'export -p | grep HOME=' typeset -x HOME=/home/ek
In any case, you can extract portable representations (which may be quoted) by searching for a word followed by
=. This doesn't rely on previous words on the line, so long as they don't immediately precede
=, which they shouldn't. For example:
% export -p | grep -oE '\w+=.*' HOME=/home/ek LANG=en_US.UTF-8 LESSCLOSE='/usr/bin/lesspipe %s %s' ....
Note that not all entries necessarily have
=. This is because variables can be unset but exported. Those entries are filtered out by the
grep command above, which may or may not be what you want.
Most of the time, you just want to inspect the output and so you won't care if the entries are preceded by
typeset -x, or something else. Then just run
I tested those commands on Ubuntu 16.04 LTS with officially packaged versions of each shell.
If you want see if a variable is exported or not, use
$ foo=a bar=b $ export foo $ declare -p foo bar declare -x foo="a" declare -- bar="b"