Bash scripting: differenze tra le versioni

corretto uso $'...', aggiunti esempi e altre modifiche minori; resta da dividere in più parti
(corretto uso $'...', aggiunti esempi e altre modifiche minori; resta da dividere in più parti)
Riga 36: Riga 36:
In questa guida d'ora in poi si farà riferimento soltanto a <code>printf</code>.
In questa guida d'ora in poi si farà riferimento soltanto a <code>printf</code>.


===Sintassi di printf===
===Uso di printf===
<pre>printf formato [ "stringa" ... ]</pre>
Sintassi: <code>printf formato [ "stringa" ... ]</code>
 
Gli usi più avanzati non sono trattati in questa guida, ma di seguito sono presentati alcuni esempi:
Gli usi più avanzati non sono trattati in questa guida, ma di seguito sono presentati alcuni esempi:
* stampa senza a capo finale
* stampa sullo schermo senza a capo finale
<pre>printf %s "$var"</pre>
<pre>printf %s "stringa da stampare"
* caratteri speciali (senza %s non serve una stringa)
printf %s "$var"</pre>
* stampa una riga vuota
<pre>
printf \\n  # corretto (doppio backslash)
printf \n    # ERRORE: stampa 'n'
 
# tra virgolette
printf "\\n" # corretto (doppio backslash)
printf "\n"  # corretto (singolo backslash)
 
# tra apici
printf '\\n' # ERRORE: stampa '\n'
printf '\n'  # corretto (singolo backslash)
</pre>
* altri caratteri speciali nel formato (stesse considerazioni sull'uso di " e ')
<pre>
<pre>
printf \\n  # nuova riga
printf \\t  # tabulazione
printf \\t  # tabulazione
printf \\r  # ritorno a inizio riga
printf \\r  # ritorno a inizio riga
printf \\NNN # stampa il carattere ascii con codice in base 8
printf \\NNN # stampa il carattere ascii con codice in base 8
</pre>
</pre>
* stampa con a capo finale
* stampa sullo schermo con a capo finale
<pre>printf %s\\n "$var"</pre>
<pre>printf %s\\n "stringa da stampare"
printf %s\\n "$var"</pre>
* stampa con a capo prima e dopo
* stampa con a capo prima e dopo
<pre>printf \\n%s\\n "$var" </pre>
<pre>printf \\n%s\\n "stringa" </pre>
 
'''Mai''' stampare una stringa e ancora peggio una variabile senza farla precedere dal formato:
<pre>
printf "stringa"    # ERRORE: le sequenze speciali inizianti in \ e % verrebbero interpretate!
printf "$var"      # ERRORE: come sopra
printf %s "stringa" # corretto
printf %s "$var"   # corretto
</pre>


Per usi più complessi, anziché rendere più complicato il formato, è preferibile utilizzare più comandi <code>printf</code>:
Per usi più complessi, anziché rendere più complicato il formato, è preferibile utilizzare più comandi <code>printf</code>:
Riga 59: Riga 82:


# equivalente, ma più leggibile:
# equivalente, ma più leggibile:
printf %s\\n   "Sintassi:"
printf %s\\n "Sintassi:"
printf \\t%s\\n "$0  [ arg ]"
printf '\t%s\n' "$0  [ arg ]"
</pre>
</pre>


Riga 72: Riga 95:


==Assegnazioni==
==Assegnazioni==
Non si deve usare il <code>'''$'''</code> davanti alla variabile a cui assegnare:
Non si deve usare il <code>'''$'''</code> davanti alla variabile a cui assegnare.  La forma consigliata, salvo necessità particolari, è quella tra virgolette per le stringhe e le concatenazioni di stringhe e variabili, e senza virgolette per una singola variabile:
<pre>
<pre>
var=stringa                        # assegno una stringa senza spazi e caratteri speciali
var="stringa"
var="stringa con spazi"             # assegno una stringa con spazi
var=$var2                   # senza virgolette
var='stringa senza apici'          # assegno una stringa contenente spazi e caratteri speciali
var=${var2}                 # equivalente a sopra
var=$var2                           # assegno un'altra variabile
var="$var2"                 # come sopra
var=${var2}                         # come sopra
var="${var1} testo ${var2}" # con virgolettte
var="$var2"                         # come sopra (non serve quotare nelle assegnazioni)
</pre>
var='$var2'                        # assegno letteralmente $var2 (e non il suo contenuto)
 
