1. Overview

Sometimes, we might want to automate the user creation process without having to interact with the command line.

In this tutorial, we’ll write a robust shell script for automating the user creation process. We’ll make use of the built-in tools that ship with most Linux distributions, building up our script as we progress through the sections of the tutorial. In the end, we’ll have a robust shell script that we can execute either manually or from another program.

2. Setting Up the Automation Script

We’ll start up by performing validation checks such as checking whether the user already exists and assigning a default password if none was provided. Afterward, we’ll go through a few variations on the actual user creation and password assignment.

2.1. Basic Usage

We’ll execute the script from the command line and provide it with the –username and –password arguments. In case of validation errors, we’ll be presented with the script usage message that contains the instructions. Once the script executes successfully, we’ll print out the username and the password.

Let’s begin by creating the script file and writing the usage function:

#!/bin/sh

usage() {
  printf "create-user [-u|--username] <username>\n"
  printf " OPTIONS\n"
  printf "  -u --username\tusername of the new account (required)\n"
  printf "  -p --password\tpassword for the new account (optional)\n"
  printf "  -h --help\tprint this help\n"
  exit 1
}

We’ll call the usage function in case of errors. It’s a UNIX and Linux convention to have the usage function included in our scripts.

2.2. Process Command Options

Now, we need to process the command options. We’ll simply iterate through the arguments using a while loop and assign the values to variables. Afterward, we’ll carry out some sanity checks, and if a password isn’t provided as an argument, we’ll assign a default one.

Let’s process the arguments after the usage function:

while [ "$#" -gt 0 ]; do
  case "$1" in
    -u|--username) username="$2" shift ;;
    -p|--password) password="$2" shift ;;
        -h|--help) usage ;;
                *) usage ;;
  esac
  shift
done

[ -z "$username" ] && usage
[ -z "$password" ] && password=$(uuidgen | cut -d'-' -f1)

If no username was provided, we print out the usage for the script and exit the program with exit code 1. In the case of a missing password, we’ve used the uuidgen command that generates a UUID. In our case, we only need the first eight characters of the generated UUID for the default password.

2.3. Check Whether User Exists

Sometimes, it’s possible that we might have an existing user with the same username as the username argument. Therefore, we’d need to check for the existing user in the user database beforehand. We can use the userdbctl command. We use the userdbctl command to query the user database on a Linux machine.

The userdbctl command returns exit code 1 for users that do not exist in the user database. Otherwise, it will return 0:

userdbctl user "$username" > /dev/null 2>&1
[ "$?" -eq 0 ] && echo "$username already exists" && exit 2

In the above snippet, we run the userdbctl command and check for the exit code it returns. The $? operator contains the exit code of the latest command we execute in the script. In this case, it will contain either a 0 or a 1.

Of course, we can leave this safety check, as the useradd command will fail if the user already exists. However, we need some kind of simple feedback that goes well with our script because useradd will return exit code 9 for a username that already exists.

3. Creating User and Assigning Password

Now that the pre-checks are complete, we’ll move on to creating the actual user. We’ll use the useradd command for user creation. For assigning the password, we’ll show a few variations.

3.1. useradd with -p Option

The useradd command creates a user with the provided username. We can also create the user with a password by supplying the -p or –password option to the useradd command:

$ useradd -m newuser -p strongpassword
$ userdbctl user newuser
User name: newuser
Disposition: regular
Login OK: yes
Password OK: yes
UID: 1004
GID: 1004 (newuser)
Directory: /home/newuser
Storage: classic
Shell: /bin/bash
Passwords: none

The -m flag creates a home directory for the user. Let’s use the above command in our script and provide it with the username and password variables:

useradd -m "$username" -p "$password" > /dev/null 2>&1

3.2. useradd, echo, and passwd Commands

The passwd command creates or changes the password for an existing user account. It takes a username as an argument and presents an interactive prompt for password modification.

Let’s change the password for the newuser that we just created:

$ passwd newuser
Changing password for newuser.
Current password:
New password:
Retype new password:
passwd: password updated successfully

As we can see, the passwd command presents us with an interactive prompt. For that reason, we’ll make use of the echo command alongside passwd to skip the interactive prompt.

