Salta al contenuto principale

tmux: terminali che non si chiudono mai

Inviato da tuxsa il

Hai avviato una copia da due ore sul server, e la connessione ssh cade: il comando si interrompe a metà. Oppure vuoi tenere sott'occhio i registri, la memoria e un editor insieme, senza aprire tre collegamenti. tmux risolve entrambi i problemi: tiene i tuoi terminali vivi sul server, anche quando tu non ci sei, e li divide come vuoi in un'unica finestra.

Cos'è

tmux (terminal multiplexer, "moltiplicatore di terminali") è un programma che gira sulla macchina, non sul tuo computer: gestisce i terminali al posto tuo e te li mostra. Non è sempre installato: su Debian e Ubuntu si aggiunge con sudo apt install tmux (vedi l'articolo su apt). Si basa su tre concetti, da conoscere subito:

  • la sessione: l'insieme di tutto ciò che stai facendo, con un nome. È quella che sopravvive quando ti scolleghi;
  • la finestra: una "scheda" dentro la sessione, come le schede di un browser;
  • il pannello (pane): una porzione di una finestra, che contiene un terminale. Una finestra può essere divisa in più pannelli.

Cosa fa

Quando avvii tmux, il programma si mette in funzione sul server e ti collega a una sessione. Tutto ciò che lanci lì dentro appartiene a tmux, non alla tua connessione. Se ti scolleghi (di proposito o per un guasto di rete) i programmi continuano a girare, e quando torni ti ricolleghi e ritrovi lo schermo com'era. Una barra in fondo allo schermo mostra la sessione, le finestre e l'ora.

Come si usa

$ tmux [comando] [opzioni]

Dentro tmux i comandi si danno premendo prima il prefisso, cioè Ctrl+b (si preme, si rilascia, e poi si preme il tasto del comando). Negli esempi scrivo, per esempio, "prefisso, poi d". Gli esempi usano il server web01 degli articoli precedenti. I comandi e le combinazioni li ho provati con tmux 3.4; le righe di tmux ls sono in inglese anche su un sistema in italiano.

Esempio 1: avviare una sessione con un nome

$ tmux new -s copie
[copie] 0:bash*                                  "web01" 05:21 02-Nov-26
$ rsync -a --progress /var/www/ /mnt/dati/www/

Con new -s nome (new session, -s per il nome) si avvia una sessione. Lo schermo si svuota e in fondo compare la barra di stato: a sinistra il nome della sessione tra parentesi quadre, poi le finestre con il loro numero e nome (0:bash, e l'asterisco * indica quella attiva), a destra il nome della macchina, l'ora e la data. Da qui in poi lavori come in un terminale normale: l'esempio lancia una copia lunga con rsync (vedi l'articolo relativo). Dare un nome alla sessione è una buona abitudine: con più sessioni, i numeri non dicono niente.

Esempio 2: staccarsi e riattaccarsi

(prefisso, poi d)
[detached (from session copie)]
$ tmux ls
copie: 1 windows (created Mon Nov  2 05:21:11 2026)
$ exit
...
$ ssh enzo@web01
$ tmux attach -t copie
$ tmux a

È il cuore di tmux. Con "prefisso, poi d" (detach) ti stacchi dalla sessione, che resta attiva: la copia continua. Puoi anche chiudere il terminale o spegnere il computer (vedi l'articolo su ssh). Quando ti ricolleghi, tmux ls elenca le sessioni esistenti e tmux attach -t copie (o l'abbreviazione tmux a, se ce n'è una sola) ti riporta dentro, con lo schermo come lo avevi lasciato. Se la connessione cade da sola, tmux fa la stessa cosa: la sessione resta, e basta riattaccarsi. Per creare la sessione se non esiste o collegarsi se esiste già: tmux new -As copie (non aggiungere -d a questa forma).

Esempio 3: più finestre, come schede

[lavoro] 0:bash  1:log*  2:htop
(prefisso, poi c)   crea una nuova finestra
(prefisso, poi n)   finestra successiva
(prefisso, poi p)   finestra precedente
(prefisso, poi 1)   vai alla finestra numero 1
(prefisso, poi ,)   rinomina la finestra
(prefisso, poi w)   elenco delle finestre
(prefisso, poi &)   chiudi la finestra (chiede conferma)

Ogni finestra è un terminale separato: in una puoi leggere i registri, in un'altra modificare un file con nano, in un'altra ancora guardare top. La barra di stato elenca le finestre, con quella attiva segnata da * e quella usata subito prima da -. Ogni comando visto qui sopra è una combinazione "prefisso, poi tasto".

Esempio 4: dividere lo schermo in pannelli

+------------------+------------------+
| top              | tail -f log      |
|                  +------------------+
|                  | bash             |
+------------------+------------------+
(prefisso, poi %)   divide in due, uno accanto all'altro
(prefisso, poi ")   divide in due, uno sopra l'altro
(prefisso, poi frecce)   passa a un altro pannello
(prefisso, poi o)   passa al pannello successivo
(prefisso, poi z)   ingrandisce o ripristina il pannello
(prefisso, poi x)   chiude il pannello (chiede conferma)

Il disegno mostra una finestra divisa in tre pannelli: a sinistra top, a destra in alto i registri con tail -f (vedi l'articolo su head e tail), in basso una shell libera. Per ottenerlo: "prefisso, poi %" (divisione verticale, i pannelli sono affiancati), ci si sposta a destra con "prefisso, poi freccia", e si divide con "prefisso, poi "" (i pannelli sono uno sopra l'altro). Il comando z (zoom) porta un pannello a schermo intero e, premuto di nuovo, lo ripristina: comodo quando vuoi leggere meglio un'uscita senza chiudere gli altri.

Esempio 5: scorrere l'uscita e copiare

(prefisso, poi [)   entra nella modalità di scorrimento
   freccia su/giù, PagSu/PagGiù   scorrono
   Ctrl+r           cerca all'indietro (Ctrl+s in avanti)
   q                esce dalla modalità
$ tmux show -g history-limit
history-limit 2000

Dentro tmux la rotella e la barra di scorrimento del terminale non funzionano come al solito: per rivedere ciò che è scorso via si entra nella modalità copia con "prefisso, poi [", ci si muove con le frecce o con PagSu e PagGiù, si cerca con Ctrl+r (all'indietro) o Ctrl+s (in avanti) e si esce con q. Chi usa vi come editor predefinito (variabili EDITOR o VISUAL) trova i tasti di vi: / per cercare, n per il risultato successivo. La cronologia conservata per ogni pannello è, per impostazione predefinita, di 2000 righe: si alza con history-limit (vedi l'esempio 7). Attivando il mouse (sempre nell'esempio 7) la rotella funziona.

Esempio 6: comandare tmux da fuori, e dagli script

$ tmux new -d -s sito 'rsync -a /var/www/ /mnt/dati/www/'
$ tmux ls
sito: 1 windows (created Mon Nov  2 05:21:11 2026)
$ tmux send-keys -t sito 'ls -l' Enter
$ tmux capture-pane -p -t sito | tail -n 3
$ tmux rename-session -t sito copie
$ tmux has-session -t copie 2>/dev/null && echo "esiste"
esiste
$ tmux kill-session -t copie

Tutto ciò che si fa con i tasti si può fare anche con un comando, ed è ciò che rende tmux programmabile. Con new -d (detached) si avvia una sessione già staccata, che esegue subito un comando: perfetto per lanciare una copia lunga e andare via. send-keys "scrive" dei tasti in una sessione, capture-pane -p stampa ciò che si vede nel pannello (per leggerlo con tail o grep), has-session verifica se esiste (con codice di uscita 0 o 1, utile in uno script). kill-session chiude la sessione e tutto ciò che contiene.

Esempio 7: personalizzare, con ~/.tmux.conf

$ nano ~/.tmux.conf
set -g mouse on
set -g history-limit 10000
set -g base-index 1
bind r source-file ~/.tmux.conf \; display-message "configurazione ricaricata"
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
$ tmux source-file ~/.tmux.conf

La configurazione sta nel file ~/.tmux.conf (si modifica con nano: vedi l'articolo relativo). Le righe: mouse on attiva il mouse (per scorrere, scegliere i pannelli, ridimensionarli); history-limit alza la cronologia a 10000 righe; base-index 1 numera le finestre da 1 invece che da 0, come sulla tastiera; bind r assegna a "prefisso, poi r" il ricaricamento del file; gli ultimi due bind dividono i pannelli con | e - (più facili da ricordare di % e "), tenendo la cartella corrente. L'ultimo comando ricarica la configurazione senza uscire. Le impostazioni valgono per i processi di tmux in funzione: se non le vedi applicate, chiudi tutte le sessioni o ricarica il file.

Esempio 8: lo stesso schermo di lavoro, sempre pronto

#!/bin/bash
SESSIONE=monitor

if tmux has-session -t "$SESSIONE" 2>/dev/null; then
    exec tmux attach -t "$SESSIONE"
fi

tmux new-session -d -s "$SESSIONE" -n sistema 'watch -n 2 free -h'
tmux split-window -h -t "$SESSIONE":sistema 'watch -n 5 df -h'
tmux split-window -v -t "$SESSIONE":sistema 'journalctl -f'
tmux new-window -t "$SESSIONE" -n shell
tmux select-window -t "$SESSIONE":sistema
exec tmux attach -t "$SESSIONE"

Lo script prepara in un colpo solo il quadro di controllo del server: se la sessione monitor esiste già, ti ricollega; altrimenti la crea con una finestra sistema divisa in tre pannelli (la memoria con watch e free, lo spazio con df, i registri con journalctl -f) e una seconda finestra shell libera. exec sostituisce lo script con tmux. Ho provato la creazione di sessione, pannelli e finestre in un sandbox, senza il collegamento finale, che richiede un terminale vero.

Esempio 9: un aiuto a distanza

$ tmux new -s aiuto
$ tmux attach -t aiuto
$ tmux attach -r -t aiuto

Due persone possono collegarsi alla stessa sessione, con lo stesso utente (per esempio tramite ssh con lo stesso account), e vedere e scrivere nello stesso terminale: un modo semplice di spiegare qualcosa o di lavorare in due. Con attach -r (read-only) chi si collega può solo guardare. Ricorda che è lo stesso utente: non è adatto a dare accesso a qualcuno di cui non ti fidi, perché ha in mano il tuo terminale.

Opzioni utili

  • tmux new -s nome: nuova sessione con nome; -d: la avvia già staccata; tmux new -As nome: si collega se esiste, altrimenti la crea.
  • tmux ls (list-sessions): elenca le sessioni; tmux attach -t nome (o a): ricollega; -r: sola lettura.
  • tmux kill-session -t nome, tmux kill-server: chiude una sessione o tutto tmux.
  • tmux rename-session, new-window, split-window, send-keys, capture-pane -p: comandi per gli script.
  • Prefisso Ctrl+b poi: d stacca, c nuova finestra, n/p finestra successiva/precedente, % e " dividono, z ingrandisce, [ scorre, x chiude il pannello, ? mostra tutte le combinazioni.
  • ~/.tmux.conf: configurazione; tmux list-keys: elenco di tutte le combinazioni.
  • screen: programma simile e più vecchio; nohup e &: per lanciare un solo comando che sopravvive alla chiusura del terminale.

Attenzione a

  • Non è un servizio permanente: le sessioni vivono finché il server di tmux è in funzione. Un riavvio della macchina le cancella, con tutto ciò che contengono (vedi l'articolo su uptime). Per i programmi che devono partire sempre, usa un servizio di systemd (vedi l'articolo su systemctl) o crontab, non tmux.
  • "prefisso" non è un tasto, è una sequenza: si preme Ctrl+b, si rilascia, e poi si preme il tasto successivo. Tenere premuto tutto insieme è l'errore dei primi giorni.
  • Dentro tmux, Ctrl+b non muove più il cursore indietro: nella shell bash è la scorciatoia per tornare di un carattere. Per usarla, premi il prefisso due volte (Ctrl+b due volte). Molti passano al prefisso Ctrl+a con set -g prefix C-a, ma anche Ctrl+a è usata da bash (inizio riga): è una scelta da fare con consapevolezza.
  • tmux dentro tmux: se ti colleghi con ssh a un server, da una sessione tmux locale, e lì avvii di nuovo tmux, il prefisso viene preso dal primo. Per dare un comando a quello interno, premi il prefisso due volte, e poi il tasto.
  • Con il mouse attivo, il copia e incolla cambia: tmux intercetta il mouse, e la selezione normale del terminale non funziona. Di solito si tiene premuto Maiusc mentre si trascina. La copia verso gli appunti del tuo computer, via ssh, richiede una configurazione a parte.
  • Un solo schermo per tutti: se due terminali sono collegati alla stessa sessione, tmux adatta la dimensione al più piccolo, e può sembrare che lo schermo "si rimpicciolisca".
  • Una sessione dimenticata resta attiva: i programmi che hai lasciato dentro continuano a consumare memoria e processore, e un terminale aperto come root è un rischio, perché chiunque entri con il tuo utente può collegarsi e usarlo. Controlla ogni tanto con tmux ls e chiudi ciò che non serve.
  • Uscire non è staccarsi: scrivere exit nell'ultima finestra chiude la sessione e i programmi che contiene. Per lasciare tutto in funzione si usa "prefisso, poi d".
  • I messaggi "no server running" e "sessions should be nested": il primo dice che non c'è nessuna sessione (nessun tmux avviato dopo l'ultimo riavvio); il secondo che stai per avviare tmux dentro tmux. Ciascun utente ha le proprie sessioni: quelle di root non si vedono da un altro utente.
  • Colori e tasti strani: dipendono dalla variabile TERM e dalla versione di tmux (tmux -V); se i colori sono sbagliati, vedi l'opzione default-terminal nella guida (man tmux: vedi l'articolo su man). Le combinazioni di tasti qui riportate sono quelle predefinite: se qualcuno ha modificato ~/.tmux.conf, possono essere diverse.

Riepilogo

Comando o tastoCosa fa
tmux new -s nomeAvvia una sessione con un nome
Ctrl+b, poi dSi stacca dalla sessione, che resta attiva
tmux lsElenca le sessioni
tmux attach -t nomeSi ricollega a una sessione (tmux a)
tmux new -As nomeSi collega, oppure crea se non esiste
Ctrl+b, poi c / n / pNuova finestra / successiva / precedente
Ctrl+b, poi % / "Divide il pannello in due (affiancati / sovrapposti)
Ctrl+b, poi frecce / z / xCambia pannello / ingrandisce / chiude
Ctrl+b, poi [Scorre l'uscita (si esce con q)
tmux new -d -s nome 'comando'Lancia un comando in una sessione già staccata
tmux kill-session -t nomeChiude una sessione
~/.tmux.confFile di configurazione (mouse, cronologia, tasti)