Vai al contenuto
LF Lomazzi Federico

Home/Software/BASH

BASH

Syskiller

Report FULL SYSTEM single bash

Lomazzi Federico MIT syskiller-fa32a.sh · 8 KB 413 righe aggiornato il 21 agosto 2026

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 **

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 **

Il codice

syskiller-fa32a.sh · BASH · 413 righe · MIT

#!/usr/bin/env bash
#
# syskiller.sh
# diagnostica rapida linux
# by Lomazzi Federico 2/7/2025
#
# uso:
#   ./syskiller.sh
#       mostra il report a video
#
#   ./syskiller.sh -o
#       salva anche il report in /tmp
#
#   ./syskiller.sh -f
#       analisi filesystem più approfondita
#
#   ./syskiller.sh -o -f
#       report completo salvato su file
#
# eseguirlo come root per ottenere tutte le informazioni disponibili

set -u

SAVE=0
FULL=0

for ARG in "$@"; do
    case "$ARG" in
        -o) SAVE=1 ;;
        -f) FULL=1 ;;
        -h|--help)
            head -n 20 "$0"
            exit 0
            ;;
    esac
done

HOST="$(hostname 2>/dev/null || echo unknown)"
DATE="$(date '+%Y-%m-%d_%H-%M-%S')"
REPORT="/tmp/syskiller_${HOST}_${DATE}.log"

if [ "$SAVE" -eq 1 ]; then
    exec > >(tee "$REPORT") 2>&1
fi

section()
{
    echo
    echo "======================================================================"
    echo "$1"
    echo "======================================================================"
}

command_exists()
{
    command -v "$1" >/dev/null 2>&1
}

section "SYSTEM"

echo "host:        $HOST"
echo "date:        $(date)"
echo "kernel:      $(uname -r)"
echo "architecture: $(uname -m)"
echo "uptime:      $(uptime -p 2>/dev/null || uptime)"

if [ -r /etc/os-release ]; then
    . /etc/os-release
    echo "os:          ${PRETTY_NAME:-unknown}"
fi

section "LOAD"

uptime

if [ -r /proc/loadavg ]; then
    echo
    echo "loadavg:"
    cat /proc/loadavg
fi

CPU_COUNT="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)"
LOAD1="$(awk '{print $1}' /proc/loadavg 2>/dev/null)"

echo
echo "cpu disponibili: $CPU_COUNT"

if command_exists awk && [ -n "${LOAD1:-}" ]; then
    awk -v load="$LOAD1" -v cpu="$CPU_COUNT" '
        BEGIN {
            ratio = load / cpu

            if (ratio >= 2)
                print "attenzione: load estremamente elevato"
            else if (ratio >= 1)
                print "attenzione: load superiore alla capacità nominale"
            else
                print "load compatibile con il numero di cpu"
        }
    '
fi

section "MEMORY"

free -h 2>/dev/null || cat /proc/meminfo

echo
echo "swap:"
swapon --show 2>/dev/null || true

section "DISK"

df -hT 2>/dev/null

echo
echo "filesystem oltre 85%:"

df -P 2>/dev/null |
awk '
    NR > 1 {
        gsub("%","",$5)
        if ($5 >= 85)
            print "WARNING:", $6, $5 "%"
    }
'

section "INODES"

df -ih 2>/dev/null

echo
echo "inode oltre 85%:"

df -Pi 2>/dev/null |
awk '
    NR > 1 && $5 != "-" {
        gsub("%","",$5)
        if ($5 >= 85)
            print "WARNING:", $6, $5 "%"
    }
'

section "TOP CPU"

ps -eo pid,ppid,user,%cpu,%mem,etime,comm --sort=-%cpu 2>/dev/null |
head -n 16

section "TOP MEMORY"

ps -eo pid,ppid,user,%cpu,%mem,rss,etime,comm --sort=-%mem 2>/dev/null |
head -n 16

section "PROCESSI ZOMBIE"

ZOMBIES="$(
    ps -eo stat,pid,ppid,user,comm 2>/dev/null |
    awk '$1 ~ /^Z/ {print}'
)"

if [ -n "$ZOMBIES" ]; then
    echo "$ZOMBIES"
else
    echo "nessun processo zombie"
fi

section "NETWORK"

if command_exists ss; then

    echo "porte in ascolto:"
    ss -lntup 2>/dev/null

    echo
    echo "stato connessioni tcp:"

    ss -tan 2>/dev/null |
    awk '
        NR > 1 {
            state[$1]++
        }

        END {
            for (s in state)
                printf "%-15s %d\n", s, state[s]
        }
    ' | sort

elif command_exists netstat; then

    netstat -lntup 2>/dev/null

else

    echo "ss/netstat non disponibili"

fi

section "FAILED SERVICES"

