Bash scripting - caratteri di escape
Bash scripting |
Sommario |
Caratteri di escape, apici e virgolette
Alcuni caratteri hanno un valore speciale per la shell, per consentire le espansioni o determinati costrutti. Di conseguenza se si intende scrivere il carattere per il suo valore letterale, è necessario comunicarlo alla shell facendolo precedere da un carattere di escape \
oppure racchiudendolo tra apici o virgolette.
Una stringa non racchiusa tra apici o tra virgolette ha i seguenti caratteri speciali: $ ' ` " \ { } [ ] * ? ~ & ; ( ) < > | #
In determinate circostanze, se non preceduti dal carattere di escape \
, possono essere: espansi, eseguiti in background, considerati parte di un nuovo comando, trattati come redirezioni e perfino come commenti. Questa sezione non è esaustiva e non considera tutte le eccezioni, ma consiglia degli accorgimenti che si possono sempre seguire per ridurre il numero di caratteri speciali.
Inoltre gli spazi (comprese le tabulazioni) non quotati con apici o virgolette, e non preceduti dal carattere di escape \
, vengono compressi e ciò che è scritto prima o dopo è interpretato come appartenente a stringhe diverse.
Per esempio:
printf %s\\n parola1; parola2 # ERRORE: parola2 è considerata un altro comando! printf %s\\n "parola1; parola2" # corretto printf %s\\n parola1 parola2 # ERRORE: niente spazi e su due righe diverse! printf %s\\n "parola1 parola2" # corretto # con una variabile var="parola1 parola2" # assegno la stringa alla variabile printf %s\\n $var # ERRORE: stampa le parole su due linee diverse printf %s\\n "$var" # stampo la stringa così com'è scritta
Il carattere di escape \
prima di un "a capo", anche se quotato (tra virgolette), ha un significato speciale che consente di scrivere un comando su più righe, trattando ogni riga preceduta da \
come una continuazione della precedente:
# stampa tutto su una riga printf %s\\n "testo su \ più \ righe" # stampa su più righe printf %s\\n "testo su più righe"
Racchiudere tra apici
Con gli apici (apostrofi) si riducono i caratteri speciali a uno soltanto, lo stesso apice, rappresentando la stringa per il suo solo valore letterale e impedendo tutte le espansioni:
printf %s\\n '$PATH "" \ `ls ..` \$HOME ~ * .[a-z]*' # stampa la stringa tra apici, letteralmente
Lo svantaggio è che non esiste un carattere di escape:
printf %s\\n 'L'\''albero di... ' # stampa "L'albero di..." (l'accento non può essere racchiuso tra apici)
Racchiudere tra $'...'
Una stringa racchiusa tra $'...'
non può essere espansa in nessun modo, come se fosse racchiusa tra apici. Il carattere \
resta un carattere di escape, quindi è possibile inserire un apice nella stringa facendolo precedere da \
e dev'essere preceduto dal carattere di escape anche ogni \
da stampare letteralmente.
Un carattere \
non preceduto da escape permette di stampare caratteri di escape, con la stessa sintassi del formato di printf
(quando racchiuso tra apici):
- \n, nuova riga;
- \b, backspace (cancella un carattere);
- \r, carriage return (ritorna a inizio riga);
- \t, tabulazione;
- \nnn, carattere ASCII in base 8;
- ecc...
Per esempio:
printf %s\\n $'stringa' # stampa la stringa printf %s $'stringa\n' # equivalente: il carattere "a capo" ora è nella stringa printf %s $'$PATH "" `ls ..`\n' # nessuna espansione printf %s $'~ * .[a-z]*\n' # nessuna espansione printf %s $'{a,b,c} $((2*2))\n' # nessuna espansione printf %s $'escape: \\\n' # per stampare un \ dev'essere preceduto da \ printf %s $'L\'albero di...\n' # stampa "L'albero di..." (l'apice può essere stampato con escape)
È un metodo molto meno diffuso rispetto a racchiudere tra apici e virgolette, perché non derivata da sh (POSIX).
Quotare (tra virgolette)
Racchiudere tra virgolette ogni stringa è raccomandabile, anche se non sempre necessario, così da ridurre il numero di caratteri speciali a cui pensare, permettendo allo stesso tempo l'espansione sicura delle variabili e dei comandi. I soli caratteri speciali rimasti sono $
, `
(ma non l'apice), "
e \
, che devono essere preceduti dal carattere di escape \
.
All'interno di una stringa quotata tutte le espansioni che non sono attivabili da $
non sono permesse. Sono possibili soltanto le espansioni di variabile/parametro, di comando e aritmetiche.
Per esempio:
printf %s\\n "$PATH" # espande la variabile PATH e ne stampa il contenuto printf %s\\n "\$HOME" # stampa letteralmente $HOME, senza espanderla (è equivalente a '$HOME') printf %s\\n "\"\" \\" # è equivalente a '"" \' printf %s\\n "$(ls ..)" # Esegue il comando "ls .." e ne stampa l'output printf %s\\n "$((2*2))" # Esegue l'espressione aritmetica e stampa 4 printf %s\\n "~ * .[a-z]*" # non effettua le espansioni di tilde e percorso, ma stampa letteralmente printf %s\\n "p{a,b,c}s" # niente espansioni