comprensione del valore predefinito di IFS


10

Nella mia GNU bash versione 4.2.8, IFS ha un valore predefinito di spazio, tab e line feed di default:

usr@T42 ~ $ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
00000003
usr@T42 ~ $ 

C'è un motivo per tale IFS predefinito? Inoltre, quali utility usano IFS oltre a bash built-in read?

Risposte:


13

La variabile IFS viene utilizzata ogni volta che la shell esegue un'attività chiamata suddivisione in parole . I casi più comuni in cui questo viene utilizzato è dopo l'espansione dei parametri (ad es. $var) O la sostituzione dei comandi (ad es. $(some-command)O i backtick obsoleti) in un comando. Qui se l'espansione contiene dei IFScaratteri, viene suddivisa in diverse "parole" prima che il comando venga elaborato. In pratica ciò significa che questi caratteri suddividono il testo sostituito in diversi argomenti (incluso il nome del comando se la variabile viene specificata per prima).

Pertanto, la ragione per cui il valore predefinito di IFSspazio, tab e newline è che sono gli spazi bianchi che normalmente ci si aspetterebbe di dividere una parola.

Un modo per evitare che si verifichi la divisione delle parole è utilizzare le virgolette doppie attorno all'espansione ( "$var") - in effetti lo hai fatto nella tua domanda. Se non lo facessi, non ci sarebbe alcun output in echoquanto non avrebbe argomenti, solo caratteri che dividono gli argomenti.

Si noti inoltre che due punti in cui la divisione delle parole non si verifica dopo l'espansione dei parametri sono con assegnazione variabile (ad es. var=$othervarE var=$(somecommand)va bene), e all'interno del [[ ]]costrutto ( [[ $var = $othervar ]]è ok, ma [ $var = $othervar ]dovrebbe essere citato).

Infine, come mi ha indicato una volta un saggio, un malinteso comune è che la prevenzione della divisione delle parole è l' unica ragione per citare una variabile. Non lo è, la quotazione impedisce anche l' espansione del nome percorso o l' espansione glob come è più comunemente noto. Se una variabile contiene caratteri glob come *allora questi possono essere espansi in nomi di file quando la variabile viene utilizzata non quotata in un comando. Ad esempio, considera:

var=*
echo $var

Questo visualizzerà i nomi dei file nella directory corrente.

Come Stephane sottolinea di seguito , l'ordine dei personaggi all'interno IFSè significativo quando si espande "$*". Dalla bashpagina man:

"$*" is equivalent to "$1c$2c...", where c is the first character of the value of
the IFS variable.  If IFS is unset, the parameters are separated by spaces.  If
IFS is null, the parameters are joined without intervening separators.

Per ulteriori esempi di suddivisione delle parole, vedere questa risposta - https://unix.stackexchange.com/a/118444/48083


1
$IFSViene utilizzato anche il primo carattere di in "$*"cui è importante l'ordine.
Stéphane Chazelas,

2
Si noti inoltre che zshinclude il carattere NUL nel suo valore predefinito $IFS(altre shell non supportano il mantenimento del carattere NUL nelle loro variabili).
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.