if command_exists systemctl; then

    FAILED="$(systemctl --failed --no-legend 2>/dev/null)"

    if [ -n "$FAILED" ]; then
        echo "$FAILED"
    else
        echo "nessun servizio systemd fallito"
    fi

else

    echo "systemd non disponibile"

fi

section "KERNEL ERRORS"

if command_exists journalctl; then

    journalctl -k -p err..alert -n 40 --no-pager 2>/dev/null

else

    dmesg 2>/dev/null |
    grep -Ei 'error|fail|critical|panic' |
    tail -n 40

fi

section "OOM KILLER"

if command_exists journalctl; then

    OOM="$(
        journalctl -k --no-pager 2>/dev/null |
        grep -Ei 'out of memory|oom-killer|killed process' |
        tail -n 30
    )"

else

    OOM="$(
        dmesg 2>/dev/null |
        grep -Ei 'out of memory|oom-killer|killed process' |
        tail -n 30
    )"

fi

if [ -n "$OOM" ]; then
    echo "$OOM"
else
    echo "nessun intervento oom rilevato"
fi

section "RECENT LOGIN"

last -n 15 2>/dev/null || true

section "LAST REBOOT"

last reboot -n 10 2>/dev/null || true

section "FAILED LOGIN"

if command_exists journalctl; then

    journalctl --since "24 hours ago" --no-pager 2>/dev/null |
    grep -Ei \
        'failed password|authentication failure|invalid user' |
    tail -n 30

elif [ -r /var/log/auth.log ]; then

    grep -Ei \
        'failed password|authentication failure|invalid user' \
        /var/log/auth.log |
    tail -n 30

else

    echo "log autenticazione non disponibile"

fi

section "RECENT ERRORS"

if command_exists journalctl; then

    journalctl -p err..alert --since "2 hours ago" \
        --no-pager 2>/dev/null |
    tail -n 80

else

    echo "journalctl non disponibile"

fi

section "LARGE FILES"

# cerca soltanto nei punti dove normalmente nasce il disastro
for DIR in /var /tmp /home; do

    [ -d "$DIR" ] || continue

    find "$DIR" \
        -xdev \
        -type f \
        -size +500M \
        -printf '%s %p\n' 2>/dev/null

done |
sort -nr |
head -n 20 |
awk '
    {
        size=$1
        $1=""
        printf "%.2f GB%s\n", size/1073741824, $0
    }
'

if [ "$FULL" -eq 1 ]; then

    section "BIG DIRECTORIES"

    # modalità più lenta: individua chi si sta mangiando il filesystem
    for DIR in /var /home /opt /srv; do

        [ -d "$DIR" ] || continue

        du -x -B1 -d 2 "$DIR" 2>/dev/null

    done |
    sort -nr |
    head -n 30 |
    awk '
        {
            size=$1
            $1=""
            printf "%8.2f GB%s\n", size/1073741824, $0
        }
    '

fi

section "DELETED BUT OPEN FILES"

if command_exists lsof; then

    DELETED="$(
        lsof +L1 2>/dev/null |
        head -n 30
    )"

    if [ -n "$DELETED" ]; then
        echo "$DELETED"
    else
        echo "nessun file cancellato ancora mantenuto aperto"
    fi

else

    echo "lsof non disponibile, controllo saltato"

fi

section "SUMMARY"

WARNINGS=0

ROOT_USAGE="$(
    df -P / 2>/dev/null |
    awk 'NR == 2 {gsub("%","",$5); print $5}'
)"

if [ "${ROOT_USAGE:-0}" -ge 90 ] 2>/dev/null; then
    echo "WARNING: filesystem root quasi pieno: ${ROOT_USAGE}%"
    WARNINGS=$((WARNINGS + 1))
fi

MEM_AVAIL="$(
    awk '/MemAvailable:/ {print $2}' /proc/meminfo 2>/dev/null
)"

MEM_TOTAL="$(
    awk '/MemTotal:/ {print $2}' /proc/meminfo 2>/dev/null
)"

if [ -n "${MEM_AVAIL:-}" ] && [ -n "${MEM_TOTAL:-}" ]; then

    MEM_PERCENT=$((MEM_AVAIL * 100 / MEM_TOTAL))

    if [ "$MEM_PERCENT" -lt 10 ]; then
        echo "WARNING: memoria disponibile inferiore al 10%"
        WARNINGS=$((WARNINGS + 1))
    fi

fi

if [ "$WARNINGS" -eq 0 ]; then
    echo "nessuna anomalia macroscopica rilevata"
else
    echo "anomalie immediate rilevate: $WARNINGS"
fi

if [ "$SAVE" -eq 1 ]; then
    echo
    echo "report salvato in: $REPORT"
fi

exit 0
18 visite

Commenti

Nessun commento, per ora.

Continua

Altri strumentidello stesso genere

Tutto il codice

BASH MIT

Monitor integrità directory

Monitor files nuovi/eliminati/modificati

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.

16 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