Bash scripting - espansioni non quotabili: differenze tra le versioni

Vai alla navigazione Vai alla ricerca
Riga 90: Riga 90:
   fi
   fi
done</pre>
done</pre>
Si faccia attenzione che tutti i pattern delle espansioni di percorso, e non solo quelli composti da <code>*</code>, possono generare più stringhe, anche se sostituiscono un singolo carattere in presenza di fili multipli con lo stesso prefisso e/o suffisso (per esempio il pattern ''a?c'' può espandersi alla lista ''abc aBC acc'', se esistono questi tre file).  
Si faccia attenzione che tutti i pattern delle espansioni di percorso, e non solo quelli composti da <code>*</code>, possono generare più stringhe, anche se sostituiscono un singolo carattere in presenza di fili multipli con lo stesso prefisso e/o suffisso (per esempio il pattern ''a?c'' può espandersi alla lista ''abc aBC acc'', se esistono questi tre file).


In alternativa il comportamento di default dell'espansione può essere cambiato in bash (non ''POSIX''), tramite <code>shopt -s</code>:
===Espansione di percorso con nuovi file===
L'espansione di percorso può fallire anche se non trova corrispondenze nella parte non riguardante i caratteri speciali, perché i caratteri speciali sono espansi in funzione di tutta la stringa. Questo significa che deve esistere il risultato dell'espansione, considerando il percorso nella sua interezza, prima dell'esecuzione di un qualsiasi comando.
 
Ne consegue che è '''sempre sbagliato''' usare l'espansione di percorso direttamente con comandi di creazione di file:
<pre>
# crea un file in ogni directory, se non esiste già
touch -- ./*/"file" # SBAGLIATO! (per come avviene l'espansione)
 
# aggiorna il tempo di accesso e modifica dei file (se esistenti) in ogni directory
touch ./*/"file"    # SBAGLIATO! (sarebbe corretto SOLO se almeno un file esiste)
# forma corretta, sempre e solo con ciclo for e if [ ... ]
for file in ./*/"file"
do
  if [ -e "$file" ]; then
      touch -- "$file"
  fi
done
 
# forma corretta del comando iniziale per creare un file in ogni directory
for dir in ./*/    # SOLO la parte già esistente nell'espansione!
do
  if [ -e "$dir" ]; then
      touch -- "${dir}/file"
  fi
done
</pre>
 
===Cambiare i risultati dell'espansione===
Il comportamento di default dell'espansione può essere cambiato in bash (non ''POSIX''), tramite <code>shopt -s</code>:
* '''nullglob''' espande a "niente" se non trova nessun file con un dato pattern, rendendo superfluo il controllo sull'esistenza;
* '''nullglob''' espande a "niente" se non trova nessun file con un dato pattern, rendendo superfluo il controllo sull'esistenza;
* '''dotglob''' espande ai file nascosti (ma non a '''.''' e '''..''');
* '''dotglob''' espande ai file nascosti (ma non a '''.''' e '''..''');
3 581

contributi

Menu di navigazione