Guida completa alle strutture speciali, variabili e espansioni di Bash

Panoramica

Questo articolo riunisce tutte le strutture speciali, variabili speciali, regole di espansione e controlli sintattici utilizzati nella shell Bash in modo sistematico.


Notazione delle variabili

I valori dinamici o dipendenti dall’ambiente sono rappresentati come <<variabile>> e ogni esempio mostra il loro utilizzo.

Variabile Esempio Descrizione
<<var>> name, path, user Nome di una variabile generica
<<default>> guest, 8080 Valore predefinito o alternativo
<<pattern>> *.txt, */ Pattern di file o stringa
<<offset>> 0, 3 Posizione iniziale (partendo da 0)
<<length>> 4, 10 Lunghezza della sottostringa
<<prefix>> ENV_, HOST Prefisso del nome variabile
<<index>> 0, 1, 2 Indice di array o chiave di dizionario
<<file>> /tmp/test.txt Percorso del file

Step 1: Metacaratteri (Simboli speciali)

Simbolo Significato Esempio
* Corrisponde a qualsiasi stringa ls *.txt
? Corrisponde a un singolo carattere ls ?.sh
[a-z] Intervallo di caratteri ls [A-Z]*
{a,b} Espansione a graffe mv {src,dest}
{1..3} Sequenza numerica touch file{1..3}.txt
$ Espansione di variabile echo $HOME
! (negazione) Operatore logico NOT [[ ! -f test.txt ]]
! (cronologia) Richiama un comando precedente !10
~ Directory home cd ~
; Esegue più comandi pwd; ls
&& Esegue se il precedente ha successo make && echo OK
` `
& Esecuzione in background sleep 5 &
` ` Pipe
> Redirezione di output echo hi > out.txt
>> Appende a un file echo hi >> out.txt
< Input da file wc -l < file.txt
() Sottoshell (cd /tmp; ls)
{} Esegue nello stesso shell { echo A; echo B; }
\ Escape echo \$HOME
' ' Nessuna espansione echo '$USER'
" " Espansione abilitata echo "$USER"

Step 2: Variabili speciali

Variabile Contenuto Esempio
$0 Nome dello script echo $0
$1…$9 Argomenti echo $1
$@ Tutti gli argomenti for a in "$@"; do echo $a; done
$# Numero di argomenti echo $#
$? Codice di uscita precedente ls /nope; echo $?
$$ PID del processo corrente echo $$
$! PID dell’ultimo job in background sleep 10 & echo $!
$- Opzioni della shell echo $-
$_ Ultimo argomento dell’ultimo comando echo $_
$PPID PID del processo padre echo $PPID
$RANDOM Numero casuale (0–32767) echo $RANDOM
$SECONDS Secondi dall’avvio della shell echo $SECONDS
$FUNCNAME Nome della funzione f(){ echo $FUNCNAME; }; f
$PIPESTATUS[@] Codici di uscita nei pipe `ls

Step 3: Espansione di variabili

Sintassi Significato Esempio
${<<var>>} Espansione semplice name=user; echo ${name}
${<<var>>:-<<default>>} Usa default se non definita echo ${user:-guest}
${<<var>>:=<<default>>} Assegna default se non definita echo ${port:=8080}
${<<var>>:+alt} Usa alt se definita x=1; echo ${x:+OK}
${<<var>>:?msg} Errore se non definita echo ${cfg:?missing}
${#<<var>>} Lunghezza della stringa n=user; echo ${#n}
${<<var>>%<<pattern>>} Rimuove la parte finale breve p=/a/b/c; echo ${p%/*}
${<<var>>%%<<pattern>>} Rimuove la parte finale lunga echo ${p%%/*}
${<<var>>#<<pattern>>} Rimuove l’inizio breve echo ${p#*/}
${<<var>>##<<pattern>>} Rimuove l’inizio lungo echo ${p##*/}
${<<var>>/<<pattern>>/<<repl>>} Sostituisce la prima occorrenza echo ${msg/foo/bar}
${<<var>>//<<pattern>>/<<repl>>} Sostituisce tutte le occorrenze echo ${msg// /_}
${<<var>>:<<offset>>} Sottostringa da offset s=abcdef; echo ${s:2}
${<<var>>:<<offset>>:<<length>>} Sottostringa con lunghezza echo ${s:1:3}
${!<<prefix>>*} Variabili con prefisso HOST1=x; HOST2=y; echo ${!HOST*}
${!<<var>>} Espansione indiretta ref=NAME; NAME=val; echo ${!ref}
${<<var>>,} / ${<<var>>^^} Minuscolo/Maiuscolo n=abc; echo ${n^^}
${<<var>>@Q} Espansione con virgolette x='abc'; echo ${x@Q}

Step 4: Array e dizionari

arr=(a b c)
echo ${arr[<<index>>]}
echo ${#arr[@]}
for i in "${arr[@]}"; do echo $i; done

declare -A map
map[<<index>>]=100
map[name]=user
echo ${map[<<index>>]}
echo ${!map[@]}

Step 5: Espansione aritmetica

x=5
y=3
echo $((x + y))
((x *= 2))
echo $x

Step 6: Condizioni e confronti

if [ "$USER" = "root" ]; then echo root; fi
if [ "$x" -lt 10 ]; then echo "small"; fi
if [ -f /etc/passwd ]; then echo "exists"; fi
s="hello123"
[[ $s =~ [0-9]+ ]] && echo "contains number"

Step 7: Sostituzione comandi e sottoshell

echo "Today: $(date +%Y-%m-%d)"
(cd /tmp; ls)

Step 8: Redirezione e file descriptor

echo "Hello" > <<file>>
echo "Append" >> <<file>>
wc -l < <<file>>
ls /nope 2> err.log
echo "OK" >&2
exec 3> custom.log
echo "via fd3" >&3
exec 3>&-

File Descriptor (FD)

Numero Nome Descrizione Esempio
0 stdin Input da tastiera/file < file.txt
1 stdout Output normale echo test > out.txt
2 stderr Output errori ls /nope 2> err.log
3+ FD utente Canale personalizzato exec 3> log.txt

Esempio:

exec 3> process.log
echo "inizio" >&3
exec 3>&-

Step 9: Trap ed error handling

set -e
set -u
set -x
set -o pipefail
trap 'echo Terminato' EXIT
trap 'echo Errore' ERR

Step 10: Controllo dei job

sleep 10 &
jobs
fg %1
bg %1
disown %1
kill %1

%1 indica il numero di job, come mostrato dal comando jobs.


Step 11: Comandi speciali e parole riservate

:
true
false
source ~/.bashrc
eval "echo executed"
{ echo A; echo B; }

Conclusione

Abbiamo coperto tutti i costrutti, le variabili e le espansioni speciali di Bash.
Comprendere questi elementi permette di scrivere script sicuri, riutilizzabili e facili da manutenere per qualsiasi scenario di automazione Linux.