Salta al contenuto principale

who: chi è collegato al sistema

Inviato da tuxsa il

Stai per riavviare un server e vuoi sapere se qualcuno ci sta lavorando. Oppure ti accorgi di un rallentamento e vuoi capire chi è collegato, e da dove. who ("chi") risponde con un elenco di poche righe: gli utenti presenti in questo momento, il terminale che usano, da quando e da quale indirizzo si sono collegati.

Cos'è

who fa parte del pacchetto coreutils, quindi è disponibile su ogni distribuzione. Non cerca niente per conto suo: legge il registro delle sessioni, un piccolo file chiamato utmp (in /var/run/utmp) in cui il sistema annota chi entra e chi esce. Per questo who risponde subito, ed è affidabile finché il registro è aggiornato.

Cosa fa

Elenca le sessioni aperte, una per riga: il nome utente, il terminale su cui lavora, la data e l'ora di accesso e, se la connessione è da remoto, l'indirizzo di provenienza. Con le opzioni aggiunge le intestazioni, da quanto tempo l'utente è inattivo, l'ora dell'ultimo avvio e altro.

Come si usa

$ who [opzioni]

Gli esempi mostrano un server chiamato web01, con due utenti collegati.

Esempio 1: il comando senza opzioni

$ who
enzo     pts/0        2026-10-29 09:20 (203.0.113.45)
backup   pts/1        2026-10-29 08:02 (192.168.1.20)

Le colonne, da sinistra a destra: il nome dell'utente, il terminale, la data e l'ora di accesso e, tra parentesi, l'indirizzo da cui si è collegato. Gli indirizzi sono inventati. Il terminale pts/N indica una sessione da remoto (per esempio con ssh) o una finestra di terminale in un ambiente grafico; tty1, tty2… sono i terminali "veri" davanti alla macchina; un indirizzo come :0 tra parentesi indica una sessione grafica locale. Se nessuno è collegato, l'output è vuoto.

Esempio 2: con le intestazioni, con -H

$ who -H
NAME     LINE         TIME             COMMENT
enzo     pts/0        2026-10-29 09:20 (203.0.113.45)
backup   pts/1        2026-10-29 08:02 (192.168.1.20)

Con -H (heading) compare la riga con i nomi delle colonne, comoda quando si mostra l'output a qualcun altro.

Esempio 3: chi è inattivo, con -u

$ who -Hu
NAME     LINE         TIME             IDLE          PID COMMENT
enzo     pts/0        2026-10-29 09:20   .          3841 (203.0.113.45)
backup   pts/1        2026-10-29 08:02 01:15        3902 (192.168.1.20)

L'opzione -u (users) aggiunge due colonne: IDLE, da quanto tempo l'utente non scrive niente (il punto . significa "attivo nell'ultimo minuto", 01:15 è un'ora e un quarto fa) e PID, il numero del processo della sessione (vedi l'articolo su ps e kill). L'utente backup risulta quindi collegato ma fermo da più di un'ora: forse una sessione dimenticata aperta.

Esempio 4: contare gli utenti, con -q

$ who -q
enzo backup
# users=2

Con -q (quick, o count) si ottengono solo i nomi e il totale delle sessioni. Se lo stesso utente ha due finestre aperte il nome compare due volte e il totale conta due.

Esempio 5: ultimo avvio e altre informazioni

$ who -b
         system boot  2026-09-12 06:39
$ who -r
         run-level 5  2026-09-12 06:39
$ who -a

-b (boot) mostra la data dell'ultimo avvio, come visto nell'articolo su uptime. L'opzione -r (runlevel) è un residuo dei vecchi sistemi: oggi i sistemi con systemd mostrano spesso un valore fisso (come 5) che non ha più un significato pratico, e su molte installazioni non mostra niente. Con -a (all) si ottiene tutto insieme: avvio, processi di accesso, utenti e altro.

Esempio 6: chi sono io? who am i

$ who am i
enzo     pts/0        2026-10-29 09:20 (203.0.113.45)
$ whoami
enzo
$ id -un
enzo
$ logname
enzo

Con who am i (o who -m) si ottiene solo la riga della propria sessione. Per il solo nome, ci sono altri tre comandi molto vicini, ma con una differenza: whoami e id -un mostrano l'utente con cui stai lavorando ora, mentre logname mostra l'utente con cui hai fatto l'accesso. Dopo sudo -i o su, whoami risponde root, mentre logname continua a rispondere enzo (vedi l'articolo su sudo). Dove il registro delle sessioni non è disponibile (come in alcuni container), who am i e logname possono non mostrare niente o dare un errore, mentre whoami funziona sempre.

Esempio 7: da quali indirizzi ci si collega

$ who | awk '{print $NF}' | tr -d '()' | sort | uniq -c
      1 192.168.1.20
      1 203.0.113.45
$ who | awk '{print $1}' | sort -u
backup
enzo

