Bash tips: differenze tra le versioni

→‎Bash Scripting: caratteri di escape e correzioni
mNessun oggetto della modifica
(→‎Bash Scripting: caratteri di escape e correzioni)
Riga 193: Riga 193:
Si noti che la forma abbreviata considera il nome della variabile come composto da tutti i caratteri validi incontrati. Per esempio <code>"$nome$cognome"</code> è equivalente a <code>"${nome}${cognome}"</code>, ma <code>"$nome_$cognome"</code> non lo è a <code>"${nome}_${cognome}"</code> perché <code>nome_</code> (con underscore finale) sarebbe un nome di variabile valido. In caso di concatenazione di variabili è preferibile accedere alle variabili con le graffe, o in alternativa (meno elegante) delimitarle dalle virgolette; infatti <code>"$nome"_"$cognome"</code> corrisponde a <code>"${nome}_${cognome}"</code>.
Si noti che la forma abbreviata considera il nome della variabile come composto da tutti i caratteri validi incontrati. Per esempio <code>"$nome$cognome"</code> è equivalente a <code>"${nome}${cognome}"</code>, ma <code>"$nome_$cognome"</code> non lo è a <code>"${nome}_${cognome}"</code> perché <code>nome_</code> (con underscore finale) sarebbe un nome di variabile valido. In caso di concatenazione di variabili è preferibile accedere alle variabili con le graffe, o in alternativa (meno elegante) delimitarle dalle virgolette; infatti <code>"$nome"_"$cognome"</code> corrisponde a <code>"${nome}_${cognome}"</code>.


Nelle assegnazioni non si deve usare il <code>'''$'''</code>, salvo che per accedere al contenuto di altre variabili. Ed è superfluo anche l'uso delle virgolette, salvo concatenazioni e spazi in cui è preferibile assieme all'uso delle graffe:
Nelle assegnazioni non si deve usare il <code>'''$'''</code>, salvo che per accedere al contenuto di altre variabili:
<pre> variable=stringa                         # assegno un valore (una stringa)
<pre> variable="stringa"                        # assegno un valore (una stringa)
  variabile="stringa con spazi"            # assegno una stringa con spazi
  variabile="stringa con spazi"            # assegno una stringa con spazi
  variabile=$altra_variabile                # assegno una variabile
  variabile=$altra_variabile                # assegno una variabile
