4

My shell script is as shown below:

#!/bin/bash

# Make sure only root can run our script
[ $EUID -ne 0 ] && (echo "This script must be run as root" 1>&2) || (exit 1)

# other script continues here...

When I run above script with non-root user, it prints message "This script..." but it doe not exit there, it continues with the remaining script. What am I doing wrong?

Note: I don't want to use if condition.

3 Answers 3

5

You're running echo and exit in subshells. The exit call will only leave that subshell, which is a bit pointless.

Try with:

#! /bin/sh
if [ $EUID -ne 0 ] ; then
    echo "This script must be run as root" 1>&2
    exit 1
fi
echo hello

If for some reason you don't want an if condition, just use:

#! /bin/sh
[ $EUID -ne 0 ] && echo "This script must be run as root" 1>&2 && exit 1
echo hello

Note: no () and fixed boolean condition. Warning: if echo fails, that test will also fail to exit. The if version is safer (and more readable, easier to maintain IMO).

Sign up to request clarification or add additional context in comments.

5 Comments

Edited, although I don't understand why you'd want to avoid the if.
@Mat, at least with bash, the return value of echo is always 0.
@paxdiablo: POSIX allows echo to fail. Not sure how/when though, and that's not something I'd worry about too much - not sure what you can do to recover from a failed echo...
POSIX may (it may fail if you're redirecting to a device that fills up), but the bash_builtins man page specifically disallows that. Not that it matters, this shouldn't be happening in one line anyway. I much prefer your multi-line version :-)
Why the $*#% don't you want to use an if? This is exactly what if is for. (You can write an if on one line if you value terseness over legibility.)
1

I think you need && rather than||, since you want to echo and exit (not echo or exit).

In addition (exit 1) will run a sub-shell that exits rather than exiting your current shell.

The following script shows what you need:

#!/bin/bash
[ $1 -ne 0 ] && (echo "This script must be run as root." 1>&2) && exit 1
echo Continuing...

Running this with ./myscript 0 gives you:

Continuing...

while ./myscript 1 gives you:

This script must be run as root.

I believe that's what you were looking for.

Comments

1

I would write that as:

(( $EUID != 0 )) && { echo "This script must be run as root" 1>&2; exit 1; }

Using { } for grouping, which executes in the current shell. Note that the spaces around the braces and the ending semi-colon are required.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.