Con awk, sort e uniq (vedi gli articoli relativi) si estrae l'informazione che serve. Nel primo comando, $NF è l'ultimo campo di ogni riga (l'indirizzo) e tr -d '()' toglie le parentesi: il risultato è l'elenco degli indirizzi di provenienza, con il numero di sessioni. Il secondo dà i nomi degli utenti, senza ripetizioni. Utile per scoprire un accesso da un indirizzo che non conosci.

Esempio 8: chi si è collegato in passato, con last

$ last -n 3
enzo     pts/0        203.0.113.45     Thu Oct 29 09:20   still logged in
backup   pts/1        192.168.1.20     Thu Oct 29 08:02   still logged in
enzo     pts/0        203.0.113.45     Wed Oct 28 18:41 - 19:05  (00:24)
$ sudo lastb | head -n 3

who mostra solo chi c'è adesso. Per la storia degli accessi si usa last, che legge il registro /var/log/wtmp: mostra chi si è collegato, da dove, quando e per quanto tempo (00:24 è la durata di 24 minuti), con -n per limitare il numero di righe. Con sudo lastb si leggono invece i tentativi di accesso falliti (dal registro /var/log/btmp, leggibile solo da root): su un server esposto a Internet, l'elenco è di solito lungo, perché qualcuno prova continuamente password a caso.

Esempio 9: scrivere a chi è collegato, o farlo uscire

$ echo "Riavvio tra 10 minuti: salvate il lavoro" | wall
$ echo "Ciao, mi senti?" | write backup pts/1
$ sudo pkill -KILL -t pts/1
$ sudo loginctl terminate-user backup

Dopo aver visto chi c'è, si può agire. wall (write all) manda un messaggio a tutti gli utenti collegati; write utente terminale lo manda a uno solo (se riceve messaggi). Per chiudere una sessione si può terminare tutti i processi di quel terminale con pkill -t (vedi l'articolo su kill), oppure usare loginctl terminate-user sui sistemi con systemd. Prima di farlo, avverti sempre l'utente: potrebbe avere un lavoro non salvato.

Esempio 10: uso negli script

#!/bin/bash
AMMESSI="enzo backup"

who | awk '{print $1, $NF}' | sort -u | while read -r utente origine; do
    case " $AMMESSI " in
        *" $utente "*) ;;
        *) echo "Accesso inatteso: $utente da $origine" ;;
    esac
done

Lo script elenca le sessioni aperte e segnala quelle di utenti che non sono nell'elenco degli ammessi. Il while read legge una riga alla volta, e case confronta il nome con l'elenco. Programmato con crontab ogni pochi minuti, e con l'output mandato per posta o in un registro, dà un primo avviso di accessi inattesi. Non sostituisce però un vero sistema di sicurezza.

Opzioni utili

  • -H: aggiunge la riga con i nomi delle colonne.
  • -u: mostra da quanto tempo ogni utente è inattivo e il numero del processo di sessione.
  • -q: solo i nomi e il numero totale di utenti.
  • -b: data dell'ultimo avvio; -r: runlevel (di scarso interesse oggi).
  • -m o am i: solo la propria sessione.
  • -a: tutte le informazioni insieme; -T: indica se l'utente accetta messaggi.
  • w: come who, più cosa sta facendo ciascun utente e il carico (vedi uptime); users: solo i nomi su una riga.
  • last, lastb: storia degli accessi riusciti e falliti; loginctl list-sessions: le sessioni secondo systemd.

Attenzione a

  • Mostra le sessioni, non le persone: la stessa persona con tre finestre di terminale compare tre volte. Il numero di -q conta le sessioni, non gli utenti diversi.
  • Non vede tutto: who legge il registro utmp, e non tutti i programmi lo aggiornano. Le sessioni nate da su o sudo restano associate all'utente originale, e alcune connessioni (come ssh con un comando singolo e senza terminale) non compaiono. Se il registro non è disponibile, come in molti container, l'output è vuoto anche se ci sono processi attivi.
  • Non è uno strumento di sicurezza: se qualcuno ha preso il controllo della macchina può modificare o cancellare i registri. Per le indagini serve confrontare più fonti (last, journalctl, /var/log/auth.log).
  • Il formato della data dipende dalla lingua: con la lingua del sistema impostata normalmente la data è del tipo 2026-10-29 09:20; con la lingua "C" (quella minima, usata da alcuni script e container) diventa Oct 29 09:20. Negli script, non fare affidamento sul formato della data: usa le colonne del nome e del terminale.
  • L'indirizzo può mancare: sulle sessioni locali non c'è la parte tra parentesi, o contiene solo il nome dello schermo grafico (:0). Con --lookup who prova a risolvere il nome della macchina con il DNS, che può rallentare il comando.
  • Un utente inattivo non è un utente assente: una sessione ferma da ore può avere programmi in esecuzione (con screen o tmux, per esempio). Chiuderla con pkill interrompe tutto quello che c'è dentro.
  • Prima di riavviare, controlla: un who prima di reboot o shutdown è una buona abitudine su un server condiviso, e un wall con un preavviso è la buona educazione.
  • whoami non è logname: il primo dice con quale utente stai lavorando adesso (cambia con sudo e su), il secondo con quale hai fatto l'accesso. Negli script di amministrazione, per sapere chi ha lanciato davvero il comando, la variabile $SUDO_USER è spesso più utile.
  • Gli indirizzi sono dati personali: un elenco di accessi con indirizzi e orari può identificare delle persone. Se lo condividi (in una segnalazione o in un forum), togli o sostituisci quelle informazioni.

Riepilogo

ComandoCosa fa
whoElenca le sessioni aperte (utente, terminale, ora, origine)
who -HAggiunge le intestazioni delle colonne
who -HuAggiunge inattività e numero del processo
who -qSolo i nomi e il numero di sessioni
who -bData e ora dell'ultimo avvio
who am iSolo la propria sessione
whoamiUtente con cui stai lavorando ora
lognameUtente con cui hai fatto l'accesso
wSessioni, attività di ciascuno e carico
last -n 10Ultimi 10 accessi
sudo lastbTentativi di accesso falliti
wallManda un messaggio a tutti gli utenti collegati
loginctl list-sessionsSessioni secondo systemd