risposta-alla-domanda-sullo-sviluppo-web-bd.com

Qual è il significato di IFS = $ '\ n' negli script bash?

All'inizio di uno script Shell bash c'è la seguente riga:

IFS=$'\n'

Qual è il significato dietro questa raccolta di simboli?

180
Abdul Al Hazred

IFS sta per "separatore di campo interno". Viene utilizzato da Shell per determinare come eseguire la suddivisione in Word, i. e. come riconoscere i confini della parola.

Prova questo in una shell come bash (altre shell possono gestirla diversamente, ad esempio zsh):

mystring="foo:bar baz rab"
for Word in $mystring; do
  echo "Word: $Word"
done

Il valore predefinito per IFS è costituito da caratteri di spazi bianchi (per essere precisi: spazio, tabulazione e nuova riga). Ogni personaggio può essere un confine di Word. Quindi, con il valore predefinito di IFS, il ciclo sopra verrà stampato:

Word: foo:bar
Word: baz
Word: rab

In altre parole, Shell pensa che lo spazio bianco sia un confine di Word.

Ora prova a impostare IFS=: prima di eseguire il ciclo. Questa volta, il risultato è:

Word: foo
Word: bar baz rab

Ora, Shell divide anche mystring in parole, ma ora tratta solo i due punti come il confine di Word.

Il primo carattere di IFS è speciale: viene utilizzato per delimitare le parole nell'output quando si utilizza lo speciale $* variabile (esempio tratto dalla Advanced Bash Scripting Guide , dove puoi anche trovare maggiori informazioni su variabili speciali come quella):

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

Confrontare con:

$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z

Si noti che in entrambi gli esempi, Shell tratterà comunque tutti i caratteri :, - e ; come confini di Word. L'unica cosa che cambia è il comportamento di $*.

Un'altra cosa importante da sapere è come il cosiddetto "spazio bianco IFS" viene trattato . Fondamentalmente, non appena IFS include caratteri di spazi bianchi, lo spazio bianco iniziale e finale viene rimosso dalla stringa da dividere prima di elaborarlo e una sequenza di spazi bianchi consecutivi delimita anche i campi. Tuttavia, questo vale solo per quei caratteri di spazi bianchi che sono effettivamente presenti in IFS.

Ad esempio, diamo un'occhiata alla stringa "a:b:: c d " (spazio finale e due caratteri spazio tra c e d).

  1. Con IFS=: sarebbe suddiviso in quattro campi: "a", "b", "" (stringa vuota) e " c d " (di nuovo, due spazi tra c e d). Nota lo spazio bianco iniziale e finale nell'ultimo campo.
  2. Con IFS=' :', sarebbe suddiviso in cinque campi: "a", "b", "" (stringa vuota), "c" e "d". Nessuno spazio bianco iniziale e finale da nessuna parte.

Nota come più caratteri di spazi bianchi consecutivi delimitano due campi nel secondo esempio, mentre più punti consecutivi non lo fanno (poiché non sono caratteri di spazi).

Quanto a IFS=$'\n', cioè un ksh93 sintassi supportata anche da bash, zsh, mksh e FreeBSD sh (con variazioni tra tutte le shell). Citando la manpage di bash:

Le parole del modulo $ 'stringa' sono trattate in modo speciale. Word si espande in "stringa", con i caratteri con escape backslash sostituiti come specificato dallo standard ANSI C.

\n è la sequenza di escape per una nuova riga, quindi IFS finisce per essere impostato su un singolo carattere di nuova riga.

216
Tblue

All'interno delle virgolette singole a bambola, alcuni personaggi vengono valutati appositamente. Per esempio, \n viene tradotto in una nuova riga.

Quindi, questa particolare riga assegna la nuova riga alla variabile IFS. IFS, a sua volta, è una variabile speciale in bash: Separatore di campo interno. Come man bash dice

viene utilizzato per la suddivisione in Word dopo l'espansione e per dividere le righe in parole con il comando incorporato read. Il valore predefinito è <space><tab><newline>.

23
choroba

In breve, IFS=$'\n' Assegna newline \n alla variabile IFS.

$'string' costrutto è un meccanismo di quotazione che utilizza per decodificare ANSI C come sequenze di escape. Questa sintassi viene da ksh93 ed era portabile su Shell moderne come bash, zsh, pdksh, busybox sh.

Questa sintassi non è definita da POSIX, ma è stata accettata per SUS issue 7 .

15
cuonglm