var="\$var2"                        # come sopra, perché $ è preceduto da \
Altre forme sono possibili, e il loro significato è trattato in seguito:
var="${var1} testo ${var2}_${var3}" # assegno una concatenazione di variabili e stringhe
<pre>
var=stringa              # assegno una stringa (senza spazi e caratteri speciali)
var=$'stringa con escape' # come sopra, ma con caratteri di escape e senza espansioni
var='stringa senza apici' # niente espansioni, né caratteri di escape
# espansioni...
var=$(comando)            # assegna l'output del comando
var=$(($n * 10))          # assegna il risultato dell'operazione
var=~utente              # assegna la home di utente
</pre>
</pre>


Riga 183: Riga 213:
</pre>
</pre>


==Espansione dei caratteri di escape==
==Racchiudere tra apici==
Sintassi: <code>$'stringa'</code>
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:
<pre>printf %s\\n '$PATH "" \ `ls ..` \$HOME ~ * .[a-z]*' # stampa la stringa tra apici, letteralmente</pre>
 
Lo svantaggio è che non esiste un carattere di escape:
<pre>printf %s\\n 'L'\''albero di... ' # stampa "L'albero di..." (l'accento non può essere racchiuso tra apici)</pre>


Se l'espansione non è quotata o preceduta da escape, e la stringa non è una variabile, ne espande i caratteri di escape (utilizzabili anche con ''printf''):
==Racchiudere tra $'...'==
Una stringa racchiusa tra <code>$'...'</code> non può essere espansa in nessun modo, come se fosse racchiusa tra apici. Il carattere <code>\</code> resta un carattere di escape, quindi è possibile inserire un apice nella stringa facendolo precedere da <code>\</code> e dev'essere preceduto dal carattere di escape anche ogni <code>\</code> da stampare letteralmente.
 
Un carattere <code>\</code> non preceduto da escape permette di stampare caratteri di escape, con la stessa sintassi del formato di <code>printf</code> (quando racchiuso tra apici):
* '''\n''', nuova riga;
* '''\n''', nuova riga;
* '''\b''', backspace (cancella un carattere);
* '''\b''', backspace (cancella un carattere);
Riga 194: Riga 231:
* ecc...
* ecc...


==Racchiudere tra apici==
Per esempio:
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:
<pre>
<pre>printf %s\\n '$PATH "" \ `ls ..` \$HOME ~ * .[a-z]*' # stampa la stringa tra apici, letteralmente</pre>
printf %s\\n $'$PATH "" `ls ..`' # nessuna espansione
 
printf %s\\n $'~ * .[a-z]*'     # nessuna espansione
Lo svantaggio è che non esiste un carattere di escape:
printf %s\\n $'{a,b,c} $((2*2))' # nessuna espansione
<pre>printf %s\\n 'L'\''albero di... ' # stampa "L'albero di..." (l'accento non può essere racchiuso tra apici)</pre>
printf %s\\n $'escape: \\'      # per stampare un \ dev'essere preceduto da \
printf %s\\n $'L\'albero di... ' # stampa "L'albero di..." (l'apice può essere stampato con escape)
printf %s $'L\'albero di...\n'  # equivalente (il carattere "a capo" è nella stringa invece che nel formato di printf)
</pre>


