The id
utility, when used with its -u
option, will output the UID of the current user. If that UID is zero, then the user is the root user. Only the root user should add new users.
Therefore, the script tests the UID of the user running the script agains zero and only performs the privileged actions (not shown in the script in the question) if the user is root.
An arguably better way to handle this in the script, if the whole script requires root, is to check whether the UID is non-zero at the start and exit with an error if it is:
if [ "$(id -u)" -ne 0 ]; then
echo 'You are not root. Try again with sudo.' >&2
exit 1
fi
As for the $?
, it's a special shell variable that always contains the exit status of the most recently executed command. It is very rare to need to use this directly, as if
is more than capable of working directly with grep
:
if grep -q "^$username" /etc/passwd; then
printf 'User "%s" already exists\n' "$username" >&2
exit 1
fi
Here, if
will use the exit status of grep
. We use grep
with -q
to stop it from producing any output and from parsing the whole file past any first match. It just returns an exit status that if
will use. We also don't need egrep
as the regular expression is not an extended regular expression (egrep
is identical to grep -E
).
Note also that diagnostic messages should be written to the standard error stream. You may do this by redirecting your messages with >&2
. Also, printf
is preferred over echo
when outputting variable data.
If you are on a system where a directory service such as NIS or LDAP is used, grepping for an existing user in /etc/passwd
may not be useful as the actual users may well be stored in a separate database.
On such systems, it may be better to use getent passwd "$username"
(this would work on non-NIS/LDAP systems too). This would return the password database entry for the particular user, or exit with a non-zero exit status, which means we could use that in our test:
if getent passwd "$username" >/dev/null; then
printf 'User "%s" already exists\n' "$username" >&2
exit 1
fi
Just note that useradd
can't add users to a NIS or LDAP database...
Although, strictly speaking nothing of the above should really be needed as useradd
should not do anything useful if the current user is not root or if the user being added already exists.
$?
looking for the exit status ofegrep
? Zero meaningegrep
matched a user, triggering '$username exists!`? – Gee_k Mar 27 '19 at 06:54