The echo command is a utility that takes input from the standard input and prints it to the standard output. We can also pipe echo with other commands to bypass prompts and confirmation messages. Therefore, we can easily automate tasks that involve prompts either in a shell script or in the Linux terminal.

Let’s see it in action:

$ echo -en "strongpassword\nnewpass\nnewpass\n" | passwd newuser
Changing password for newuser.
Current password:
New password:
Retype new password:
passwd: password updated successfully

Here’s what happened:

  • We enabled the escape sequence characters support for the echo command through the -e flag
  • The -n flag disables printing the trailing newline
  • We echo the current password followed by the new and confirmed password
  • Each password is separated by the “\n” character, so they are treated as three separate standard inputs
  • The output from the echo command is piped to the passwd command, which we used to change the password for newuser

Now that we have some idea of how to bypass prompts using echo, we can implement this in our script instead of providing the password to the useradd command:

useradd -m "$username" > /dev/null 2>&1
echo -n "$password\n$password\n" | passwd "$username" /dev/null 2>&1

3.3. useradd, echo, and chpasswd Commands

Alternatively, we can use the chpasswd command to change the password for new users. It performs the same function as passwd.

Let’s see it in action:

$ chpasswd
newuser:secretpasscode

Like passwd, chpasswd will present us with an interactive multi-line prompt. We write the username followed by a colon (:) and the new password. Afterward, we can press CTRL+D to apply the changes. Like passwd, we can also use the echo command to automate this process:

$ echo "newuser:code7654" | chpasswd

Now that we’re familiar with chpasswd, we can use it instead of passwd in our script:

useradd -m "$username"
echo "${username}:${password}" | chpasswd

4. Finishing Touches

Our script is almost complete. Now, we need to write the feedback code that lets a user know that the user is created successfully.

We’ll check for the exit code of the latest command that’s executed in the script, which might be useradd, passwd, or chpasswd, depending on the variation used:

if [ "$?" -eq 0 ]; then
  echo "Username: $username"
  echo "Password: $password"
else
  echo "Failed to set up user account"
  userdel -f "$username"
fi

Let’s break it down:

  • We check for the exit code of the previously executed command and expect it to be equal to 0
  • If it’s 0, which usually indicates success, we print out the username and password
  • In case of failure, we print out the failure message and remove the user from the user database using the userdel command if it’s been created
  • The -f flag forces userdel to remove the user – even if the user is still logged in – along with their home directory and mail spool

We’re now ready to test out the script:

$ ./create-user -u "johndoe" -p "ys2b7444"
Username: johndoe
Password: ys2b7444
$ ./create-user -u "doejohn"
Username: doejohn
Password: 89c871de
$ ./create-user -u johndoe
johndoe already exists
$ ./create-user
create-user [-u|--username] <username>
OPTIONS
 -u --username  username of the new account (required)
 -p --password  password for the new account (optional)
 -h --help      print this help

Our create-user script is now complete:

#!/bin/sh

usage() {
  printf "create-user [-u|--username] &lt;username&gt;\n"
  printf " OPTIONS\n"
  printf "  -u --username\tusername of the new account (required)\n"
  printf "  -p --password\tpassword for the new account (optional)\n"
  printf "  -h --help\tprint this help\n"
  exit 1
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    -u|--username) username="$2" shift ;;
    -p|--password) password="$2" shift ;;
        -h|--help) usage ;;
                *) usage ;;
  esac
  shift
done

[ -z "$username" ] && usage
[ -z "$password" ] && password=$(uuidgen | cut -d'-' -f1)

useradd -m "$username" -p "$password" > /dev/null 2>&1

#------------#
# VARIATIONS #
#------------#
# useradd -m "$username"
# echo -n "$password\n$password\n" | passwd $username"
# echo "${username}:${password}" | chpasswd

if [ "$?" -eq 0 ]; then
  echo "Username: $username"
  echo "Password: $password"
else
  echo "Failed to set up user account"
  userdel -f "$username"
fi

5. Conclusion

In this article, we saw how we can automate the process of creating a user. Throughout the article, we wrote a robust shell script that we can use from the terminal or another program to create users. We used different tools in the script for creating users, assigning passwords to users, and querying the user database.

Comments are closed on this article!