==Quotare (tra virgolette)==
==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 <code>$</code>, <code>`</code> (ma non l'apice), <code>"</code> e <code>\</code>, che devono essere preceduti dal carattere di escape <code>\</code>.
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 <code>$</code>, <code>`</code> (ma non l'apice), <code>"</code> e <code>\</code>, che devono essere preceduti dal carattere di escape <code>\</code>.


All'interno di una stringa quotata l'espansione <code>$'stringa'</code> e tutte quelle che '''non''' sono attivabili da <code>$</code> non sono permesse. Sono possibili soltanto le espansioni di variabile/parametro, di comando e aritmetiche.
All'interno di una stringa quotata tutte le espansioni che '''non''' sono attivabili da <code>$</code> non sono permesse. Sono possibili soltanto le espansioni di variabile/parametro, di comando e aritmetiche.


Per esempio:
Per esempio:
Riga 214: Riga 254:
printf %s\\n "$((2*2))"    # Esegue l'espressione aritmetica e stampa 4
printf %s\\n "$((2*2))"    # Esegue l'espressione aritmetica e stampa 4
printf %s\\n "~ * .[a-z]*" # non effettua le espansioni di tilda e percorso, ma stampa letteralmente
printf %s\\n "~ * .[a-z]*" # non effettua le espansioni di tilda e percorso, ma stampa letteralmente
printf %s\\n "{a,b} $'\n'" # stampa letteralmente, senza espansioni
printf %s\\n "p{a,b,c}s"   # niente espansioni
</pre>
</pre>


=Espansioni in stringhe quotate=
=Espansioni in stringhe quotate=
Le espansione attivate da <code>$</code> avvengono con la stessa priorità, e in una stringa quotata con l'eccezione di <code>$'stringa'</code> sono le uniche permesse, quindi il risultato di un'espansione non può mai essere espanso un'altra volta all'interno di una stringa quotata. Sono permesse le sole espansioni di variabile, già vista, e di parametro, di comando e aritmetica (intera), che saranno trattate in seguito.
Le espansione attivate da <code>$</code> avvengono con la stessa priorità, e in una stringa quotata sono le uniche permesse, quindi il risultato di un'espansione non può mai essere espanso un'altra volta. Sono permesse le sole espansioni di variabile, già vista, e di parametro, di comando e aritmetica (intera), che saranno trattate in seguito.


==Espansione di parametro (stringa)==
==Espansione di parametro (stringa)==
Riga 390: Riga 430:


=Espansioni non quotabili=
=Espansioni non quotabili=
Le espansioni trattate nelle sezioni successive avvengono unicamente in stringhe non quotate, almeno limitatamente ai caratteri speciali che le attivano. L'espansione <code>$'stringa'</code> non è quotabile, ma è stata già trattata con i caratteri di escape.
Le espansioni trattate nelle sezioni successive avvengono unicamente in stringhe non quotate, almeno limitatamente ai caratteri speciali che le attivano, e sono attivabili soltanto da caratteri diversi dal '''$'''.


Le loro priorità sono tutte diverse: l'espansione di parentesi è quella maggiore, seguita dalla tilda, da tutte le espansioni attivabili con '''$''' (quelle quotabili e <code>$'stringa'</code>) e infine dall'espansione di percorso.
Le loro priorità sono tutte diverse: l'espansione di parentesi è quella maggiore, seguita dalla tilda, da tutte le espansioni attivabili con '''$''' (quelle quotabili) e infine dall'espansione di percorso.


Inoltre le espansioni di parentesi e di percorso, che potrebbero essere espanse a più di una singola stringa, non sono possibili direttamente in un'assegnazione.
Inoltre l'espansione di tilda, che è sempre espansa in una singola stringa, è l'unica possibile in un'assegnazione tra le espansioni non quotabili.


==Espansione di tilda==
==Espansione di tilda==
Riga 548: Riga 588:
Infatti non esiste un modo di contenere il carattere ASCII n. 0 in nessuna posizione:
Infatti non esiste un modo di contenere il carattere ASCII n. 0 in nessuna posizione:
<pre>
<pre>
var=$(printf \\000)    # SBAGLIATO: $var è vuota
var=$'\000# SBAGLIATO: $var è vuota
var=$(printf \\000X)    # SBAGLIATO: $var contiene solo X
var=$'X\000X' # SBAGLIATO: $var contiene XX
var=$(printf X\\000X# SBAGLIATO: $var contiene XX
var="$(printf X\\000X)" # SBAGLIATO: equivalente a sopra
var=$'\000'            # SBAGLIATO anche così!
</pre>
</pre>


Riga 656: Riga 693:
|Verificata_da=
|Verificata_da=
:[[Utente:S3v|S3v]] (in Bash tips)
:[[Utente:S3v|S3v]] (in Bash tips)
:[[Utente:HAL 9000|HAL 9000]] 12:00, 14 lug 2014 (CEST)
:[[Utente:HAL 9000|HAL 9000]] 12:14, 15 lug 2014 (CEST)
|Estesa_da=
|Estesa_da=
:[[Utente:S3v|S3v]] (in Bash tips)
:[[Utente:S3v|S3v]] (in Bash tips)
3 581

contributi