Shell Scripting

Crear usuaris en bloc a Linux amb un script de Bash

/bin/bash


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 -m crea el directori personal (/home/usuari, copiant-hi el contingut de /etc/skel) i -s /bin/bash li assigna Bash com a shell.
  • chpasswd llegeix línies usuari:contrasenya de 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 -e fa 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 -r llegeix 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’usuari joan\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

  1. Dona-li permís d’execució: chmod +x crear_usuaris.sh.
  2. Prova’l primer en una màquina virtual o un contenidor, no directament en un servidor en producció.
  3. 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 comanda newusers (del mateix paquet que useradd) 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.
  • adduser a Debian i Ubuntu: és interactiu i més amable per crear usuaris d’un en un, però per a scripts és millor useradd.
  • Grups: si tots els usuaris han d’anar al mateix grup, afegeix -G nom_grup a useradd (el grup ha d’existir; el pots crear amb groupadd).
  • Validesa de la contrasenya: amb chage pots 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.

Posts relacionats