Ti è mai capitato di dover rinominare 200 file uno per uno? O di lanciare lo stesso comando su decine di server ogni mattina? Se fai sviluppo o sistemistica, lo scenario è fin troppo familiare. Noi, di Meteora Web, ci siamo passati decine di volte: un task ripetitivo che ti mangia tempo, energia e concentrazione. La soluzione è una: uno script Bash ben scritto. In questa guida prendiamo i quattro mattoni fondamentali di Bash — variabili, condizioni, cicli e funzioni — e li trasformiamo in strumenti concreti per automatizzare il tuo lavoro. Niente teoria astratta: esempi reali, errori comuni, codice che puoi copiare e usare subito.
Variabili: dove tieni i dati che cambiano
Una variabile in Bash è un contenitore di testo (sì, anche i numeri sono testo). La usi per non ripetere valori a mano e per rendere lo script adattabile a contesti diversi.
Dichiarazione e assegnamento
#!/bin/bash
# Assegna un valore a una variabile (NON mettere spazi attorno a =)
NOME="Meteora"
ANNO=2017
PI_GRECO=3.14
echo "Azienda: $NOME, fondata nel $ANNO"
Errore comune: scrivere NOME = "Meteora" con lo spazio. Bash interpreterà NOME come un comando e = come primo argomento. Sempre senza spazi.
Variabili d'ambiente e locali
Usa export per rendere una variabile disponibile ai processi figli. Per variabili temporanee, basta dichiararle nello script.
# Variabile locale
DB_HOST="localhost"
# Variabile d'ambiente (visibile ai comandi successivi)
export DB_USER="admin"
Espansione e quoting
- Doppi apici
"$VAR"— permettono l'espansione della variabile. - Apici singoli
'$VAR'— trattano tutto come letterale, nessuna espansione. - Backtick o $() — eseguono un comando e ne catturano l'output:
ORA=$(date).
NOME="Meteora Web"
echo "Benvenuto in $NOME" # stampa: Benvenuto in Meteora Web
echo 'Benvenuto in $NOME' # stampa: Benvenuto in $NOME
Cosa fare subito:
Apri un terminale e crea uno script con una variabile che contiene il percorso di una directory. Usala per fare ls -l su quella directory. Poi cambia il valore della variabile e rilancia lo script — capisci subito il vantaggio.
Condizioni: fai scegliere allo script
Uno script senza condizioni è come un semaforo sempre verde: va sempre dritto, anche quando dovrebbe fermarsi. Con if, elif, else e gli operatori di test, lo script decide in base ai dati.
Struttura base if
if [ "$NUMERO" -gt 10 ]; then
echo "Numero maggiore di 10"
elif [ "$NUMERO" -eq 10 ]; then
echo "Numero uguale a 10"
else
echo "Numero minore di 10"
fi
Nota lo spazio dopo [ e prima di ]; è obbligatorio. E then va sulla stessa riga di if separato da punto e virgola, oppure su riga nuova.
Operatori di test
- Confronto numeri:
-eq,-ne,-gt,-ge,-lt,-le. - Stringhe:
=(uguale),!=(diverso),-z(lunghezza zero),-n(non vuota). - File:
-f(esiste ed è file regolare),-d(directory),-x(eseguibile).
FILE="/etc/passwd"
if [ -f "$FILE" ]; then
echo "$FILE esiste"
fi
Test avanzati con [[ ]] (consigliato)
[[ ... ]] è più potente: supporta operatori logici && e ||, pattern matching e non ha bisogno di quoting per le variabili.
if [[ "$NOME" == M* ]]; then
echo "Il nome inizia con M"
fi
Errore comune: usare && dentro [ ] per combinare condizioni. In [ ] si usa -a (and) e -o (or), ma è deprecato. Usa sempre [[ ]] per maggiore leggibilità.
Cosa fare subito:
Scrivi uno script che prende un argomento (es. un nome directory) e verifica se esiste. Se esiste, stampa il numero di file al suo interno; altrimenti, creala. Lo usiamo continuamente nei deployment.
Cicli: ripeti senza impazzire
I cicli servono per eseguire un blocco di codice su una lista di elementi. In Bash hai due protagonisti: for e while.
Ciclo for: su elenchi espliciti o wildcard
# Itera su una lista di parole
for FRUTTA in mela pera banana; do
echo "Frutta: $FRUTTA"
done
# Itera su file con pattern
for FILE in *.log; do
echo "Pulendo $FILE"
> "$FILE" # svuota il file
done
Ciclo for con sequenze
for i in {1..5}; do
echo "Iterazione $i"
done
Attenzione: {1..5} non funziona con variabili (es. {1..$N}). Per range dinamici usa seq.
Ciclo while: finché una condizione è vera
CONTATORE=1
while [ $CONTATORE -le 5 ]; do
echo "Contatore: $CONTATORE"
((CONTATORE++))
done
La sintassi (( )) permette aritmetica intera. Puoi usare let o $(( )).
Leggere un file riga per riga
while IFS= read -r RIGA; do
echo "Elaboro: $RIGA"
done < "input.txt"
Errore comune: dimenticare IFS= e -r. Senza, Bash taglia spazi e interpreta backslash. Sempre così per leggere file in modo sicuro.
Cosa fare subito:
Prendi una directory piena di file .jpg e scrivi un ciclo for che li converta in .png con convert (ImageMagick). Un backup batch che ti salva ore.
Funzioni: organizza e riusa il codice
Quando uno script supera le 30 righe, il caos è dietro l'angolo. Le funzioni incapsulano blocchi logici: le chiami quando servono, le modifichi in un punto solo.
Definizione e chiamata
#!/bin/bash
log() {
local MESSAGGIO="$1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $MESSAGGIO"
}
log "Avvio deploy"
log "Deploy completato"
La parola function è opzionale; basta il nome seguito da parentesi e corpo tra graffe. local rende una variabile visibile solo dentro la funzione, evitando conflitti con lo script principale.
Parametri e valori di ritorno
somma() {
local A=$1
local B=$2
local RESULT=$((A + B))
echo $RESULT
}
RISULTATO=$(somma 5 7)
echo "5 + 7 = $RISULTATO"
Le funzioni Bash non restituiscono un valore con return (quello è solo per codici di uscita). Il vero output lo produci con echo e lo catturi con $().
Errori comuni
- Dimenticare
local— le variabili diventano globali e inquinano lo script. - Usare
returnper restituire dati — funziona solo per numeri interi 0-255. Per stringhe o numeri grandi, usaechoe cattura l'output. - Non passare i parametri con le virgolette se contengono spazi — usa
"$1"sempre.
Cosa fare subito:
Riprendi lo script del ciclo for sulla directory. Estrai la logica di conversione in una funzione converti_formato che accetta estensione sorgente e destinazione. Poi chiamala per .jpg→.png e .png→.webp. Uno script che cresce bene.
In sintesi — cosa fare adesso
- Scrivi un primo script di backup che usa variabili per definire la directory sorgente e quella di destinazione, un ciclo for per iterare sui file e una funzione per loggare ogni operazione.
- Sostituisci i comandi manuali ripetitivi con uno script Bash. Identifica un task che fai ogni giorno (es. aggiornare i permessi dei file, compilare asset) e automatizzalo.
- Testa le condizioni sui file nei tuoi script di deployment: verifica che i binari esistano, che le directory siano scrivibili, prima di lanciare operazioni pericolose.
- Usa
[[ ]]invece di[ ]per tutte le nuove condizioni. Più leggibile, meno bug. - Metti ogni funzione in un file separato di libreria (es.
lib.sh) e caricalo consource lib.sh. Riuso puro.
Noi, di Meteora Web, usiamo Bash ogni giorno nei nostri workflow di deploy, nei controlli di sicurezza sui server e nella gestione delle VM. È il coltellino svizzero del sysadmin, e padroneggiarlo ti toglie un peso enorme. Prendi un problema ripetitivo, scrivi uno script, e vedrai che differenza fa.
Sponsored Protocol