Linux User Creation Bash Script
I am on my way to being a world class DevOps engineer.
Task : Your company has employed many new developers. As a SysOps engineer, write a bash script called create_users.sh that reads a text file containing the employee’s usernames and group names, where each line is formatted as user; groups.
Script Requirements :
Create a bash script called create_users.sh
Create users and groups with home directories and appropriate permissions and ownership.
Generate random passwords for the users.
Log all actions to /var/log/user_management.log
Store passwords securely in /var/secure/user_passwords.txt
Hand errors, such as existing users and log these errors.
Here is how to write a script that finds a solution to the given task.
Declare Shebang
#!/bin/bashNote: The very first step to writing a script is declaring shebang(#!). Then specify what type of script you're writing. Here, it's a bash script. Hence, its declared with /bain/bash.
Declare Arrays
#Declare User and Groups Arrays users=() groups=()The 'users' and 'groups' arrays are to store the usernames and group names read from the input file which allows to keep track of each user and their associated groups as you processed the input file, ensuring that users could be created and then added to their respective groups, including handling their password generation and logging actions accordingly.
Declare logfiles and password paths
#Declare logfiles and password paths log_file="/var/log/user_management.log" password=="/var/secure/user_passwords.txt"In this step, we establish the paths for the log file and password file in our bash script. The /var/log/user_management.log holds detail activities of a user while the /var/secure/user_passwords will securely store generated user passwords.
Read the input file
# Read input file using functions function readInputFile() { local file="$1" # Read input file while IFS= read -r line; do user=$(echo "$line" | cut -d';' -f1 | tr -d '[:space:]') group=$(echo "$line" | cut -d';' -f2 | tr -d '[:space:]') # Add user to the users array users+=("$user") # Add group to the groups array groups+=("$group") done < "$file" }This function reads the input file line by line, splitting each line into
userandgroupusing a semicolon as the delimiter. It trims any whitespace from these values and adds them to their respective arrays.First, we define a function called
readInputFile. This function takes a file as argument, which is the path to the input file and reads it line by line.The
IFS=';'sets the internal field separator to a semicolon, which allows us to split each line intouserandgroupvariables.Then clear any whitespace around the
userandgroupvalues using thetr -d '[:space:]'command.The username and groups are added to their arrays using the
users+=("$user")andgroups+=("$groups")command.Check Argument Passed
# Check if necessary amount of argument is passed(1 arg) if [ "$#" -ne 1 ]; then echo "Usage: $0 <input_file>" exit 1 fiThis checks if required argument is passed to the script, if not it displays a usage message and exits the script with an error status code.
Read Input file
# Read input file input_file="$1" echo "Reading your input file: $input_file" readInputFile "$input_file"Capture the file path which is assigned to a variable as an argument:
input_file="$1"Print Information to terminal:
echo "Reading your input file: $input_file"Call the Function to Read the File :
read_input_file "$input_file"Check if log and password files exist and create them if they don't exist
# Check existence of the log and password files, and create them if not if [ ! -f "$log_file" ]; then mkdir -p /var/log touch "$log_file" chmod 640 "$log_file" fi if [ ! -f "$password_file" ]; then mkdir -p /var/secure touch "$password_file" chmod 600 "$password_file" fiThis checks if the log and password files exist and creates a /var/log and /var/secure directories and necessary files with it's necessary permissions assigned to it.
Iterating Over Users Array in Bash
# Iterate over the users array for (( i = 0; i < ${#users[@]}; i++ )); do user="${users[$i]}" user_groups="${groups[$i]}" if id "$user" &>/dev/null; then echo "User $user already exists, Skipped" | tee -a "$log_file" elseIn the above script, to process each user and their associated group from arrays (
usersandgroups), the script uses aforloop. Then, it assigns current username to user, assigns associated groups to groups and checks if user exists.Create User
# Create user useradd -m -s /bin/bash "$user" if [[ $? -ne 0 ]]; then echo "Create User $user failed" | tee -a "$log_file" exit 1 fi echo "User $user created successfully" | tee -a "$log_file"useradd -m -s /bin/bash "$user"creates the user with a home directory and sets the default shell to/bin/bash.if [[ $? -ne 0 ]]; then: Checks the exit status ($?) of the previous command (useradd). A non-zero exit status indicates an error during user creation.echo "User $user created successfully" | tee -a "$log_file": Logs a success message indicating that user creation was successfultee -a "$log_file": Appends the success message to the$log_file, ensuring that the action is logged for auditing or troubleshooting purposes.Set User Password
# Set password password=$(openssl rand -base64 50 | tr -dc 'A-Za-z0-9!?%=' | head -c 10) echo "$user:$password" | chpasswd if [[ $? -ne 0 ]]; then echo "Set password for $user failed" | tee -a "$log_file" exit 1 fi echo "Password for $user set successfully" | tee -a "$log_file" echo "$user,$password" >> "$password_file"This generates random passwords and appends the passwords to users using the
openssl rand -base64 50command to create a 50-character random string. It then filters the string to include only specific characters usingtr -dc 'A-Za-z0-9!?%='that includes alphabets, numbers and special characters and shortens it to 10 characters withhead -c 10.The generated password is assigned to the user with the
echo "$user:$password" | chpasswdcommand, thus setting the user's password. Then the script checks thechpasswdcommand's exit status using$?. If the command fails, it logs the error to a file and exits with status 1.Add User to Groups
# Add user to personal group usermod -aG "$user" "$user" if [[ $? -ne 0 ]]; then echo "Add user $user to personal group failed" | tee -a "$log_file" exit 1 fi echo "User $user added to personal group successfully" | tee -a "$log_file" # Add user to other groups IFS=',' read -r -a group_array <<< "$user_groups" for group in "${group_array[@]}"; do if grep -q "^$group:" /etc/group; then echo "Group $group already exists" | tee -a "$log_file" else groupadd "$group" if [[ $? -ne 0 ]]; then echo "Create group $group failed" | tee -a "$log_file" exit 1 fi echo "Group $group created successfully" | tee -a "$log_file" fi usermod -aG "$group" "$user" if [[ $? -ne 0 ]]; then echo "Add user $user to group $group failed" | tee -a "$log_file" exit 1 fi echo "User $user added to group $group successfully" | tee -a "$log_file" done fi done exit 0This part of the script adds the user to its personal group by using the
usermod -aG "$user" "$user"command to add each user to a group with the same name as their username. This ensures that every user has a personal group, which helps with file sharing and permissions management. Ifusermodfails, the script logs an error to a log file, which aids troubleshooting.The script the adds users to other specified groups and also manages users in multiple groups. It reads group names from the variable (
$user_groups) which is separated by commas. The script checks for the existence of each group and creates it if necessary usinggroupadd. Then, it adds the user to each group withusermod -aG. This is important for setting up access permissions based on the members of the group.To Handle Errors and Logging
The script logs any errors encountered during the addition of users to groups or the creation of groups by using the
tee -a $log_file"as seen in the code. Then,exit 1indicates an abnormal termination of the script due to an error.
After writing your script you save and exit your script, add executable permissions to the script, then execute your script to confirm that the written script functions correctly.
To save and exit the script, it depends on the text editor used to write the script.
For Nano text editor: press
ctrl + O(the letter 'O', not the number zero), then press theenterbutton to save the script and finallyctrl + xto exit the nano editor.For Vim text editor: press
escto ensure you are in normal mode, then press the colon button:, then typewqand finally, press theenterbutton to save and exit the script.To add executable permissions to the script, you use the
chmod +x thescriptname.shcommand.To execute the script, you use the
sudo ./thescriptname.shcommand.
Check out HNG here : https://hng.tech/internship, https://hng.tech/hire.