Riga 271: Riga 271:
   echo ${VAR/st/ST}  # --> queSTa.sarebbe.una.stringa.di.esempio
   echo ${VAR/st/ST}  # --> queSTa.sarebbe.una.stringa.di.esempio
   echo ${VAR//st/ST}  # --> queSTa.sarebbe.una.STringa.di.esempio</pre>
   echo ${VAR//st/ST}  # --> queSTa.sarebbe.una.STringa.di.esempio</pre>
===Caratteri di escape===
Alcuni caratteri hanno un valore speciale per la shell, per consentirne le espansioni (di variabile, parametro, comando, percorso, ecc...). Di conseguenza se si intende scrivere un carattere speciale senza espanderlo, è necessario comunicarlo alla shell facendolo precedere da un carattere di escape '<code>\</code>' oppure racchiudendolo tra apici o virgolette (a seconda dell'espansione da disattivare).
Questa sezione non è esaustiva, ma consiglia qualche semplice accorgimento:
* racchiudere tra apici (apostrofi) una stringa riduce a uno soltanto i caratteri speciali, ossia lo stesso apice, rappresentando la stringa per il suo solo valore letterale e impedendo tutte le espansioni. Lo svantaggio è che non esiste un carattere di escape, e che quindi un apice contenuto nella stringa non può essere racchiuso tra apici, rendendone più complicato l'escape. Per esempio:
:<pre>echo '$PATH "" \ `ls ..` \$HOME ~ * .[a-z]*'  # stampa la stringa tra apici, così com'è scritta</pre>
:<pre>echo 'L'\''albero di... ' # l'accento non deve essere racchiuso tra apici, e va preceduto da \</pre>
* racchiudere tra virgolette (ossia quotare) ogni stringa è in genere raccomandabile e la scelta consigliata, così da ridurre drasticamente il numero di caratteri speciali, permettendo l'uso delle variabili. I soli caratteri speciali sono <code>$</code>, <code>`</code> (ma non l'apice), <code>"</code> e <code>\</code> devono essere preceduti dal carattere di escape <code>\</code>. Le espansioni di percorso e tilda (*, ?, [...], ~, ... ) non sono possibili; mentre lo sono quelle di variabile e parametro (attraverso un <code>$</code> senza <code>\</code>), e quelle di comando (attraverso un <code>`</code> o un <code>$(</code> senza <code>\</code>). Riprendendo l'esempio:
:<pre>echo "$PATH \"\" \\ `ls ..` \$HOME ~ * .[a-z]*" # espande PATH e il comando ls, ma non HOME. Si noti l'uso dei \.</pre>
* non racchiudere tra virgolette e apici serve a permettere le espansioni di percorso e tilda. È sempre consigliabile racchiudere tutto il resto tra virgolette. I più comuni sono (si ricordi per le espansioni che su ambienti UNIX e Unix-like per file si intende sia un file regolare, sia una directory, un link, una pipe, un socket, un device, ecc...):
** <code>~</code> espande alla home (equivalente alla variabile $HOME, che però può essere quotata);
*** <code>~utente</code> espande alla home di un dato utente, ma la stringa utente non può essere quotata né essere una variabile da espandere;
** <code>?</code> pattern per un singolo carattere di un file;
*** <code>nomefile.???</code> combacia con tutti i file con nome "nomefile" e terminanti con tre caratteri qualsiasi per estensione;
** <code>*</code> pattern per tutti i possibili caratteri di un file (di default tranne quelli inizianti con .):
*** <code>*</code> da solo espande a tutti i file non nascosti nella directory corrente. È sempre buona norma far precedere l'asterisco da un ./, che indica la cartella corrente, se è il primo carattere del pattern, per impedire espansioni di file inizianti con "-", che potrebbero essere visti come opzioni da alcuni comandi;
*** <code>./*</code> equivalente a <code>*</code> ma più sicuro; di seguito si aggiunge il prefisso della directory corrente a tutte le espansioni inizianti con <code>*</code>;
*** <code>./*.txt</code> espande a tutti i file con estensione .txt;
*** <code>./*/</code> espande a tutte le directory non nascoste;
*** <code>prefisso*suffisso</code>espande a tutti i file con un dato prefisso e suffisso;
*** <code>./*."${estensione}"</code> espande dopo aver espanso la variabile (contrariamente a ~), che può anche essere quotata.
È importante tenere presente per le espansioni di percorso che, se nessun file combacia con un dato pattern, allora l'espansione *non* viene effettuata e i caratteri mantengono il loro valore originale. Per di più <code>*</code> e <code>?</code> sono caratteri validi per un nome di file. L'esistenza di file ottenuti da tali espansioni va pertanto sempre controllata, per esempio con <code>[ -e "$file" ]</code>:
<pre>for file in ./*; do
  if [ -e "$file" ]; then
      ...
  fi
done</pre>


===Concatenazione e redirezione===
===Concatenazione e redirezione===
Riga 333: Riga 367:
Rinomina tutti i file <code>*.txt</code> della directory corrente in <code>*.log</code>:
Rinomina tutti i file <code>*.txt</code> della directory corrente in <code>*.log</code>:


  $ for f in *.txt; do mv -- "$f" "${f/%txt/log}"; done
  $ for f in ./*.txt; do if [ -e "$f" ]; then mv -- "$f" "${f/%txt/log}"; fi; done


{{Suggerimento | L'opzione "--" dopo il comando esterno <code>mv</code> serve per comunicargli che le stringhe che seguono non sono opzioni, nemmeno se iniziassero con il carattere "-". È sempre buona norma utilizzarla con comandi che accettano file come argomenti, il cui nome non è noto a priori, in particolare per comandi che manipolano i file, come: <code>rm</code>, <code>cp</code>, <code>mv</code>, ecc... <br/>
{{Suggerimento | L'opzione "--" dopo il comando esterno <code>mv</code> serve per comunicargli che le stringhe che seguono non sono opzioni, nemmeno se iniziassero con il carattere "-". È sempre buona norma utilizzarla come controllo aggiuntivo con comandi che accettano file come argomenti, il cui nome non è noto a priori, in particolare per comandi che manipolano i file come: <code>rm</code>, <code>cp</code>, <code>mv</code>, ecc... <br/>
L'opzione deve essere supportata dal comando esterno, non è trattata specialmente dalla shell.}}
L'opzione deve essere supportata dal comando esterno, non è trattata specialmente dalla shell.}}


3 581

contributi