Quan has de donar d’alta molts usuaris alhora (els alumnes d’un curs, el personal d’un departament, els comptes d’un laboratori), fer-ho un per un és lent i és fàcil equivocar-se. Amb un script de Bash ho pots automatitzar a partir d’una llista en un fitxer de text. En aquest article tens un script complet, explicat pas a pas, i les errades que cal evitar.
Nota important sobre la versió original d’aquest article. Els scripts que hi havia no funcionaven: el here document que passava la contrasenya a passwd tenia el EOF final sagnat, i Bash no el reconeix (l’script dona syntax error: unexpected end of file). A més, comprovava si l’usuari existia amb grep -q $1 /etc/passwd, que també troba coincidències parcials (si existeix joana, creia que joan ja existia), i posava la mateixa contrasenya, P@ssw0rd, a tothom. Aquí tens una versió corregida.
La llista d’usuaris
Parteix d’un fitxer de text, usuaris.txt, amb un nom d’usuari per línia. L’script salta les línies buides i les que comencen per #:
# Alumnes del curs d'administració de sistemes
joan
maria
anna
Els noms han de ser en minúscules, començar per una lletra o _ i contenir només lletres, xifres, _ i - (és el criteri que Debian aplica per defecte i el que valida l’script).
L’script
Desa’l com a crear_usuaris.sh:
#!/usr/bin/env bash
# crear_usuaris.sh: crea els usuaris d'una llista amb una contrasenya aleatòria
set -uo pipefail
if [[ $EUID -ne 0 ]]; then
echo "Executa'l com a root: sudo $0 FITXER" >&2
exit 1
fi
llistat="${1:-}"
if [[ -z "$llistat" ]]; then
read -rp "Fitxer amb la llista d'usuaris: " llistat
fi
if [[ ! -f "$llistat" ]]; then
echo "El fitxer '$llistat' no existeix." >&2
exit 1
fi
# Aquí es desaran les contrasenyes inicials (només les pot llegir root)
credencials="credencials_$(date +%Y%m%d_%H%M%S).txt"
(umask 077; : > "$credencials")
crear_usuari() {
local usuari=$1 contrasenya
if getent passwd "$usuari" >/dev/null; then
echo " ja existeix, el salto"
return 0
fi
contrasenya=$(openssl rand -base64 12)
useradd -m -s /bin/bash "$usuari" || return 1
echo "$usuari:$contrasenya" | chpasswd || return 1
passwd -e "$usuari" >/dev/null || return 1 # l'haurà de canviar al primer inici de sessió
echo "$usuari:$contrasenya" >> "$credencials"
echo " creat"
}
errors=0
while IFS= read -r usuari || [[ -n "$usuari" ]]; do
usuari=${usuari%$'\r'} # treu el \r dels fitxers fets a Windows
[[ -z "$usuari" || "$usuari" == \#* ]] && continue # salta línies buides i comentaris
if [[ ! "$usuari" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then
echo "Nom no vàlid: '$usuari'" >&2
errors=$((errors + 1))
continue
fi
echo "Usuari $usuari:"
if ! crear_usuari "$usuari"; then
echo " ERROR en crear $usuari" >&2
errors=$((errors + 1))
fi
done < "$llistat"
echo "Contrasenyes inicials desades a: $credencials"
[[ $errors -eq 0 ]] || { echo "Hi ha hagut $errors errors." >&2; exit 1; }
Com funciona
1. Cal ser root
if [[ $EUID -ne 0 ]]; then
Crear usuaris i canviar contrasenyes requereix privilegis d’administrador. Si no l’executes amb sudo, l’script s’atura amb un missatge clar en lloc de fallar a mitja feina.
2. El fitxer de la llista
El fitxer es pot passar com a argument (sudo ./crear_usuaris.sh usuaris.txt) o, si no, l’script el demana amb read. Abans de continuar comprova que existeix.
3. Contrasenyes aleatòries, desades en un fitxer protegit
credencials="credencials_$(date +%Y%m%d_%H%M%S).txt"
(umask 077; : > "$credencials")
En lloc d’una contrasenya comuna per a tothom (qualsevol usuari podria entrar al compte d’un altre que encara no l’hagi canviada), cada usuari en rep una d’aleatòria amb openssl rand -base64 12 (16 caràcters). L’umask 077 fa que el fitxer de credencials es creï amb permisos 600, de manera que només el pot llegir root. Reparteix les contrasenyes per un canal segur i esborra el fitxer quan ja no el necessitis.
4. Comprovar si l’usuari ja existeix
if getent passwd "$usuari" >/dev/null; then
getent passwd usuari només respon si hi ha un usuari amb aquest nom exacte, i també funciona amb usuaris que vénen d’un directori LDAP. És molt més fiable que buscar el nom amb grep dins de /etc/passwd.
5. Crear l’usuari i posar-li la contrasenya
useradd -m -s /bin/bash "$usuari"
echo "$usuari:$contrasenya" | chpasswd
passwd -e "$usuari"
useradd -mcrea el directori personal (/home/usuari, copiant-hi el contingut de/etc/skel) i-s /bin/bashli assigna Bash com a shell.chpasswdllegeix líniesusuari:contrasenyade l’entrada estàndard i és l’eina pensada per canviar contrasenyes des d’un script.passwd, en canvi, està pensat per a ús interactiu.passwd -efa caducar la contrasenya: en el primer inici de sessió, el sistema obligarà l’usuari a triar-ne una de nova.
Si alguna d’aquestes comandes falla, la funció retorna un error i el bucle principal l’apunta.
6. Llegir la llista línia per línia
while IFS= read -r usuari || [[ -n "$usuari" ]]; do
usuari=${usuari%$'\r'}
...
done < "$llistat"
IFS= read -rllegeix cada línia sencera, sense retallar espais ni interpretar barres inverses.|| [[ -n "$usuari" ]]processa també l’última línia encara que el fitxer no acabi amb un salt de línia (passa sovint amb fitxers escrits a mà).${usuari%$'\r'}treu el retorn de carro dels fitxers creats a Windows. Sense això, intentaria crear l’usuarijoan\r.- L’expressió regular rebutja els noms no vàlids abans de cridar
useradd.
Al final, l’script mostra on ha desat les contrasenyes i, si hi ha hagut errors, en diu quants i acaba amb codi de sortida 1.
Com fer-lo servir
- Dona-li permís d’execució:
chmod +x crear_usuaris.sh. - Prova’l primer en una màquina virtual o un contenidor, no directament en un servidor en producció.
- Executa’l:
sudo ./crear_usuaris.sh usuaris.txt.
$ sudo ./crear_usuaris.sh usuaris.txt
Usuari joan:
creat
Usuari maria:
creat
Usuari anna:
ja existeix, el salto
Contrasenyes inicials desades a: credencials_20261004_194804.txt
I el fitxer de credencials, només llegible per root:
$ sudo cat credencials_20261004_194804.txt
joan:xOotBrot64deRmNp
maria:s29vZrGB3y3py4mZ
Comprova que els usuaris s’han creat:
$ getent passwd joan
joan:x:1001:1001::/home/joan:/bin/bash
$ sudo chage -l joan | head -1
Last password change : password must be changed
Alternatives i millores
newusers: la comandanewusers(del mateix paquet queuseradd) crea usuaris en bloc a partir d’un fitxer amb el format de/etc/passwd, contrasenya inclosa. Va bé per a càrregues massives, però és menys flexible que un script.addusera Debian i Ubuntu: és interactiu i més amable per crear usuaris d’un en un, però per a scripts és milloruseradd.- Grups: si tots els usuaris han d’anar al mateix grup, afegeix
-G nom_grupauseradd(el grup ha d’existir; el pots crear ambgroupadd). - Validesa de la contrasenya: amb
chagepots fixar quants dies dura la contrasenya o quan caduca el compte. - Molts servidors: si has de mantenir els mateixos usuaris en diverses màquines, val més un directori centralitzat (LDAP, FreeIPA) o una eina com Ansible que no pas executar l’script a cada servidor.
Automatitzar l’alta d’usuaris estalvia temps i errors, però és una tasca delicada: revisa bé l’script, prova’l abans i tracta les contrasenyes inicials amb cura.