La shell li salva già
Ogni comando che scrivi finisce nella cronologia della shell, ma i valori predefiniti sono piccoli e il file si scrive solo quando la shell si chiude. Due sessioni aperte insieme possono sovrascriversi le righe a vicenda. Per bash, aggiungi questo a ~/.bashrc:
HISTSIZE=100000
HISTFILESIZE=100000
HISTCONTROL=ignoreboth
HISTTIMEFORMAT='%F %T '
shopt -s histappend
PROMPT_COMMAND='history -a'
HISTSIZEeHISTFILESIZEtengono fino a 100.000 righe in memoria e nel file.ignorebothsalta le righe ripetute e quelle che iniziano con uno spazio.HISTTIMEFORMATaggiunge data e ora ahistory.histappendehistory -aaggiungono subito ogni comando al file, così una connessione persa non perde nulla. SePROMPT_COMMANDha già un valore, mettihistory -a;davanti.
Per zsh, la shell predefinita su macOS, metti questo in ~/.zshrc:
HISTFILE=~/.zsh_history
HISTSIZE=100000
SAVEHIST=100000
setopt EXTENDED_HISTORY INC_APPEND_HISTORY HIST_IGNORE_SPACE HIST_IGNORE_DUPS
Fai lo stesso sui server che usi di più. Via SSH la cronologia si salva sul server, per l'utente con cui hai fatto l'accesso.
Ritrovare un comando
Premi Ctrl-R e scrivi una parte qualsiasi del comando. Premi ancora Ctrl-R per i risultati più vecchi, Invio per eseguire, o una freccia per modificarlo prima. Per vedere un elenco:
history | grep journalctl
Con data e ora impostate come sopra, l'elenco mostra quando è stato eseguito ogni comando:
1 2026-11-06 15:21:40 echo one
2 2026-11-06 15:21:40 diskfree /tmp
3 2026-11-06 15:21:40 uptime -p # @health
L'ultima riga mostra un trucco utile. Un commento dopo # non fa nulla quando il comando gira, ma resta nella cronologia. Aggiungi un'etichetta come # @health o # @deploy, e con Ctrl-R seguito da @health trovi tutti i comandi con quell'etichetta.
Alias e funzioni per i comandi che ripeti
Un comando che scrivi ogni settimana merita un nome corto. Un alias è testo fisso. Una funzione accetta argomenti:
alias logs='journalctl -u nginx --since "1 hour ago" --no-pager'
diskfree() { df -h "${1:-/}" | tail -n 1; }
diskfree da solo controlla /, mentre diskfree /var controlla quella cartella. Per vedere cosa fa un nome usa type logs. Gli alias funzionano solo nelle shell interattive, quindi uno script o ssh server logs non li trovano. In quei casi usa una funzione in un file caricato con source, o un piccolo script in ~/bin.
Un comando salvato per server nella configurazione SSH
Per un comando che lanci sempre su un certo server, come seguire un log, la configurazione SSH può eseguirlo all'accesso. Metti questo in ~/.ssh/config:
Host web1-logs
HostName web1
RemoteCommand tail -f /var/log/nginx/error.log
RequestTTY yes
A quel punto ssh web1-logs apre direttamente il log. RequestTTY yes dà un terminale al comando, così Ctrl-C funziona. La voce non accetta anche un comando sulla riga di comando: ssh web1-logs uptime fallisce con Cannot execute command-line and remote command. Quando serve, scavalcala:
ssh -o RemoteCommand=none web1-logs uptime
Altri esempi sono nella guida al file ssh config.
Tenerli in un unico file da portare con te
Metti alias e funzioni in un file a parte, caricalo dalla configurazione della shell e copialo sui server che usi:
mkdir -p ~/.config/shell
$EDITOR ~/.config/shell/commands.sh
echo '[ -f ~/.config/shell/commands.sh ] && . ~/.config/shell/commands.sh' >> ~/.bashrc
ssh web1 'mkdir -p ~/.config/shell' && scp ~/.config/shell/commands.sh web1:.config/shell/
Aggiungi una volta la stessa riga echo al ~/.bashrc del server. Se tieni il file in un repository git, hai la sua storia e un modo semplice per portarlo su una macchina nuova. Per mandarlo su molti server insieme, vedi come eseguire un comando su più server.
Cosa non salvare mai
I file della cronologia sono testo semplice. Una password scritta sulla riga di comando, come mysql -pS3cret, resta lì per chiunque possa leggere il file. Tre modi per tenere fuori i segreti:
- Inizia la riga con uno spazio. Con
ignorebothin bash oHIST_IGNORE_SPACEin zsh non viene salvata. - Escludi degli schemi una volta per tutte con
HISTIGNOREin bash:
HISTIGNORE='*PASSWORD*:*TOKEN*'
- Togli una riga appena scritta. Con bash 5 o successivo, questo cancella il comando precedente:
history -d -2
Questo sistema solo la cronologia in memoria. Se la riga è già finita nel file della cronologia, cancellala anche lì e cambia la password, perché potrebbe essere già stata copiata altrove. Meglio ancora, lascia che sia il programma a chiedere la password, con mysql -p senza nulla dopo, o leggi i segreti da un file con permessi stretti.
Domande
Dove salva bash la cronologia dei comandi?
In ~/.bash_history, scritto quando la shell si chiude, a meno di aggiungere history -a a PROMPT_COMMAND. zsh usa il file indicato in HISTFILE, spesso ~/.zsh_history.
La cronologia su un server contiene anche i miei comandi locali?
No. Ogni macchina tiene la propria cronologia. I comandi scritti in una sessione SSH si salvano sul server, nella cronologia dell'utente con cui hai fatto l'accesso.
Come evito che un comando venga salvato?
Inizialo con uno spazio, se in bash HISTCONTROL contiene ignorespace o se in zsh è attivo HIST_IGNORE_SPACE. Con HISTIGNORE puoi anche escludere schemi come *TOKEN*.
Che differenza c'è fra un alias e una funzione?
Un alias sostituisce la prima parola di un comando con un testo fisso. Una funzione è un piccolo programma che accetta argomenti, come una cartella o il nome di un servizio.
Fonti
- Manuale di bash: Bash History Facilities
- Manuale di bash: variabili (HISTCONTROL, HISTIGNORE)
- Manuale di zsh: opzioni della cronologia
- ssh_config(5), RemoteCommand