🌍 Italiano · Read in English →

Ti è mai capitato? Lanci un backup, una build lunga, un rsync da mezzo terabyte o un agente che macina task sul tuo VPS, chiudi il portatile per andare a prendere un caffè… e al ritorno trovi il processo morto, ammazzato insieme alla tua sessione SSH. Benvenuto nel mondo del segnale SIGHUP.

Nel 2024 avevamo scritto un cheatsheet dedicato a screen. Ma nel frattempo il modo in cui lavoriamo è cambiato: harness di sviluppo, agenti che girano per ore, sessioni remote su VPS che devono sopravvivere a una connessione ballerina (il nostro stesso stack di sviluppo vive così). screen è ancora ottimo, ma non è l'unico strumento. Quindi allarghiamo il discorso: quattro strumenti, quando usarli, e i comandi che servono davvero.

Il modello mentale: due famiglie

Prima dei comandi, la cosa più utile è capire che questi strumenti risolvono lo stesso problema in due modi diversi:

  1. Sganciare un singolo processo dal terminale, così continua a girare per conto suo → nohup (e cugini come disown, setsid). Fire and forget: lancio e me ne dimentico, l'output finisce in un file.
  2. Tenere viva un'intera sessione interattiva a cui puoi staccarti (detach) e riattaccarti (reattach) quando vuoi, con più finestre e pannelli → i multiplexer: screen, tmux, zellij. La sessione vive sul server; tu ci entri e esci.

Regola pratica: se devi solo lanciare un comando lungo e rivederne l'output dopo, nohup basta. Se vuoi lavorare dentro una sessione persistente (aprire più shell, tornarci sopra, spostarti tra pannelli), ti serve un multiplexer.


nohup — lancia e dimentica

Cos'è. Un comando che esegue un altro comando ignorando il segnale SIGHUP, quello che il sistema può inviare ai processi quando il terminale che li ha lanciati sparisce. Fa parte di GNU coreutils ed è normalmente già disponibile sulle distribuzioni Linux.

Quando usarlo. Un solo task in background, non interattivo, di cui ti basta l'output su file: un backup notturno, una compilazione lunga, uno script di migrazione. Nessuna voglia di "tornare dentro".

La caratteristica fondamentale di nohup è che devi pensarci prima: decidi fin dall'inizio che quel processo dovrà continuare a vivere anche dopo la chiusura della sessione SSH.

Comandi essenziali.

# Lancia in background e ignora SIGHUP.
# Senza redirect, l'output va normalmente su ./nohup.out
nohup ./backup.sh &

# Meglio: redirigi stdout+stderr su un log tuo
nohup ./backup.sh > backup.log 2>&1 &

# Controlla che stia girando e segui il log
jobs -l
ps aux | grep backup.sh
tail -f backup.log

Ma cosa succede se non ci avevi pensato prima?

Hai lanciato il tuo comando normalmente:

./long_task.sh

Il processo sta lavorando in foreground e occupa il terminale. Solo dopo mezz'ora ti ricordi che devi chiudere il portatile, terminare la connessione SSH o semplicemente andare via.

È qui che disown diventa davvero interessante.

Prima sospendi temporaneamente il processo con:

Ctrl-Z

Bash ti restituisce il prompt. A quel punto:

bg                # riprende il processo in background
disown -h %1      # evita che Bash gli invii SIGHUP

La sequenza completa, quindi, è:

./long_task.sh

# ...ops, devo chiudere la sessione SSH...

# Ctrl-Z          → sospende il processo
bg                # lo riprende in background
disown -h %1      # lo protegge dal SIGHUP della shell

Ed è proprio questa la differenza pratica interessante tra i due.

Con:

./long_task.sh &
disown -h %1

devi comunque sapere prima che vuoi lasciare il processo in background. A quel punto tanto vale normalmente partire direttamente con nohup.

Il vero superpotere di disown è invece il piano B: hai già lanciato un processo in foreground, magari gira da parecchio tempo, e solo dopo ti accorgi che devi abbandonare la sessione SSH.

Ctrl-Z → bg → disown e il lavoro può continuare.

Nota tecnica: con -h, disown non rimuove il job dalla job table; lo marca in modo che Bash non gli invii SIGHUP.

E setsid? Permette di avviare il comando in una nuova sessione, separandolo ulteriormente dal contesto del terminale:

setsid ./long_task.sh > out.log 2>&1

