What is the simplest scriptable way to check whether a shell variable is exported?

Solution 1:

Use the declare command and the regular expression matching operator:

test_var () {
    # $1 - name of a shell variable
    var=$1
    [[ -z "${!var}" ]] && echo Error
    [[ $(declare -p $1)  =~ ^declare\ -[aAilrtu]*x[aAilrtu]*\  ]] || echo Error
}

Solution 2:

In Bash 4.4 or later, you can use the ${parameter@a} shell parameter expansion to get a list of attributes about a parameter, including if it is exported.

Here is a simple function demonstrating ${parameter@a}, that will tell you if a given variable is exported, given its name:

function is_exported {
    local name="$1"
    if [[ "${!name@a}" == *x* ]]; then
        echo "Yes - '$name' is exported."
    else
        echo "No - '$name' is not exported."
    fi
}

Example of use:

$ is_exported PATH
Yes - 'PATH' is exported.
$ foo=1 is_exported foo
Yes - 'abc' is exported.
$ bar=1; is_exported bar
No - 'abc' is not exported.
$ export baz=1; is_exported baz
Yes - 'baz' is exported.
$ export -n baz; is_exported baz
No - 'baz' is not exported.
$ declare -x qux=3; is_exported qux
Yes - 'qux' is exported.

How it works:

The format returned by ${parameter@a} is one character per attribute, with the meaning of each attribute character coming from the corresponding options from the declare command - in this case, we want to look for x - exported.

Solution 3:

I'm aware the question is 3 years old, however one may find following solution simpler:

[ "$(bash -c 'echo ${variable}')" ]

answers, if the variable is exported and has non-empty value.

Solution 4:

You can use compgen with its -X option to determine if a variable is exported:

compgen -e -X "!$MAY_BE_EXPORTED_VARIABLE"

E.g.:

$ NOT_EXPORTED="xxx"
$ compgen -e -X '!SHELL'
SHELL
$ compgen -e -X '!NOT_EXPORTED'
$ echo $?
1