Linux / Comando history di Bash: cercare e riutilizzare i comandi
Il comando history in Bash mostra i comandi precedenti conservati dalla shell corrente, con i rispettivi numeri, e permette di cercarli, richiamarli, eliminare voci o sincronizzare la lista con il file di cronologia. Per visualizzare solo gli ultimi pochi comandi, usa history 20; per cercare una stringa specifica, usa history | grep 'testo'; e per trovare rapidamente comandi mentre digiti, usa Ctrl+r.
history è un comando integrato in Bash. La spiegazione in questo articolo si basa su Bash, e altre shell come Zsh o Fish possono avere file di cronologia e impostazioni differenti.
Cos'è il comando history?
Bash memorizza i comandi inseriti dall'utente in una shell interattiva in una lista di cronologia in memoria. history è un comando che permette di visualizzare e modificare questa lista e leggere o scrivere il file di cronologia indicato da HISTFILE.
Con la cronologia abilitata, Bash interattivo legge normalmente ~/.bash_history all’avvio e salva le nuove voci all’uscita. Se histappend è attiva le aggiunge, altrimenti può sovrascrivere il file. Variabili e file di inizializzazione possono cambiare questi valori: il comportamento è descritto nel manuale GNU Bash, sezione HISTORY.
La cronologia dei comandi è una funzione di comodità, non un registro di audit di sicurezza. Gli utenti possono eliminare le voci e, se la shell termina in modo anomalo o la registrazione della cronologia è disabilitata, potrebbe non essere salvata.
Uso di base
- Per esercitarti senza leggere o riscrivere la tua cronologia salvata, avvia una Bash temporanea dal terminale con
HISTFILE=/dev/null bash --noprofile --norc. Le modifiche successive riguardano questa shell figlia. - Inserisci
printf 'demo\n', poihistory: vedrai la riga registrata con un numero. Usa soltanto comandi dimostrativi in questa sessione. - Al termine digita
exitper tornare alla shell precedente. I comandi eseguiti nella shell temporanea non vengono salvati nel tuo normale file di cronologia; il comando che l’ha avviata può restare nella cronologia della shell esterna.
Senza opzioni, history mostra la lista della sessione Bash corrente con i numeri delle voci. Il comando di consultazione stesso può comparire nella lista.
history
Questo è un esempio illustrativo: numeri e comandi effettivi dipendono dalla sessione. Le righe mostrate sono dati della cronologia, non istruzioni da eseguire.
241 apt update
242 systemctl status ssh
243 journalctl -u ssh
244 history
Per visualizzare solo una porzione recente della cronologia, come le ultime 20 voci, specificare un numero.
history 20
| Formato | Funzione | Avvertenze |
|---|---|---|
history n |
Visualizzare le ultime n voci | Si basa sulla lista in memoria della shell corrente. |
history -c |
Cancella tutta la lista corrente in memoria | Lo stato di altre sessioni shell e dei file deve essere considerato separatamente. |
history -d numero |
Elimina l'elemento specificato | Per prima cosa, controlla se il numero da eliminare è corretto. |
history -a |
Aggiungi nuovi elementi di questa sessione alla fine del file | HISTFILE deve essere impostato. |
history -n |
Aggiungi nuove voci dal file all'elenco corrente | Utile per leggere le voci aggiunte al file da un’altra sessione. |
history -r |
Aggiungi l'intero file di cronologia all'elenco corrente | Può creare voci duplicate che già esistono. |
history -w |
Sovrascrivi il file di cronologia con l'elenco corrente | Se sono aperti più terminali, potrebbe influenzare la cronologia di altre sessioni. |
history -p espressione |
Stampa solo i risultati dell'espansione della cronologia | È utile per controllare il risultato espanso di ! prima dell'esecuzione. |
history -s comando |
Aggiungi alla cronologia senza eseguire il comando | Gli argomenti diventano una sola voce; in uso interattivo sostituiscono normalmente la riga history -s appena registrata. |
Per le definizioni esatte e gli stati restituiti da ciascuna opzione, consulta il manuale GNU Bash per il comando integrato history.
Ricerca dei comandi precedenti
Filtraggio della lista con grep
Per filtrare le righe della cronologia, collega history a grep con una pipe. Grep interpreta il modello come un’espressione regolare; per una stringa letterale contenente caratteri speciali puoi usare grep -F.
history | grep 'systemctl'
Per ignorare le maiuscole e minuscole, usa grep -i.
history | grep -i 'nginx'
Questo metodo è comodo per controllare i risultati, ma il comando di ricerca corrente incluso nell'output può apparire anche nei risultati.
Ricerca interattiva con Ctrl+r
Se Bash sta utilizzando la modalità di modifica base di Emacs, puoi eseguire una ricerca incrementale inversa dei comandi precedenti con Ctrl+r. Ogni volta che digiti un carattere per cercare, viene visualizzata la voce corrispondente più recente, e premendo di nuovo Ctrl+r si passa al risultato precedente.
Enter: Esegue il comando visualizzato.- Tasti freccia sinistra/destra: Termina la ricerca e modifica il comando.
Ctrl+g: Annulla la ricerca e ritorna all'input originale.
Con i tasti predefiniti di Emacs, termina la ricerca con una freccia per modificare la riga prima di premere Invio. Le associazioni personalizzate e la modalità vi possono cambiare i tasti; il manuale di Readline incluso in Bash descrive ricerca incrementale e comandi di movimento.
Richiamare ed eseguire comandi precedenti
Espansione della cronologia usando i punti esclamativi
In Bash interattivo, puoi usare l'espansione della cronologia iniziando con ! per richiamare comandi precedenti.
| Espressione | Significato | Esempio |
|---|---|---|
!! |
Comando precedente | sudo !! antepone sudo al comando precedente: lo spazio è necessario. Controlla prima cosa verrà eseguito e con quali privilegi. |
!125 |
Comando con numero di cronologia 125 | Puoi controllare il numero dall'output di history. |
!-3 |
Il terzo comando precedente dalla posizione corrente | Seleziona i comandi recenti per posizione relativa. |
!ssh |
Il comando più recente che inizia con ssh | Se ci sono molti comandi con lo stesso prefisso, potrebbe essere selezionato un elemento inatteso. |
!?nginx? |
Il comando più recente che contiene nginx | Cerca per una stringa nel mezzo del comando. |
^old^new^ |
Sostituisci la prima stringa corrispondente del comando precedente ed esegui | Viene usato per correggere piccoli errori di battitura ed eseguire nuovamente. |
L'espansione della cronologia è abilitata per impostazione predefinita in Bash interattivo, mentre è disabilitata negli script non interattivi. Per la sintassi dettagliata, consulta il manuale GNU Bash sull’espansione della cronologia.
Controllare il risultato dell'espansione prima di eseguire
!numero e !stringa possono eseguire immediatamente il comando trovato, quindi fare particolare attenzione se nella cronologia ci sono comandi di cancellazione, modifica dei permessi o spegnimento del sistema. Se si passa l'espressione a history -p tra apici singoli, come sotto, puoi controllare il risultato senza eseguirlo. Le virgolette doppie non impediscono in generale l’espansione di ! in Bash interattivo.
history -p '!!'
history -p '!ssh'
In Bash usando Readline, impostare l'opzione seguente consente di visualizzare prima il risultato dell'espansione della cronologia nel buffer di modifica senza esecuzione immediata.
shopt -s histverify
In ambienti con più terminali dove i numeri possono cambiare facilmente, è spesso più sicuro cercare con Ctrl+r, controllare il contenuto e poi eseguire.
Eliminare voci dalla cronologia
Eliminare una voce specifica
Innanzitutto, controlla il numero con history e poi elimina la voce corrispondente dalla lista della cronologia della memoria usando l'opzione -d.
history -d 125
Le versioni di Bash che supportano gli intervalli accettano il numero iniziale e quello finale, entrambi inclusi. Verifica le opzioni disponibili con help history: 125 e 120–125 sono esempi da sostituire con numeri appena controllati nella tua lista.
history -d 120-125
Per riflettere i risultati della cancellazione nel file di cronologia corrente, puoi controllare l'elenco e poi eseguire history -w. Tuttavia, tieni presente che altre sessioni del terminale potrebbero successivamente scrivere di nuovo la cronologia precedente nel file al momento della loro uscita, quindi assicurati che non siano aperte più sessioni.
Eliminare l'intero elenco corrente
L'opzione -c cancella tutte le voci nella lista della cronologia nella memoria della shell corrente.
history -c
Per aggiornare il file di cronologia in modo che corrisponda all'elenco corrente, dovresti capire come funziona history -w prima di usarlo. La cancellazione della cronologia riguarda solo la cronologia della shell e non rimuove i log di sistema, i log di audit, i backup o la cronologia di altri terminali.
File di cronologia e più terminali
Ogni processo Bash mantiene una propria lista di cronologia in memoria. Per impostazione predefinita, i comandi appena eseguiti in un altro terminale potrebbero non apparire immediatamente nella history del terminale corrente.
| Comando | Comportamento tra il file della cronologia e la sessione corrente |
|---|---|
history -a |
Aggiunge alla fine del file la nuova cronologia della sessione corrente che non è ancora stata salvata nel file. |
history -n |
Aggiunge nuove righe del file della cronologia che la sessione corrente non ha ancora letto alla lista di memoria. |
history -r |
Aggiunge l'intero contenuto del file della cronologia alla fine della lista di memoria corrente. |
history -w |
Sovrascrive il file della cronologia con l'intera lista di memoria corrente. |
Per importare una nuova cronologia da un altro terminale, aggiungila prima al file in quel terminale con history -a, poi leggila nel terminale corrente con history -n.
history -a
history -n
Puoi utilizzare l'opzione histappend per aggiungere nuove voci invece di sovrascrivere il file di cronologia quando la shell termina.
shopt -s histappend
Per conservare questa scelta, aggiungila alla sezione pertinente di ~/.bashrc dopo aver controllato eventuali impostazioni esistenti. histappend riguarda il salvataggio all’uscita: non importa automaticamente le voci dagli altri terminali. Un eventuale PROMPT_COMMAND di sincronizzazione va integrato con quello esistente, senza sovrascriverlo alla cieca. Nemmeno history -a; history -n garantisce un ordine globale perfetto o elimina ogni conflitto fra scritture contemporanee.
Configurare le variabili della cronologia
| Variabile | Ruolo |
|---|---|
HISTFILE |
Il percorso del file in cui viene memorizzata la cronologia. Il valore predefinito comune è ~/.bash_history. |
HISTSIZE |
Il numero massimo di comandi da mantenere nella lista della cronologia in memoria della shell corrente. |
HISTFILESIZE |
Limita la dimensione massima del file di cronologia in termini di righe. |
HISTCONTROL |
Imposta le regole di memorizzazione, come non registrare comandi che iniziano con uno spazio o comandi duplicati consecutivi. |
HISTIGNORE |
Specifica modelli di shell, separati da due punti, che devono corrispondere all’intera riga per escluderla; non sono espressioni regolari. |
HISTTIMEFORMAT |
Specifica il formato di data e ora da visualizzare nell'output di history. |
Questo esempio imposta un limite di 5.000 comandi in memoria e di 10.000 righe nel file, esclude le righe iniziate da uno spazio, rimuove duplicati e aggiunge data e ora alla visualizzazione. Righe, timestamp e comandi su più righe non corrispondono necessariamente a un rapporto di uno a uno: HISTFILESIZE non indica 10.000 comandi.
HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoreboth:erasedups
HISTTIMEFORMAT='%F %T '
shopt -s histappend
Per rendere persistenti queste impostazioni, conserva una copia di ~/.bashrc, controlla se contiene già valori per queste variabili e aggiorna la sezione pertinente. Avvia una nuova Bash oppure rileggi il file seguente dopo averne verificato tutto il contenuto: source esegue anche gli altri comandi presenti, non soltanto le assegnazioni della cronologia.
source ~/.bashrc
HISTCONTROL=ignoreboth combina ignorespace e ignoredups; erasedups elimina dalla lista le precedenti righe identiche al nuovo comando. HISTTIMEFORMAT usa i formati di strftime, qui anno-mese-giorno e ora con uno spazio finale: mostra anche l’ora delle voci che la conservano, ma non ricostruisce l’ora originale dei vecchi comandi privi di timestamp. Per annullare una modifica, ripristina il valore precedente nella shell e la copia della configurazione; ridurre i limiti può avere già eliminato voci e non le ripristina. Consulta le variabili della cronologia nel manuale Bash.
Cronologia dei comandi e sicurezza
Se inserisci password, chiavi API, token o contenuti di chiavi private come argomenti della riga di comando, questi possono essere esposti non solo nella cronologia della shell ma anche nelle informazioni dei processi in esecuzione o in altri log. Per le informazioni sensibili, si consiglia di non inserirle direttamente nella riga di comando, ma di utilizzare l'input standard fornito dal programma, un archivio sicuro di credenziali o un file di configurazione con accesso ristretto.
Se ignorespace è impostato in HISTCONTROL, i comandi che iniziano con uno spazio possono essere esclusi dalla cronologia. Tuttavia, è necessario verificare se questa impostazione sia effettivamente attiva e non impedisce altri log, quindi non si dovrebbe fare affidamento esclusivamente su questo metodo per proteggere informazioni sensibili.
printf '%s\n' "$HISTCONTROL"
printf '%s\n' "$HISTFILE"
Anche se elimini le voci con history -d o history -c, le stesse informazioni possono rimanere in altre sessioni shell, backup, log di audit e log delle applicazioni. Se le credenziali sono esposte, non limitarti a eliminare la cronologia; dovresti invalidare la password o il token interessato e rilasciarne uno nuovo.
Problemi comuni
Gli ultimi comandi da un altro terminale non sono visibili
Ogni sessione Bash utilizza un elenco di memoria indipendente. Dopo aver eseguito history -a nel terminale dove sono stati eseguiti i comandi, prova a eseguire history -n nel terminale che vuoi controllare. A lungo termine, puoi esaminare histappend e le impostazioni di inizializzazione della shell.
La cronologia è scomparsa dopo la chiusura del terminale
Controlla se HISTFILE è vuota o non impostata, se il file è scrivibile e se HISTSIZE o HISTFILESIZE valgono 0. Verifica anche che la registrazione sia attiva con set -o: l’opzione history deve risultare on. Se la shell è stata terminata con la forza, il processo di salvataggio della cronologia all'uscita potrebbe non essere stato eseguito.
I numeri delle voci sono cambiati
I numeri della cronologia non sono identificatori fissi ma la posizione nella lista di memoria corrente. Se elimini le voci o carichi il file per unire le voci di un’altra sessione, i numeri possono cambiare. È più sicuro cercare e controllare il contenuto dei comandi piuttosto che ricordare ed eseguire vecchi numeri.
Si possono usare le stesse impostazioni in Zsh o Fish?
Le impostazioni non sono trasferibili direttamente a Zsh o Fish. printf '%s\n' "$SHELL" di solito indica la shell di login preferita, non prova quale interprete stia eseguendo la sessione corrente. Nella Bash corrente printf '%s\n' "$BASH_VERSION" ne mostra la versione; confronta anche il processo della sessione e la documentazione ufficiale della shell che stai realmente usando.
Riepilogo
history in Bash può essere utilizzato non solo per visualizzare i comandi precedenti, ma anche per eliminare voci specifiche, leggere/scrivere il file della cronologia e sincronizzarsi tra le sessioni. Per la ricerca quotidiana, history | grep e Ctrl+r sono comodi, e quando si riesegue utilizzando l'espansione della cronologia, è necessario prima controllare il contenuto del comando.
Per regolare la quantità e il modo in cui viene salvata la cronologia, considera HISTSIZE, HISTFILESIZE, HISTCONTROL, HISTTIMEFORMAT e histappend insieme. Per scegliere altri strumenti in base al compito, consulta la lista dei comandi Linux.




