Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to test if current user one of two allowed users to start a process, but I can't seem to get the multi-condition to work correctly:

test ($(whoami) != 'mpurcell' || $(whoami) != 'root')) && (echo "Cannot start script as non-ccast user..."; exit 1)

Is there a way to test multiple users without have to enter two lines, like this:

test $(whoami) != 'mpurcell' && (echo "Cannot start script as non-ccast user..."; exit 1)
test $(whoami) != 'root' && (echo "Cannot start script as non-ccast user..."; exit 1)
share|improve this question
add comment

3 Answers

up vote 4 down vote accepted

bash 3.x and above have a regular expression match operator =~ available in the [[ operator

if [[ ! "$(whoami)" =~ ^(mpurcell|root)$ ]]
then
    echo "Go away" >&2
    exit 1
fi

etc...

I was reading that quoting rules on the regular expression changed in bash 3.2 or so. The above works on my 3.2.25, you may need to quote it if your bash is older.

share|improve this answer
    
Nice solution. Worked well, thank you. –  Mike Purcell Jun 8 '12 at 23:22
    
You should use ^(mpurcell|root)$ to avoid matching e.g. jethrootis. Also, you can do the negation with [[ ! "$(whoami)" =~ ^(mpurcell|root)$ ]] –  Gordon Davisson Jun 9 '12 at 3:28
    
@GordonDavisson thanks, my answer updated. –  Rich Homolka Jun 11 '12 at 3:48
add comment

test is just a command, so its expression is parsed just like the arguments to any other command -- meaning that parentheses, pipes, etc must be escaped or quoted to work (and to avoid trouble with this, test uses -o instead of ||). If you're actually using bash, it has a [[ ]] test expression that avoids these parsing oddities.

Also, your expression logic is off. You report the error if the current user isn't mpurcell or isn't root; since the current user can't be both, it'll always error out. I'm pretty sure you want an and there.

Finally, since you have the echo ...; exit 1 part in parentheses, it'll be executed in a subshell, and hence the exit command will exit the subshell, not the script. To avoid this, use { ... } instead of parentheses.

Here's a bash version:

[[ $(whoami) != 'mpurcell' && $(whoami) != 'root' ]] && { echo "Cannot start script as non-ccast user..."; exit 1; }

And here's a version that should work in a generic POSIX shell:

test "$(whoami)" != 'mpurcell' -a "$(whoami)" \!= 'root' && { echo "Cannot start script as non-ccast user..."; exit 1; }
share|improve this answer
    
+1 for clarification, I opted to go with Rich's solution only because I have to call whoami once. –  Mike Purcell Jun 8 '12 at 23:23
add comment

Try: [ $(whoami) != 'mpurcell' -a $(whoami) != 'root' ] && (echo "Cannot start script as non-ccast user..."; exit 1)

share|improve this answer
    
Thanks for the response, I opted to go with Rich's response. –  Mike Purcell Jun 8 '12 at 23:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.