If you need a linux bulk users onboarding script—read a list, create accounts,
set shells and home trees, then hand out shell password material once—useradd
plus chpasswd is the usual server approach on Debian and Ubuntu. Desktop
distros often teach adduser, but adduser is interactive; for how to
create multiple users in linux from a file, useradd stays predictable in
loops. Read
how to create a user in Linux,
useradd, and
adduser first if the basics are new.
Shell syntax below was checked with
bash -non Ubuntu 25.04, Bash 5.2.37. I did not executeuseradd/chpasswdin this environment (they need root and real accounts); run on a VM or container you can throw away.
Input file: list of usernames (stub-friendly format)
Put one username per line, optional comments with #, blank lines ignored. This
matches the “read the list of … users” part of long onboarding prompts:
# usernames.txt
ravi_kumar
anjali_gupta
amit_patelUsernames should match ^[a-z_][a-z0-9_-]*$ (POSIX account name rules); reject
anything else so a typo does not break useradd.
Simple create user script (homes with -m)
#!/usr/bin/env bash
set -euo pipefail
if [[ $(id -u) -ne 0 ]]; then
echo "Run as root (or sudo ./script)" >&2
exit 1
fi
user_file=${1:-usernames.txt}
[[ -f "$user_file" ]] || { echo "Missing $user_file" >&2; exit 1; }
while IFS= read -r line || [[ -n "$line" ]]; do
line=${line//$'\r'/}
[[ -z "${line// }" || "$line" =~ ^[[:space:]]*# ]] && continue
u=${line%%[[:space:]]*}
if [[ ! "$u" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then
echo "skip invalid name: $u" >&2
continue
fi
if id "$u" &>/dev/null; then
echo "exists: $u"
continue
fi
useradd -m -c "bulk,$u" "$u"
echo "created: $u"
done <"$user_file"-m creates /home/$u with skeleton files. Adjust /etc/skel on Ubuntu
if you need default dotfiles for onboarding.
Custom shell and home directory (useradd -d / -b)
Pick a shell that exists on the image (often /bin/bash). If every home must live
under a shared prefix, set BASE and pass -d explicitly—avoid the earlier
bug pattern of using $home_base before defining it.
#!/usr/bin/env bash
set -euo pipefail
[[ $(id -u) -eq 0 ]] || exit 1
user_file=${1:-usernames.txt}
shell_bin=/bin/bash
base=/srv/homes
mkdir -p "$base"
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "${line// }" || "$line" =~ ^[[:space:]]*# ]] && continue
u=${line%%[[:space:]]*}
[[ "$u" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] || continue
id "$u" &>/dev/null && continue
useradd -m -d "$base/$u" -s "$shell_bin" -c "bulk,$u" "$u"
echo "created $u -> $base/$u"
done <"$user_file"Per-user password, chage, and a secrets file (better than echoing)
For shell password setup without pasting into chat logs:
- Generate one secret per user (example uses
openssl). - Pipe
username:passwordlines tochpasswd. - Write the same pairs to a root-only file (mode 600), not to stdout.
- Run
chage -d 0so Linux forces a change at first login.
#!/usr/bin/env bash
set -euo pipefail
[[ $(id -u) -eq 0 ]] || exit 1
user_file=${1:-usernames.txt}
secrets=/root/bulk-onboarding-$(date +%F).txt
: >"$secrets"
chmod 600 "$secrets"
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "${line// }" || "$line" =~ ^[[:space:]]*# ]] && continue
u=${line%%[[:space:]]*}
[[ "$u" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] || continue
id "$u" &>/dev/null && continue
pw=$(openssl rand -base64 18)
useradd -m -s /bin/bash -c "bulk,$u" "$u"
printf '%s:%s\n' "$u" "$pw" | chpasswd
printf '%s\t%s\n' "$u" "$pw" >>"$secrets"
chage -d 0 "$u"
echo "created $u (password recorded in $secrets)" >&2
done <"$user_file"Deliver $secrets through your org’s vault or out-of-band channel—never commit
it to git.
Using one random password for every user (an older pattern) is weak; prefer per-user secrets as above.
How to switch user in Linux using a shell script (testing)
After creation, operators usually verify with an interactive shell:
su - username— classic; prompts for that user’s password.sudo -u username -i— handy if root’s sudoers allows it; still interactive for a login shell.
Fully non-interactive “switch user” inside a script for password auth is painful
(expect is brittle). Prefer sudo -u user command … to run one command as the
new account during automation instead of scripting su passwords.
Summary
How to create multiple users in linux from a file: loop with useradd -m,
validate names, skip existing id. A solid create user script adds -s
and -d when homes leave /home. For shell password handling, feed
chpasswd with openssl-generated secrets, store them in a 600 file, and
use chage -d 0 for first-login rotation. For how to switch user in linux using
shell script workflows, use sudo -u for single commands; reserve su -
for manual checks. Treat any bulk onboarding script as sensitive: dry-run on a VM,
read man useradd / man chpasswd, and align with your distro’s defaults on
Ubuntu and elsewhere.

