If you've never written a bash script before, today you'll be seeing how to write one.
Bash scripts are used to automate linux processes. Knowing how to write and implement them will serve you well in your devops journey.
In this article, I'll be showing you how I wrote a bash script that automates the process of creating users, assigning groups, setting up home directories, and managing passwords on a Unix-like system. The script also logs actions and handles errors efficiently.
Overview of the Script
Prerequisites
You must have a functional ubuntu terminal that you can test the script(create_users.sh) from.
The script must be run with root privileges to perform administrative tasks.
The input file must contain usernames and groups in the format: username;group1,group2.
#!/bin/bash
# Check if the script is run as root, if not re-execute it with sudo
if [ "$EUID" -ne 0 ]; then
echo "This script must be run as root. Re-executing with sudo..."
sudo bash "$0" "$@"
exit $?
fi
# Define paths to log and password file
LOGGER="var/log/user_management.log"
PASSWORD_FILE="var/secure/user_passwords.txt"
# Ensure directories and files exist with necessary permissions
sudo mkdir -p var/log
sudo mkdir -p var/secure
sudo chmod 700 /var/secure
sudo touch $LOGGER
sudo chmod 600 /var/secure/user_passwords.txt
sudo chown root:root /var/secure/user_passwords.txt
sudo touch $PASSWORD_FILE
# Function for generating logs
logging_function(){
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> $LOGGER
}
# Function for generating random passwords
password_generator(){
tr -dc A-Za-z0-9 </dev/urandom | head -c 12
}
# Check if a user text file was provided
if [ -z "$1" ];then
echo "Usage: $0 <user_file>"
exit 1
fi
# Read the file line by line and loop through
while IFS=';' read -r user groups || [ -n "$user" ]; do
# Trimming whitespace
user=$(echo "$user" | xargs)
groups=$(echo "$groups" | xargs)
# Skip empty lines
[ -z "$user" ] && continue
# Check if user already exists
if id "$user" &>/dev/null; then
logging_function "User $user already exists."
continue
fi
# Create user and generate password
password=$(password_generator)
sudo useradd -m -s /bin/bash "$user"
if [ $? -ne 0 ]; then
log_action "Failed to create user $user"
continue
fi
echo "$user:password" | chpasswd
logging_function "User $user created with home directory"
# Create personal group and assign to user
sudo usermod -aG "$user" "$user"
# Assign additional groups to user
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo $group | xargs)
if [ -n "$group" ]; then
if ! getent group "$group" > /dev/null 2>&1; then
groupadd "$group"
logging_function "Group $group created"
fi
usermod -aG "$group" "$user"
logging_function "User $user added to group $group"
fi
done
# Set home directory permissions
sudo chmod 700 /home/$user
sudo chown $user:$user /home/$user
# Store password securely
echo "$user, $password" >> $PASSWORD_FILE
logging_function "password for $user stored"
done < "$1"
#Give a success response
echo "User creation complete. Check $LOGGER"
This is the full script. I named it create_users.sh
Script Breakdown
Let's dive into the script line-by-line.
Self-Elevation Check
#!/bin/bash
This shebang line indicates that the script should be run using the bash shell.
if [ "$EUID" -ne 0 ]; then
echo "This script must be run as root. Re-executing with sudo..."
sudo bash "$0" "$@"
exit $?
fi
This block checks if the script is being run as the root user. If not, it re-executes itself with sudo to gain root privileges and exits with the same status code as the sudo command. Cool, right?
Define Log and Password File Paths
LOGGER="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
These lines define the paths for the log file and the password file where actions and generated passwords will be stored.
Ensure Directories and Files Exist
sudo mkdir -p /var/log
sudo mkdir -p /var/secure
sudo chmod 700 /var/secure
This section ensures that the required directories exist and sets appropriate permissions. The -p option in mkdir creates the directory only if it doesn't exist.
sudo touch $LOGGER
sudo touch $PASSWORD_FILE
sudo chmod 600 $PASSWORD_FILE
sudo chown root:root $PASSWORD_FILE
These commands create the log and password files if they don't exist and set their permissions to ensure only the root user can read and write them.
Logging Function
logging_function() {
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> $LOGGER
}
This function logs a message to the log file with a timestamp. It appends the message ($1) to the log file.
Password Generator
password_generator() {
tr -dc A-Za-z0-9 </dev/urandom | head -c 12
}
This function generates a random 12-character password using /dev/urandom for randomness.
Check for User File
if [ -z "$1" ]; then
echo "Usage: $0 <user_file>"
exit 1
fi
This block checks if an input file was provided as an argument. If not, it displays usage information and exits.
Read File Line by Line
while IFS=';' read -r user groups || [ -n "$user" ]; do
This while loop reads the input file line-by-line. IFS=';' sets the internal field separator to ;, and read -r user groups reads each line into the user and groups variables. The || [ -n "$user" ] part ensures the loop processes the last line even if it doesn't end with a newline.
Trim Whitespace
user=$(echo "$user" | xargs)
groups=$(echo "$groups" | xargs)
These lines remove leading and trailing whitespace from the user and groups variables using xargs.
Skip Empty Lines
[ -z "$user" ] && continue
This condition skips empty lines by continuing to the next iteration of the loop if user is empty.
Check if User Exists
if id "$user" &>/dev/null; then
logging_function "User $user already exists."
continue
fi
This block checks if the user already exists using the id command. If the user exists, it logs the information and skips to the next iteration.
Create User and Set Password
password=$(password_generator)
sudo useradd -m -s /bin/bash "$user"
if [ $? -ne 0 ]; then
logging_function "Failed to create user $user"
continue
fi
echo "$user:$password" | sudo chpasswd
Here, a random password is generated, and the useradd command creates a new user with a home directory and sets the shell to /bin/bash. If useradd fails, it logs the failure and continues to the next iteration. The chpasswd command sets the user's password.
Log User Creation
logging_function "User $user created with home directory"
This line logs the successful creation of the user and their home directory.
Create Personal Group
sudo usermod -aG "$user" "$user"
This command adds the user to their personal group, which is named the same as the username.
Assign Additional Groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo $group | xargs)
if [ -n "$group" ]; then
if ! getent group "$group" > /dev/null 2>&1; then
sudo groupadd "$group"
logging_function "Group $group created"
fi
sudo usermod -aG "$group" "$user"
logging_function "User $user added to group $group"
fi
done
This block assigns additional groups to the user. It splits the groups variable into an array using IFS=',', and then iterates over each group. If the group doesn't exist, it is created. The user is then added to each group, and the actions are logged.
Set Home Directory Permissions
sudo chmod 700 /home/$user
sudo chown $user:$user /home/$user
These commands set the permissions and ownership of the user's home directory to ensure it's secure and owned by the user.
Store Password Securely
echo "$user, $password" >> $PASSWORD_FILE
logging_function "Password for $user stored"
The user's password is stored in the password file, and the action is logged.
End of Script
done < "$1"
echo "User creation complete. Check $LOGGER"
The done < "$1" line marks the end of the while loop, which reads from the input file. The final echo statement informs the user that the process is complete and advises checking the log file for details.
Conclusion
This script provides a comprehensive solution for user management in a Unix-like system. It ensures that users are created with secure passwords, assigned to appropriate groups, and have their actions logged for auditing purposes. By understanding each line of the script, administrators can modify and extend it to fit their specific needs.
Learn More
For more information on automation scripts and enhancing your technical skills, consider exploring the HNG Internship program. If you are looking to hire skilled developers, visit HNG Hire to find top talent.
Top comments (0)