Anche qui, però, siamo nel caso “ci penso prima”.

Ma cosa significa > out.log 2>&1?
> out.log manda (ridireziona) l’output normale del comando (stdout) nel file out.log. 2>&1 dice di mandare nello stesso posto anche gli errori (stderr). In pratica: tutto quello che il comando avrebbe scritto sul terminale, messaggi ed errori compresi, finisce in out.log.

comando > out.log 2>&1
#          ↑          ↑
#       output     errori
#       nel file   nello stesso file

Gotcha. Con nohup e disown non c'è reattach: il processo continua a lavorare, ma non puoi rientrare nella sua sessione come faresti con screen, tmux o zellij. Per questo funzionano bene con task non interattivi e output rediretto su file.


screen — il classico intramontabile

Cos'è. Uno dei multiplexer di terminale storici più diffusi. GNU Screen esiste dagli anni '80 e crea sessioni persistenti a cui puoi staccarti e riattaccarti. È ancora molto comune, soprattutto sui server meno recenti.

Quando usarlo. Ti connetti a macchine eterogenee, magari datate, dove non vuoi o non puoi installare altro e vuoi qualcosa che molto probabilmente conosci già. O semplicemente lo usi da vent'anni e le dita vanno da sole.

Installazione.

sudo apt install screen     # Debian/Ubuntu
sudo dnf install screen     # Fedora/RHEL

Comandi essenziali. Il tasto di comando (prefix) è Ctrl-a.

screen -S lavoro        # crea una sessione di nome "lavoro"

# ...dentro la sessione...

# Ctrl-a d              → detach
#                         la sessione resta viva sul server

screen -ls              # elenca le sessioni
screen -r lavoro        # riattacca la sessione
screen -x lavoro        # attach condiviso

Dentro la sessione:

  • Ctrl-a c → nuova finestra
  • Ctrl-a n / Ctrl-a p → finestra successiva / precedente
  • Ctrl-a " → elenco delle finestre
  • Ctrl-a Esc → modalità copia / scrollback
  • Ctrl-a d → detach

Quando screen non collabora

Qui arrivano alcuni dei comandi più utili in assoluto.

La connessione SSH è caduta ma la sessione risulta ancora Attached

È un classico: perdi la connessione SSH, ti ricolleghi subito, fai:

screen -ls

e trovi qualcosa del genere:

12345.lavoro    (Attached)

Screen pensa che la vecchia connessione sia ancora viva e quindi un normale:

screen -r lavoro

può rifiutarsi di riattaccare la sessione.

Invece di aspettare, puoi dire a Screen:

screen -d -r lavoro

Il significato è molto semplice:

-d    detach dalla vecchia connessione
-r    reattach su questa

In pratica: staccala da dove credi che sia ancora collegata e dammela qui.

È probabilmente uno dei comandi Screen più utili da ricordare.

Voglio staccare una sessione dall'esterno

Può capitare di voler fare detach senza riuscire o senza voler entrare nella sessione:

screen -S lavoro -X detach

La sessione continua a vivere, semplicemente non resta più associata al terminale precedente.

La sessione è completamente impazzita

Terminale corrotto, programma bloccato, input che non risponde, sessione ormai ingestibile.

Certo, potresti aprire un'altra shell, fare:

ps -ef

cercare il processo giusto e poi usare kill.

Ma quando ci sono più processi simili non è sempre divertente, e soprattutto non è difficile ammazzare quello sbagliato.

Se vuoi eliminare direttamente l'intera sessione Screen:

screen -S lavoro -X quit

Questo termina la sessione Screen dall'esterno.

È il martello: usalo quando vuoi davvero terminare la sessione Screen. I programmi ancora legati ai suoi terminali normalmente termineranno con essa; eventuali processi che si sono già sganciati o daemonizzati possono invece continuare a vivere.

Prima di arrivare al quit, se hai qualche speranza che la sessione sia ancora recuperabile, puoi provare:

screen -S lavoro -X detach
screen -d -r lavoro

Se continua a essere irrecuperabile:

screen -S lavoro -X quit

Ripulire le sessioni morte

Dopo crash, reboot o connessioni terminate male può capitare che screen -ls mostri sessioni morte o riferimenti ormai inutili.

Puoi ripulirli con:

screen -wipe

Non termina le sessioni sane: serve a rimuovere dall'elenco quelle che non esistono più realmente.

Kit di pronto soccorso Screen

