Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For some shell sessions I want to be able to print a warning flag if a shell variable is not set and exported.

It is fairly simple to do something like this to print "Error" in the prompt if SET_ME is unset or null.

test_var () { test -z "$1" && echo Error; }
PS1='$(test_var "$SET_ME") \$ '

However this fails to flag if I set SET_ME without exporting it, which is an error that I want to be able to detect. Short of something like $(bash -c 'test -z "$SET_ME" && echo Error;') or grepping the output of export, is there a simple check that I can do to test whether SET_ME has been exported?

A non-POSIX, bash-only solution is completely acceptable.

share|improve this question

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)  =~ " -[aAilrtu]*x[aAilrtu]* " ]] || echo Error
}
share|improve this answer
    
I think that this is what I'm looking for. In theory, the re might need to be more flexible, e.g. if I had a read-only exported variable, but in practice I never use other typeset attributes. – Charles Bailey Jul 19 '12 at 13:36
    
Good point. I'll fix it for posterity. – chepner Jul 19 '12 at 13:40
    
It looks like attempting to quote the regular expression stops it working as a regular expression in bash >= 3.2. – Charles Bailey Jul 19 '12 at 14:14
    
Also there's an inconsistency, -z "$1" assumes I'm passing the value of a variable to test_var (as I was) whereas declare -p expects its name. I came up with this test which takes the name of a shell variable: test_exported_notnull () { re='^declare -\w*x'; [[ -n $(eval echo \$$1) ]] && [[ $(declare -p "$1") =~ $re ]]; } . – Charles Bailey Jul 19 '12 at 14:51
    
To avoid the eval, just add this first line: var=$1, then use [[ -z "${!var}" ]] && echo Error. – chepner Jul 19 '12 at 16:00

If I resign myself to having to use export and grep, the simplest test is probably something like this.

export | grep -Eq '^declare -x SET_ME='

or if I want non-null as well:

export | grep -Eq '^declare -x SET_ME=".+"'
share|improve this answer
    
POSIX 7 says that export is unspecified, and defines a precise format for export -p similar to bash export but different. But bash seems to ignore POSIX and use the same format as export for export -p! – Ciro Santilli 巴拿馬文件 六四事件 法轮功 Oct 16 '14 at 22:37

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.

share|improve this answer

The export command, given without parameters, gives a list of exported names in the current environment:

$ FOO1=test
$ FOO2=test
$ export | grep FOO
$ export FOO2
$ export | grep FOO
declare -x FOO2="test"

Some cutting and sed'ing gets rid of the fluff:

export | cut -d' ' -f 3- | sed s/=.*//

There's your list of exports, ready for further processing.

share|improve this answer
1  
This does work but I was hoping for a lighter answer with fewer implied forks (hence "Short of [...] grepping the output of export") as my planned use is in my prompt. – Charles Bailey Jul 19 '12 at 12:15
    
@CharlesBailey: I see. I came to this by searching the bash manpage for export, and this was the only thing I came up with. No help from the shell escapes either. The export is builtin anyway, but I doubt you can avoid the grep. – DevSolar Jul 19 '12 at 12:26

The simplest method I currently can think of:

[ bash -c ': ${v1?}' 2>/dev/null ]
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .