Una variabile non quotata (come in $var
) o la sostituzione di comando (come in $(cmd)
o `cmd`
) è l' operatore split + glob in shell tipo Bourne.
Cioè, il loro contenuto è diviso in base al valore corrente della $IFS
variabile speciale (che per impostazione predefinita contiene lo spazio, la scheda e i caratteri di nuova riga)
E quindi ogni parola risultante da quella suddivisione è soggetta alla generazione del nome del file (noto anche come globbing o espansione del nome file ), cioè sono considerati come modelli e vengono espansi all'elenco dei file che corrispondono a quel modello.
Quindi in for i in $(xrandr)
, $(xrandr)
poiché non è racchiuso tra virgolette, è diviso in sequenze di caratteri di spazio, tabulazione e newline. E ogni parola risultante da quella suddivisione viene controllata per trovare i nomi dei file corrispondenti (o lasciata così com'è se non corrispondono a nessun file) e for
scorre su tutti.
In for i in "$(xrandr)"
, non stiamo usando l'operatore split + glob come viene citata la sostituzione del comando , quindi c'è un passaggio nel ciclo su un valore: l'output di xrandr
(senza i caratteri di nuova riga finali che comandano le strisce di sostituzione ).
Tuttavia echo $i
, $i
viene nuovamente citato, quindi il contenuto di $i
viene diviso e soggetto alla generazione del nome file e questi vengono passati come argomenti separati al echo
comando (e echo
restituisce i suoi argomenti separati da spazi).
Quindi lezione imparata:
- se non si desidera la suddivisione delle parole o la generazione del nome file , citare sempre espansioni variabili e sostituzioni di comandi
- se si desidera la suddivisione delle parole o la generazione del nome file , lasciarli non quotati ma impostare di
$IFS
conseguenza e / o abilitare o disabilitare la generazione del nome file, se necessario ( set -f
, set +f
).
In genere, nell'esempio sopra riportato, se si desidera passare in rassegna l'elenco di parole separato vuoto nell'output di xrandr
, è necessario:
- lasciare
$IFS
al suo valore predefinito (o disinserirlo) per dividere gli spazi vuoti
- Utilizzare
set -f
per disabilitare la generazione nome di file se non sei sicuro che xrandr
non emette alcun *
o ?
o [
personaggi (che sono i caratteri jolly utilizzati nei modelli di generazione di file)
E quindi usa solo l'operatore split + glob (lascia solo la sostituzione dei comandi o l'espansione variabile non quotata) nella in
parte del for
ciclo:
set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done
Se si desidera ciclo nel corso dei (non-vuoto) le linee di xrandr
uscita, avresti bisogno di set $IFS
per il carattere di nuova riga:
IFS='
'