# elenco sessioni
screen -ls

# normale reattach
screen -r lavoro

# la sessione risulta ancora Attached:
# forza detach + reattach
screen -d -r lavoro

# staccala dall'esterno senza terminarla
screen -S lavoro -X detach

# sessione irrecuperabile: termina tutto
screen -S lavoro -X quit

# ripulisci le sessioni morte
screen -wipe

Se usi Screen spesso, probabilmente questi sei comandi sono più utili di metà delle shortcut disponibili.

Gotcha. Il prefix Ctrl-a va in conflitto con la scorciatoia Bash "vai a inizio riga" (devi premere Ctrl-a a). Lo scroll con il mouse è scomodo e la configurazione (.screenrc) è decisamente spartana rispetto alle alternative moderne.

Ma Screen ha un pregio enorme: è semplice, robusto e, quando qualcosa va storto, con screen -d -r, -X quit e -wipe riesci quasi sempre a rimettere ordine senza andare a caccia di PID.


tmux — lo standard de facto moderno

Cos'è. Una delle scelte moderne più comuni quando si parla di terminal multiplexer. Fa tutto quello che fa Screen, ma aggiunge una gestione molto più comoda di finestre e pannelli, un'ottima possibilità di scripting e soprattutto una configurazione molto potente tramite ~/.tmux.conf.

Se devi imparare un solo multiplexer, probabilmente partirei da qui.

Installazione

Su Debian/Ubuntu:

sudo apt update
sudo apt install tmux

Su Fedora/RHEL:

sudo dnf install tmux

Controlliamo che ci sia:

tmux -V

Poi creiamo la prima sessione:

tmux new -s dev

Sei dentro tmux.

Il tasto di comando, chiamato prefix, di default è:

Ctrl-b

Questo significa che quasi tutti i comandi tmux si fanno premendo prima Ctrl-b, rilasciandolo, e poi il secondo tasto. Per esempio Ctrl-b d fa detach dalla sessione.

tmux ls
tmux attach -t dev

Ed eccoci già al comportamento che ci interessa: puoi chiudere SSH, tornare più tardi e riattaccarti alla stessa sessione.

Prima di imparare le scorciatoie: sistemiamo tmux

Tmux funziona benissimo anche appena installato, ma qualche modifica rende l'esperienza molto più piacevole.

Il file di configurazione dell'utente è:

~/.tmux.conf

Se non esiste:

nano ~/.tmux.conf

E come primo config metterei questo:

# -----------------------------
# Mojalab starter .tmux.conf
# -----------------------------

# Usa Ctrl-a come prefix invece di Ctrl-b
set -g prefix C-a
unbind C-b
bind C-a send-prefix

# Mouse: selezione pannelli, resize, scroll
set -g mouse on

# Le finestre partono da 1 invece che da 0
set -g base-index 1

# Anche i pannelli partono da 1
setw -g pane-base-index 1

# Più scrollback
set -g history-limit 50000

# Nuove finestre nella directory corrente
bind c new-window -c "#{pane_current_path}"

# Split mantenendo la directory corrente
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"

# Ricarica il config senza uscire da tmux
bind r source-file ~/.tmux.conf \; display-message "tmux.conf ricaricato"

Ora ricaricalo:

tmux source-file ~/.tmux.conf

Oppure, da dentro tmux, dopo la prima volta puoi semplicemente usare:

Ctrl-a r

Cosa abbiamo appena cambiato?

1. Ctrl-a al posto di Ctrl-b

Di default tmux usa Ctrl-b, ma il prefix può essere cambiato direttamente nel config.

Noi usiamo:

set -g prefix C-a
unbind C-b
bind C-a send-prefix

Così chi arriva da Screen si ritrova subito a casa:

Ctrl-a d

fa detach.

Attenzione solo a una cosa: Ctrl-a è anche la scorciatoia Bash per andare a inizio riga. Se vuoi mandare un vero Ctrl-a al programma dentro tmux, premi:

Ctrl-a Ctrl-a

2. Accendiamo il mouse

set -g mouse on

Sembra una banalità, ma cambia parecchio l'esperienza.

Puoi usare il mouse per:

  • selezionare un pannello;
  • ridimensionare i pannelli;
  • cambiare finestra dalla barra di stato;
  • usare la rotella per lo scroll.

Tmux supporta tutto questo nativamente quando l'opzione mouse è attiva.

3. Numeriamo da 1

