Vai al contenuto
LF Lomazzi Federico

Home/Software/BASH

BASH

Monitor integrità directory

Monitor files nuovi/eliminati/modificati

Lomazzi Federico MIT filwatch-fcb74.sh · 4 KB 182 righe aggiornato il 23 agosto 2026

Vi è mai capitato di dovervi scansionare un sacco di directory e files per poi accorgervi che ad essere broken era un symlink o maree di inodes? Questo potrebbe essere lo strumento che fà per voi. Facile da usare, veloce e sopratutto và diritto al punto.

Crea una baseline e per orni esecuzione successiva vi segnala file nuovi/eliminati/modificati.
Un solo bash, niente database e niente demoni residenti

Il codice

filwatch-fcb74.sh · BASH · 182 righe · MIT

#!/usr/bin/env bash
#
# filewatch.sh
# controllo integrità filesystem - Lomazzi Federico 2/7/2025
#
# uso:
#   ./filewatch.sh init /etc
#       crea la baseline iniziale
#
#   ./filewatch.sh check /etc
#       confronta lo stato attuale con la baseline
#
#   ./filewatch.sh update /etc
#       aggiorna la baseline allo stato attuale
#
# la baseline viene salvata in /var/tmp/filewatch
# usare preferibilmente come root per poter leggere tutti i file

set -u

MODE="${1:-}"
TARGET="${2:-}"

STATE_DIR="/var/tmp/filewatch"

if [ -z "$MODE" ] || [ -z "$TARGET" ]; then
    echo "uso: $0 {init|check|update} /directory"
    exit 1
fi

if [ ! -d "$TARGET" ]; then
    echo "errore: directory inesistente: $TARGET"
    exit 1
fi

TARGET="$(cd "$TARGET" 2>/dev/null && pwd -P)" || exit 1

mkdir -p "$STATE_DIR" || exit 1

ID="$(printf '%s' "$TARGET" | sha256sum | awk '{print $1}')"

BASELINE="$STATE_DIR/$ID.baseline"
CURRENT="$STATE_DIR/$ID.current"

generate_state()
{
    local OUT="$1"

    : > "$OUT"

    # il sort rende il confronto indipendente dall'ordine restituito da find
    find "$TARGET" -xdev -type f -print0 2>/dev/null |
    while IFS= read -r -d '' FILE; do

        HASH="$(sha256sum "$FILE" 2>/dev/null | awk '{print $1}')"

        [ -z "$HASH" ] && HASH="UNREADABLE"

        printf '%s|%s\n' "$HASH" "$FILE"

    done | sort -t'|' -k2 > "$OUT"
}

case "$MODE" in

    init)

        if [ -f "$BASELINE" ]; then
            echo "baseline già presente per: $TARGET"
            echo "usa '$0 update \"$TARGET\"' per sostituirla"
            exit 1
        fi

        echo "creazione baseline: $TARGET"

        generate_state "$BASELINE"

        COUNT="$(wc -l < "$BASELINE")"

        echo "baseline creata"
        echo "file registrati: $COUNT"
        echo "database: $BASELINE"
        ;;

    update)

        echo "aggiornamento baseline: $TARGET"

        generate_state "$CURRENT"

        mv "$CURRENT" "$BASELINE" || exit 1

        COUNT="$(wc -l < "$BASELINE")"

        echo "baseline aggiornata"
        echo "file registrati: $COUNT"
        ;;

    check)

        if [ ! -f "$BASELINE" ]; then
            echo "nessuna baseline presente per: $TARGET"
            echo "eseguire prima: $0 init \"$TARGET\""
            exit 1
        fi

        echo "controllo: $TARGET"

        generate_state "$CURRENT"

        declare -A OLD_HASH
        declare -A NEW_HASH

        while IFS='|' read -r HASH FILE; do
            OLD_HASH["$FILE"]="$HASH"
        done < "$BASELINE"

        while IFS='|' read -r HASH FILE; do
            NEW_HASH["$FILE"]="$HASH"
        done < "$CURRENT"

        CREATED=0
        DELETED=0
        MODIFIED=0

        echo

        for FILE in "${!NEW_HASH[@]}"; do

            if [ -z "${OLD_HASH[$FILE]+x}" ]; then

                echo "[NEW]      $FILE"
                CREATED=$((CREATED + 1))

            elif [ "${OLD_HASH[$FILE]}" != "${NEW_HASH[$FILE]}" ]; then

                echo "[MODIFIED] $FILE"
                MODIFIED=$((MODIFIED + 1))

            fi

        done

        for FILE in "${!OLD_HASH[@]}"; do

            if [ -z "${NEW_HASH[$FILE]+x}" ]; then
                echo "[DELETED]  $FILE"
                DELETED=$((DELETED + 1))
            fi

        done

        rm -f "$CURRENT"

        echo
        echo "nuovi:      $CREATED"
        echo "modificati: $MODIFIED"
        echo "eliminati:  $DELETED"

        if [ "$CREATED" -eq 0 ] &&
           [ "$MODIFIED" -eq 0 ] &&
           [ "$DELETED" -eq 0 ]; then

            echo
            echo "nessuna modifica rilevata"
            exit 0
        fi

        # exit code 2 permette di usarlo facilmente anche da cron o altri script
        exit 2
        ;;

    *)

        echo "modalità non valida: $MODE"
        echo "uso: $0 {init|check|update} /directory"
        exit 1
        ;;

esac

exit 0
16 visite

Commenti

Nessun commento, per ora.

Continua

Altri strumentidello stesso genere

Tutto il codice

BASH MIT

Syskiller

Report FULL SYSTEM single bash

Vi raccoglie in un unico report load, cpu, ram, swap, dischi, inode, processi pesanti, porte in ascolto, connessioni, servizi falliti, errori kernel, OOM killer, ultimi login, file grossi e directory che vi stanno esplodendo. Utile per poi spararlo via alla AI preferita che in tempo zero fà in 1 minuto quello che facevamo noi prima in 2 ore... :-)) ** Sempre prestando occhio anche a cosa fà la AI, ovviamente **

18 visite

BASH MIT

Backup incrementale con rotazione (bash)

Un solo file, nessuna dipendenza.

Vi serve un bash veloce per un backup incrementale rapido, sicuro e senza troppe pretese? Questo bash l'ho usato varie volte a chiusura lavoro per il backup di folder sulle quali ci ritornavo sporadicamente, ma dove era necessario sapere sempre dove ci si era fermati. Un bash senza fronzoli ma che fà il suo lavoro.

24 visite

JAVASCRIPT MIT

Questo gioco è tornato otto anni dopo, e non l'ho più scritto io.

Vecchi giochi, nuove competenze

Nel 2018 avevo scritto per mio figlio un piccolo gioco educativo in JavaScript usando Phaser, impiegandoci tre o quattro serate. Otto anni dopo lui lo ha ripreso ed in una frazione di quel tempo ne ha costruito una versione enormemente più ricca usando l'AI come esecutore tecnico. La parte interessante non è che l'AI sappia programmare, ma che il collo di bottiglia si sia spostato dal codice alla capacità di progettare, verificare e correggere.

26 visite

Scarica