First, the things I like in this script:
- Good use of the shell options to find simple mistakes. That's the first thing I do in my shell scripts.
- Good error reporting - correctly using the error stream and exit status
- Good use of quoted strings. You didn't miss the tricky one in
$(basename "$0")
.
- Everything is laid out well - it's clear and easy to read.
The observations I have are generally quite minor.
I don't see why we have two separate commands here:
set -o nounset; set -o errexit
It's simpler to write
set -o nounset -o errexit
We're using an undefined conversion here:
printf >&2 '%b\n' "$@"
%b
isn't among the conversions specified by POSIX. I think that %s
should be fine here, if we change the single use of \n
into a separate string argument (and this neatly fixes an obscure bug if the command file-name contains \
):
error "Usage of $(basename "$0") script:" \
'' \
'Starts a root shell, no argument accepted.'
is_root
and start_root_shell
each contain a single command and are used just once, so the benefit of using functions is debatable. I'd lean towards inlining them, perhaps with a comment.
Modified version
The only change I'd insist upon if accepting this code would be to use a specified, portable conversion in the printf
. The rest is just style.
#!/bin/sh
set -o nounset -o errexit
error()
{
printf >&2 '%s\n' "$@"
exit 1
}
if [ "$#" -gt 0 ]
then
error "Usage of $(basename "$0") script:" \
'' \
'Starts a root shell, no argument accepted.'
fi
if [ "$(id -u)" -eq 0 ]
then
error 'You are already superuser!'
fi
# Start the root shell
exec sudo -s