Di default tmux parte da finestra 0.

Noi facciamo:

set -g base-index 1
setw -g pane-base-index 1

Così finestre e pannelli iniziano da 1, che personalmente trovo più naturale.

4. Aumentiamo lo scrollback

set -g history-limit 50000

Tmux conserva lo storico dell'output di ogni pannello. Alzare il limite è utile quando dentro una sessione girano build, log o agenti che producono parecchio output.

5. Nuove finestre e split restano nella directory corrente

Questa è una delle modifiche che si sente subito.

Senza configurazione, quando apri una nuova finestra o un nuovo pannello potresti non ritrovarti nella directory in cui stavi lavorando.

Noi diciamo:

bind c new-window -c "#{pane_current_path}"
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"

Così se sei in:

/var/www/myproject

e apri una nuova finestra o fai uno split, anche il nuovo terminale parte da lì. È una configurazione consigliata anche nelle recipe ufficiali di tmux.

Le scorciatoie che servono davvero

Con il nostro config il prefix è Ctrl-a.

Ctrl-a d        detach

Ctrl-a c        nuova finestra
Ctrl-a n        finestra successiva
Ctrl-a p        finestra precedente

Ctrl-a %        split affiancato
Ctrl-a "        split sopra/sotto

Ctrl-a frecce   cambia pannello

