Logbook — memoria terminale

Lavori da terminale. Apri una sessione, cominci a installare, configurare, modificare. A un certo punto chiedi aiuto a un’IA — copi l’output, incolli la risposta, esegui il comando suggerito. Funziona. Vai avanti.
Tre settimane dopo non ricordi cosa hai fatto, perché lo hai fatto, e soprattutto non riesci a riprodurre l’ambiente da zero.
Il terminale è il libro di ciò che avviene. Il problema è che non è di carta.
Questo script nasce da quella frustrazione. L’obiettivo è semplice: registrare tutto quello che succede in una sessione di lavoro, pulire il log da qualsiasi cosa sensibile, e produrre un file che puoi incollare direttamente a un’IA senza rischiare di portarti dietro token, password o chiavi private.
L’idea ha senso?#
Il problema che risolve è reale: le sessioni di lavoro con un’IA sono per natura iterative e caotiche, e la storia di come si arriva a un risultato si perde quasi sempre. Nessuno strumento mainstream affronta esattamente questo caso d’uso — la maggior parte dei tool di logging è pensata per ambienti di produzione, non per sessioni di sviluppo/configurazione personale.
Le alternative esistono, ma non fanno la stessa cosa:
script— il comando Unix usato internamente da questo script. Funziona, ma produce log grezzi illeggibili e non filtra niente.asciinema— registra sessioni in formato riproducibile. Bellissimo per demo, inutile qui — l’output è pensato per essere riprodotto, non letto.bash-preexec+ hook personalizzati — pipeline simili esistono, ma richiedono molto più setup e non sono pensate per l’integrazione con IA.atuin— history shell avanzata con sync e ricerca. Risolve il problema della history, non quello del log completo con output.
Nessuna di queste fa esattamente questo: registrare + pulire + oscurare + produrre un file pronto per IA. La combinazione è originale.
Come funziona#
Lo script aggiunge tre funzioni al tuo ambiente bash: logbook_start, logbook_stop e logbook_status.
logbook_start nome_sessione genera una cartella unica con timestamp, fa uno snapshot dei pacchetti installati, e avvia la registrazione. Il nome della sessione attiva viene salvato in ~/.logbook_session — questo è il meccanismo di recovery: se il terminale si chiude prima dello stop, al prossimo avvio lo script trova il file, ti avvisa, e ti chiede cosa fare.
logbook_stop esegue la pulizia in ordine preciso. Il primo passaggio oscura i dati sensibili direttamente sul log grezzo, prima di qualsiasi altra operazione — così anche un comando con password digitata per errore viene neutralizzato prima che il file venga letto. Poi rimuove le sequenze ANSI, fa un secondo passaggio di oscuramento sul log pulito come doppia sicurezza, genera l’hash di integrità ed elimina tutti i file intermedi.
logbook_status mostra la sessione attiva e la dimensione del log corrente — utile per sessioni lunghe.
Lo script completo#
Da aggiungere al tuo ~/.bashrc o ~/.bash_profile:
# ===== LOGBOOK – SESSIONE TERMINALE =====
# History sicura
shopt -s histappend
export PROMPT_COMMAND='history -a; history -n; history -w'
export HISTCONTROL=ignoreboth
export HISTFILESIZE=100000
export HISTSIZE=100000
export HISTIGNORE="*sudo*:*password*:*secret*"
# File di stato sessione attiva
LOGBOOK_STATE="$HOME/.logbook_session"
# Oscura dati sensibili da un file — usata sia sul raw che sul log finale
_logbook_redact() {
local input="$1"
local output="$2"
sed -E \
-e 's/(password|passwd|pwd)[= :]+[^ ]+/\1=REDACTED/gi' \
-e 's/(token|access_token)[= :]+[^ ]+/\1=REDACTED/gi' \
-e 's/(apikey|api_key|api-key)[= :]+[^ ]+/\1=REDACTED/gi' \
-e 's/(Authorization: Bearer )[A-Za-z0-9\._-]+/\1REDACTED/gi' \
-e 's/ghp_[A-Za-z0-9]+/REDACTED_GITHUB_TOKEN/gi' \
-e 's/-----BEGIN PRIVATE KEY-----/REDACTED_PRIVATE_KEY/gi' \
"$input" > "$output"
}
# Avvio sessione
logbook_start() {
if [ -z "$1" ]; then
echo "Uso: logbook_start nome_sessione"
return 1
fi
# Controlla se esiste una sessione precedente non chiusa
if [ -f "$LOGBOOK_STATE" ]; then
local prev_dir
prev_dir=$(cat "$LOGBOOK_STATE")
echo ""
echo "⚠️ ATTENZIONE: trovata una sessione precedente non chiusa."
echo " Cartella: $prev_dir"
echo ""
echo " Cosa vuoi fare?"
echo " [1] Chiudi quella sessione e avvia questa"
echo " [2] Abbandona quella sessione ed elimina i log grezzi"
echo " [3] Annulla"
echo ""
read -rp "Scelta [1/2/3]: " choice
case "$choice" in
1)
echo "Chiusura sessione precedente..."
AUDIT_DIR="$prev_dir" logbook_stop
;;
2)
echo "Eliminazione log grezzi della sessione precedente..."
rm -f "$prev_dir/full_raw.log" "$prev_dir/clean.log" "$prev_dir/clean_no_ansi.log"
rm -f "$LOGBOOK_STATE"
echo "Fatto."
;;
3)
echo "Operazione annullata."
return 0
;;
*)
echo "Scelta non valida. Operazione annullata."
return 1
;;
esac
fi
# ID unico per terminale + timestamp
export AUDIT_NAME="$(date +%F_%H%M%S)_$1"
export AUDIT_DIR="$HOME/terminal_audit/$AUDIT_NAME"
mkdir -p "$AUDIT_DIR"
# Salva il path della sessione attiva per recovery
echo "$AUDIT_DIR" > "$LOGBOOK_STATE"
# Snapshot pacchetti prima della sessione
dpkg --get-selections > "$AUDIT_DIR/packages_before.txt"
echo ""
echo "📋 Logbook avviato: $AUDIT_NAME"
echo " Per chiudere la sessione: logbook_stop"
echo ""
script -q -f "$AUDIT_DIR/full_raw.log"
}
# Stop sessione
logbook_stop() {
if [ -z "$AUDIT_DIR" ]; then
if [ -f "$LOGBOOK_STATE" ]; then
export AUDIT_DIR=$(cat "$LOGBOOK_STATE")
echo "Recovery: ripreso da $AUDIT_DIR"
else
echo "Nessuna sessione logbook attiva trovata."
return 1
fi
fi
if [ ! -d "$AUDIT_DIR" ]; then
echo "Cartella sessione non trovata: $AUDIT_DIR"
return 1
fi
echo "Elaborazione sessione in corso..."
# STEP 1: oscura i dati sensibili dal raw log prima di tutto
if [ -f "$AUDIT_DIR/full_raw.log" ]; then
_logbook_redact "$AUDIT_DIR/full_raw.log" "$AUDIT_DIR/full_raw_redacted.log"
mv "$AUDIT_DIR/full_raw_redacted.log" "$AUDIT_DIR/full_raw.log"
fi
# STEP 2: pulizia ANSI/sequenze terminale
col -b < "$AUDIT_DIR/full_raw.log" > "$AUDIT_DIR/clean.log"
sed -r "s/\x1B(\[[0-9;]*[mK]|\]0;.*\x07)//g" "$AUDIT_DIR/clean.log" > "$AUDIT_DIR/clean_no_ansi.log"
# STEP 3: comandi della sessione
history | sed 's/^ *[0-9]\+ *//' > "$AUDIT_DIR/commands.log"
# STEP 4: snapshot pacchetti dopo sessione
dpkg --get-selections > "$AUDIT_DIR/packages_after.txt"
diff "$AUDIT_DIR/packages_before.txt" "$AUDIT_DIR/packages_after.txt" > "$AUDIT_DIR/package_changes.diff"
# STEP 5: secondo passaggio redact sul log pulito
_logbook_redact "$AUDIT_DIR/clean_no_ansi.log" "$AUDIT_DIR/safe_for_ai_clean.log"
# STEP 6: hash di integrità
sha256sum "$AUDIT_DIR/safe_for_ai_clean.log" > "$AUDIT_DIR/integrity.sha256"
# STEP 7: elimina tutti i log intermedi
rm -f "$AUDIT_DIR/full_raw.log" "$AUDIT_DIR/clean.log" "$AUDIT_DIR/clean_no_ansi.log"
# STEP 8: rimuove il file di stato sessione
rm -f "$LOGBOOK_STATE"
echo ""
echo "✅ Logbook chiuso."
echo " Cartella: $AUDIT_DIR"
echo " Pronto per IA: $AUDIT_DIR/safe_for_ai_clean.log"
echo ""
unset AUDIT_DIR
unset AUDIT_NAME
}
# Stato sessione corrente
logbook_status() {
if [ -f "$LOGBOOK_STATE" ]; then
local session_dir
session_dir=$(cat "$LOGBOOK_STATE")
echo "Sessione attiva: $session_dir"
if [ -f "$session_dir/full_raw.log" ]; then
local size
size=$(du -h "$session_dir/full_raw.log" | cut -f1)
echo "Dimensione log corrente: $size"
fi
else
echo "Nessuna sessione logbook attiva."
fi
}
Come si usa#
# Inizio sessione
logbook_start configurazione-hugo
# ... lavori, installi, configuri, sbagli, correggi ...
# Verifica stato (opzionale)
logbook_status
# Fine sessione
logbook_stop
Al termine trovi tutto in ~/terminal_audit/2026-02-27_143022_configurazione-hugo/:
commands.log # Comandi eseguiti nella sessione
packages_before.txt # Pacchetti installati prima
packages_after.txt # Pacchetti installati dopo
package_changes.diff # Cosa è cambiato
safe_for_ai_clean.log # Log pulito, pronto da incollare
integrity.sha256 # Hash del log finale
Cosa viene oscurato#
| Pattern | Sostituito con |
|---|---|
password=, passwd:, pwd = | REDACTED |
token=, access_token: | REDACTED |
apikey=, api_key=, api-key= | REDACTED |
Authorization: Bearer ... | Authorization: Bearer REDACTED |
Token GitHub (ghp_...) | REDACTED_GITHUB_TOKEN |
| Intestazione chiave privata | REDACTED_PRIVATE_KEY |
Il filtro viene applicato due volte: una sul log grezzo appena chiusa la sessione, una sul log pulito prima di generare il file finale. Se un comando sensibile è finito nel log per errore, viene neutralizzato prima che qualsiasi altro processo lo legga.
Lavorare bene durante una sessione logbook#
Il log che il logbook produce è tanto più leggibile quanto meno usi editor interattivi. Nano, Vim e simili generano sequenze di controllo che il filtro ANSI non riesce a pulire completamente — il risultato nel log è rumore illeggibile.
La regola pratica è semplice: tutto quello che puoi fare da riga di comando, fallo da riga di comando. Tre strumenti coprono il 90% dei casi.
cat — scrivere un file da zero#
cat > ~/nomefile.txt
riga uno
riga due
riga tre
Premi Ctrl+D per chiudere. Nel log appare esattamente quello che hai scritto, pulito e leggibile.
heredoc — scrivere file con struttura in un colpo solo#
cat > ~/nomefile.txt << 'EOF'
riga uno
riga due
riga tre
EOF
Le virgolette singole attorno a EOF impediscono a bash di espandere variabili dentro il testo. Se vuoi che le variabili vengano espanse, togli le virgolette:
cat > ~/nomefile.txt << EOF
data di oggi: $(date)
utente: $USER
EOF
sed — modificare una riga specifica in un file esistente#
# Sostituisce la prima occorrenza
sed -i 's/vecchio/nuovo/' ~/nomefile.txt
# Sostituisce tutte le occorrenze
sed -i 's/vecchio/nuovo/g' ~/nomefile.txt
# Sostituisce solo alla riga 5
sed -i '5s/vecchio/nuovo/' ~/nomefile.txt
# Aggiunge una riga dopo la riga 3
sed -i '3a\nuova riga aggiunta' ~/nomefile.txt
# Elimina la riga 7
sed -i '7d' ~/nomefile.txt
Il flag -i modifica il file direttamente. Per vedere l’anteprima senza modificare, togli -i.
Il flusso pratico#
# Creo il file
cat > ~/test.conf << 'EOF'
host = localhost
port = 9000
debug = false
EOF
# Verifico
cat ~/test.conf
# Modifico una riga
sed -i 's/debug = false/debug = true/' ~/test.conf
# Verifico di nuovo
cat ~/test.conf
Nel log risultante tutto è perfettamente leggibile — nessuna sequenza spuria, nessun rumore. Esattamente quello che serve per ridare contesto a una sessione futura.
L’obiettivo non è automatizzare tutto. È capire tutto quello che viene fatto, poterlo spiegare e replicare
Il logbook è il primo mattone.