Ctrl-a z        zoom del pannello corrente
Ctrl-a [        modalità copia / scroll

Ctrl-a ?        mostra tutti i key binding

Ctrl-a r        ricarica ~/.tmux.conf

Gli split % e " e il comando ? per mostrare l'help fanno parte dei binding standard di tmux.

Sessioni: creare, entrare, uscire e distruggere

# nuova sessione
tmux new -s dev

# elenco sessioni
tmux ls

# riattacca
tmux attach -t dev

# abbreviazione equivalente
tmux a -t dev

Per fare detach dall'interno:

Ctrl-a d

Se invece una sessione è completamente da buttare:

tmux kill-session -t dev

Oppure, se vuoi fermare tutto tmux, comprese tutte le sessioni:

tmux kill-server

Quest'ultimo è decisamente il pulsante rosso.

E se la sessione risulta già attached?

Qui tmux è un po' più amichevole di Screen.

Puoi collegarti e contemporaneamente scollegare gli altri client dalla stessa sessione con:

tmux attach -d -t dev

In pratica:

-d    scollega gli altri client
-t    scegli la sessione

È l'equivalente concettuale del nostro:

screen -d -r lavoro

Il bello dei pannelli

Qui tmux comincia davvero a differenziarsi dal modo classico di usare Screen.

Puoi avere, dentro la stessa finestra:

+----------------------+-------------------+
|                      |                   |
|   editor / agent     |     tail log      |
|                      |                   |
|                      +-------------------+
|                      |                   |
|                      |       shell       |
+----------------------+-------------------+

Per esempio:

Ctrl-a %

divide verticalmente la finestra, creando due pannelli affiancati.

Poi:

Ctrl-a "

divide il pannello corrente sopra/sotto.

E con:

Ctrl-a frecce

ti sposti tra i vari terminali.

Se vuoi temporaneamente vedere un pannello a tutto schermo:

Ctrl-a z

Lo ripremi e torni al layout precedente.

Un piccolo .tmux.conf, non una religione

Online troverai .tmux.conf da centinaia di righe, plugin manager, temi, status bar con CPU, RAM, Git, meteo e probabilmente anche le fasi lunari.

Non serve partire da lì.

Il nostro primo config fa solo alcune cose concrete:

Ctrl-a
mouse
numerazione da 1
scrollback più grande
directory corrente preservata
reload veloce

Ed è già abbastanza per trasformare tmux da “Screen con tasti diversi” in uno strumento molto più comodo da usare tutti i giorni.

Poi, se nasce l'esigenza, si può andare oltre: plugin, salvataggio delle sessioni, layout automatici, integrazione con editor e molto altro.

Ma prima conviene imparare a vivere bene dentro una sessione tmux.

Bonus: tmux-resurrect — e dopo un reboot?

Abbiamo visto che una sessione tmux sopravvive tranquillamente alla caduta della connessione SSH.

Ma se a cadere è il server?

Normalmente la risposta è semplice: addio sessione. Un reboot termina tmux e, naturalmente, tutti i processi che stavano girando al suo interno.

Qui entra in gioco tmux-resurrect, uno dei plugin più interessanti dell'ecosistema tmux.

L'idea è semplice: Resurrect salva la struttura del nostro ambiente tmux e permette di ricostruirla successivamente.

Può ricordare, tra le altre cose:

  • sessioni;
  • finestre;
  • pannelli;
  • layout;
  • directory di lavoro;
  • alcuni programmi in esecuzione.

Attenzione però: non congela i processi in RAM e non li fa sopravvivere magicamente al reboot.

Salva abbastanza informazioni da poter ricostruire il workspace e, per alcuni programmi, rilanciare ciò che stava girando.

Installiamolo con TPM

Il modo più comodo per gestire i plugin di tmux è TPM — Tmux Plugin Manager.

Per prima cosa cloniamolo:

git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

Poi apriamo il nostro:

nano ~/.tmux.conf

e aggiungiamo in fondo al file:

# -----------------------------
# Plugin
# -----------------------------

# tmux-resurrect
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'

# Avvia TPM
run '~/.tmux/plugins/tpm/tpm'

È importante che la riga:

run '~/.tmux/plugins/tpm/tpm'

rimanga in fondo alla parte dedicata ai plugin.

Ora ricarichiamo la configurazione:

tmux source-file ~/.tmux.conf

Poi, da dentro tmux, premiamo:

Ctrl-a I

La I è maiuscola: TPM installerà i plugin dichiarati nel .tmux.conf.

Ricordiamoci che Ctrl-a è il nostro prefix personalizzato; con una configurazione tmux standard sarebbe Ctrl-b.

Salviamo il nostro workspace

Supponiamo di avere una sessione dev con tre pannelli:

+----------------------+-------------------+
|                      |                   |
|   progetto           |    tail log       |
|                      |                   |
|                      +-------------------+
|                      |                   |
|                      |      shell        |
+----------------------+-------------------+

Per salvarne lo stato premiamo:

Ctrl-a Ctrl-s

Resurrect salva lo stato corrente.

Possiamo continuare a lavorare normalmente.

Ripristiniamolo

Dopo un reboot avviamo nuovamente tmux:

tmux

e premiamo:

Ctrl-a Ctrl-r

Resurrect prova a ricostruire il workspace salvato: sessioni, finestre, pannelli, layout e directory.

Quindi i due comandi da ricordare sono praticamente questi:

Ctrl-a Ctrl-s    → SAVE

Ctrl-a Ctrl-r    → RESTORE

Possiamo fare ancora meglio

Resurrect richiede che siamo noi a salvare lo stato.

Esiste però un altro plugin della stessa famiglia, tmux-continuum, che può automatizzare periodicamente il salvataggio e integrare ulteriormente il ripristino delle sessioni.

Nel .tmux.conf possiamo aggiungere:

set -g @plugin 'tmux-plugins/tmux-continuum'

La nostra sezione plugin diventa quindi:

# -----------------------------
# Plugin
# -----------------------------

set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

run '~/.tmux/plugins/tpm/tpm'

Ricarichiamo:

tmux source-file ~/.tmux.conf

e installiamo il nuovo plugin:

Ctrl-a I

Continuum può salvare automaticamente lo stato di tmux a intervalli regolari, evitando di dover ricordare ogni volta Ctrl-a Ctrl-s.

Ma non confondiamolo con systemd

Questo è il punto più importante.

tmux-resurrect e tmux-continuum sono fantastici per ricostruire un ambiente di lavoro.

Non sono però un sostituto di systemd.

Se dopo un reboot vogliamo ritrovare:

sessione dev
├── editor
├── shell in /var/www/myproject
└── finestra dei log

Resurrect è esattamente lo strumento giusto.

Se invece abbiamo:

python worker.py

e quel worker deve essere sempre attivo, deve partire automaticamente al boot e deve essere riavviato se crasha, non dovremmo affidarci a tmux.

Quello è un servizio.

E lì vogliamo qualcosa come:

systemd
supervisor
Docker restart policy

La differenza è sottile ma fondamentale:

tmux-resurrect
      ↓
ricostruisce il nostro ambiente di lavoro

systemd / supervisor / Docker
      ↓
garantiscono il ciclo di vita del servizio

Resurrect è per noi che torniamo a lavorare.

Un service manager è per il processo che deve lavorare anche senza di noi.


zellij — il nuovo arrivato che ti prende per mano

Cos'è. Zellij è un multiplexer moderno scritto in Rust, ma parte da una filosofia abbastanza diversa da quella di tmux.

Con tmux installi uno strumento potentissimo e poi, piano piano, costruisci il tuo ambiente: .tmux.conf, scorciatoie, plugin, TPM, Resurrect...

Zellij prova invece a fare una cosa diversa: essere piacevole da usare già trenta secondi dopo l'installazione.

Entri e trovi subito pannelli, tab, gestione delle sessioni, layout, pannelli flottanti e soprattutto una barra inferiore che ti ricorda continuamente quali comandi puoi usare.

In altre parole: invece di pretendere che tu impari il multiplexer, cerca di insegnartelo mentre lo usi.

Installazione

Zellij difficilmente sarà già presente su un server, quindi quasi sicuramente dovremo installarlo.

Se abbiamo Rust e Cargo:

cargo install --locked zellij

Controlliamo:

zellij --version

Poi possiamo semplicemente partire:

zellij

Oppure, meglio ancora, diamo subito un nome alla sessione:

zellij -s dev

Ed eccoci dentro.

La prima differenza si vede subito

La cosa interessante è quello che troviamo in fondo allo schermo.

Zellij lavora attraverso diverse modalità e mostra le scorciatoie disponibili direttamente nell'interfaccia.

Qualcosa concettualmente simile a:

+----------------------------------------------------+
|                                                    |
|                     shell                          |
|                                                    |
|                                                    |
+----------------------------------------------------+
| Ctrl-p PANE | Ctrl-t TAB | Ctrl-o SESSION | ...   |
+----------------------------------------------------+

Non dobbiamo quindi ricordarci immediatamente venti combinazioni di tasti.

Se vogliamo lavorare con i pannelli:

Ctrl-p

entriamo nella modalità Pane e Zellij ci mostra cosa possiamo fare.

Per esempio possiamo creare un nuovo pannello, spostarci tra quelli esistenti, ridimensionarli o chiuderli.

Per lavorare con i tab:

Ctrl-t

Per le operazioni sulla sessione:

Ctrl-o

Questa è probabilmente la differenza più evidente rispetto a Screen e tmux: Zellij cerca continuamente di essere scopribile.

Costruiamo un workspace vero

Immaginiamo di lavorare su un progetto e di volere:

  • il nostro editor o agente sulla sinistra;
  • i log in alto a destra;
  • una shell in basso a destra.

Il risultato potrebbe essere:

+----------------------------------------------------+
| TAB: dev                                           |
+-------------------------------+--------------------+
|                               |                    |
|                               |  tail -f app.log   |
|       editor / agent          |                    |
|                               +--------------------+
|                               |                    |
|                               |      shell         |
+-------------------------------+--------------------+
| Ctrl-p PANE | Ctrl-t TAB | Ctrl-o SESSION | ...   |
+----------------------------------------------------+

Ed è esattamente il genere di ambiente per cui un multiplexer comincia ad avere molto più senso di una semplice shell persistente.

I pannelli flottanti

Poi Zellij tira fuori una delle sue caratteristiche più simpatiche: i floating panes.

Invece di dividere ulteriormente il nostro layout, possiamo aprire un terminale temporaneo sopra quello che stiamo facendo.

Concettualmente:

+----------------------------------------------------+
|                                                    |
|          editor / agent          log               |
|                                                    |
|        +------------------------------+            |
|        |                              |            |
|        |       floating shell         |            |
|        |                              |            |
|        +------------------------------+            |
|                                                    |
+----------------------------------------------------+

È comodissimo per quelle operazioni da trenta secondi per cui non vogliamo distruggere il layout: controllare un processo, fare un git status, lanciare un comando o dare un'occhiata veloce a qualcosa.

Ed è una buona dimostrazione della filosofia di Zellij: parecchie comodità che altrove richiedono configurazione qui sono già parte dell'esperienza normale.

Sessioni: staccarsi e tornare

Naturalmente possiamo fare quello per cui siamo arrivati fin qui: lasciare viva la sessione quando usciamo da SSH.

Possiamo vedere le sessioni disponibili con:

zellij list-sessions

e rientrare nella nostra:

zellij attach dev

Da dentro Zellij possiamo entrare nella modalità Session con:

Ctrl-o

e fare detach.

Qui ricordiamoci la distinzione importante:

detach → usciamo, ma la sessione continua a vivere.

quit → terminiamo Zellij e quindi la sessione.

Se dentro sta macinando qualcosa che vogliamo ritrovare dopo, vogliamo fare detach, non quit.

Il Session Manager

Zellij dispone anche di un gestore delle sessioni integrato.

Con i keybinding di default lo apriamo con:

Ctrl-o w

Da lì possiamo vedere e cambiare sessione, crearne una nuova, rinominarla, scollegare altri client e gestire le sessioni senza ricordare necessariamente nomi e comandi da shell.

E c'è una sorpresa interessante: le versioni moderne di Zellij conservano anche i metadati delle sessioni terminate e possono resuscitarne il contesto, ricostruendo layout, tab, pannelli e i comandi che vi erano associati.

Questo non significa che i vecchi processi siano sopravvissuti al reboot: esattamente come per tmux-resurrect, viene ricostruito il workspace e i comandi possono essere rilanciati. La memoria runtime del vecchio processo è andata persa.

È un'altra piccola differenza filosofica: Zellij non vuole essere soltanto un processo invisibile che gestiamo attraverso comandi, ma un vero ambiente di lavoro interattivo.

E se invece il workspace lo preparassimo prima?

Qui arriviamo a una delle caratteristiche più interessanti: i layout.

Possiamo descrivere come deve essere organizzato il nostro ambiente e chiedere a Zellij di costruircelo.

Creiamo, per esempio, un layout per il nostro progetto:

mkdir -p ~/.config/zellij/layouts
nano ~/.config/zellij/layouts/mojalab-dev.kdl

Un primo layout potrebbe essere:

layout {
    tab name="dev" {
        pane split_direction="vertical" {
            pane size="65%"
            pane {
                pane command="tail" {
                    args "-f" "app.log"
                }
                pane
            }
        }
    }
}

L'idea è semplice:

TAB dev
│
├── 65% → pannello principale
│
└── 35%
    ├── tail -f app.log
    └── shell

Ora possiamo partire direttamente con:

zellij --layout mojalab-dev

e Zellij ci prepara il tavolo di lavoro.

Questa è una differenza interessante rispetto al semplice “riaprire tre terminali”: stiamo descrivendo il nostro workspace come configurazione.

Possiamo quindi avere layout diversi:

mojalab-dev.kdl
backend.kdl
monitoring.kdl
production-debug.kdl

e aprire l'ambiente che ci serve quando ci serve.

Anche Zellij ha il suo file di configurazione

Naturalmente possiamo personalizzarlo.

Il file principale è:

~/.config/zellij/config.kdl

Ma qui c'è una differenza importante rispetto a quello che abbiamo appena fatto con tmux:

non abbiamo bisogno di partire modificandolo.

Possiamo tranquillamente usare Zellij con i suoi default, imparare come ragiona e solo dopo cambiare ciò che realmente ci infastidisce.

Possiamo anche farci generare una configurazione di partenza:

mkdir -p ~/.config/zellij
zellij setup --dump-config > ~/.config/zellij/config.kdl

A quel punto abbiamo davanti tutte le opzioni disponibili e possiamo modificarle con calma.

È quasi l'approccio opposto rispetto al nostro .tmux.conf: invece di costruire subito il nostro tmux ideale, con Zellij possiamo partire dai default e togliere o cambiare solo quello che non ci piace.

Quindi Zellij è meglio di tmux?

No.

Ed è probabilmente la domanda sbagliata.

Tmux ha anni di maturità, un ecosistema enorme, configurazioni praticamente infinite, scripting eccellente e una quantità gigantesca di documentazione.

Possiamo trasformarlo esattamente nello strumento che vogliamo.

Zellij parte invece da un'altra idea: forse non dovremmo essere obbligati a trasformarlo prima di poterlo usare comodamente.

Per chi conosce tmux a memoria e ha un .tmux.conf perfezionato negli anni, cambiare potrebbe non avere alcun senso.

Per chi invece installa oggi per la prima volta un terminal multiplexer, Zellij è molto interessante proprio perché dopo pochi minuti pannelli, tab, sessioni e layout cominciano già ad avere senso.


A colpo d'occhio

Strumento Cosa persiste Reattach interattivo Finestre / pannelli Curva Di solito preinstallato Ideale per
nohup Singolo processo No No Bassissima Sì Un comando lungo, fire-and-forget
screen Sì Sì Sì (base) Media Spesso Server datati, "c'è già"
tmux Sì Sì Sì (ottimo) Media A volte Lavoro quotidiano, scripting, standard
zellij Sì Sì Sì (moderno) Bassa No Partire subito, zero config

E allora quale scelgo?

  • Devo solo lanciare un processo e rivederne l'output dopo → nohup (con il redirect su file). Semplice, normalmente già disponibile.
  • Voglio una sessione di lavoro remota persistente e devo scegliere una cosa sola da imparare → tmux. È lo standard, lo troverai ovunque nella documentazione e nei dotfiles altrui.
  • Sono su una macchina vecchia dove non installo nulla → screen, quasi certamente c'è già.
  • Comincio adesso e voglio produttività immediata senza smanettare → zellij.

Nel nostro caso — un VPS che ospita harness di sviluppo e processi che devono sopravvivere a ore di lavoro e a connessioni instabili — la combinazione vincente è tmux per le sessioni di lavoro (ci stacchi, chiudi il laptop, torni e ritrovi tutto) più nohup per i task batch fire-and-forget che non richiedono interazione. Due strumenti, due lavori diversi, zero processi ammazzati dalla disconnessione.

🔗 Correlato: quel VPS da 5€ — e come tengo d'occhio i miei coding-agent direttamente dal browser — ha una storia tutta sua: I miei coding-agent vivono su un VPS da 5€.

Quattro strumenti, quattro caratteri

A questo punto possiamo descrivere tutto l'articolo in maniera molto meno scientifica, ma forse più efficace:

Screen è il caro, vecchio e affidabile coltellino svizzero che trovi nel cassetto.

tmux è l'officina che puoi attrezzare esattamente come vuoi.

Zellij è l'officina moderna che quando entri ha già gli attrezzi appesi al posto giusto.

E nohup è quello a cui lanciamo il martello mentre usciamo dall’officina: «continua tu, io me ne vado». 😂

E, stranamente, è anche un discreto criterio per scegliere quale usare.

E se deve sopravvivere anche a un reboot?

Ne abbiamo già parlato nella parte di tmux ma vale la pena approfondire:

nohup, screen, tmux e zellij proteggono il nostro lavoro dalla fine della connessione SSH, ma un reboot del server è un'altra storia: se la macchina si spegne, i processi che stavano girando vengono terminati.

tmux-resurrect e la session resurrection di Zellij ricostruiscono il workspace; non rendono magicamente persistenti i processi.

Se avevi una shell aperta in /var/www/myproject, può ricreartela lì. Se avevi un determinato comando in esecuzione, in alcuni casi può rilanciarlo. Ma il vecchio processo, con la sua memoria e il suo stato runtime, è morto durante il reboot.

Quindi possiamo pensare a tre livelli diversi:

Cade SSH
    ↓
nohup / screen / tmux / zellij
    ↓
il lavoro continua a girare

Reboot del server
    ↓
tmux + tmux-resurrect / Zellij session resurrection
    ↓
posso ricostruire il mio ambiente di lavoro

Il processo DEVE essere sempre disponibile
e ripartire automaticamente se muore
    ↓
systemd / supervisor / container restart policy

Quest'ultimo è il confine importante.

Se stiamo facendo sviluppo e vogliamo ritrovare velocemente il nostro ambiente dopo un reboot, tmux-resurrect o la session resurrection integrata di Zellij sono esattamente il genere di comodità che vogliamo.

Se invece quel processo è un'applicazione, un worker, un demone o qualcosa che deve partire al boot e deve essere riavviato automaticamente in caso di crash, non dobbiamo affidarci a una sessione tmux.

Lì siamo nel territorio di systemd, di un process supervisor oppure — se lavoriamo con container — delle restart policy di Docker.

In breve:

sessione SSH che cade → rendi persistente processo o terminale

server che riparte → puoi ricostruire il workspace

servizio che deve esserci sempre → usa un vero service manager

Sembrano problemi simili, ma sono tre esigenze diverse.

Conclusione

SIGHUP non deve più spaventarti. Che tu scelga il minimalismo di nohup, l'onnipresenza di screen, la potenza di tmux o la freschezza di zellij, il principio è lo stesso: il tuo lavoro vive sul server, non nella fragile sessione SSH che ci passa sopra. Scegli lo strumento in base al compito, non per moda — e la prossima volta che chiudi il portatile, il tuo backup (o il tuo agente) continuerà a lavorare come se niente fosse.