È possibile salvare e assegnare a IFS secondo necessità. Non c'è niente di sbagliato nel farlo. Non è raro salvare il suo valore per il ripristino in seguito a una modifica temporanea e rapida, come nell'esempio di assegnazione dell'array.
Come menziona @llua nel suo commento alla tua domanda, il semplice disinserimento di IFS ripristinerà il comportamento predefinito, equivalente all'assegnazione di uno spazio-tab-newline.
Vale la pena considerare come può essere più problematico non impostare / disinserire IFS in modo esplicito piuttosto che farlo.
Dall'edizione POSIX 2013, 2.5.3 Variabili shell :
Le implementazioni possono ignorare il valore di IFS nell'ambiente o l'assenza di IFS dall'ambiente, nel momento in cui viene invocata la shell, nel qual caso la shell deve impostare IFS su <spazio> <tab> <nuova> quando viene invocata .
Una shell invocata conforme a POSIX può o meno ereditare IFS dal suo ambiente. Da ciò segue:
- Uno script portatile non può ereditare in modo affidabile IFS attraverso l'ambiente.
- Uno script che intende utilizzare solo il comportamento di suddivisione predefinito (o l'unione, nel caso di
"$*"
), ma che può essere eseguito in una shell che inizializza IFS dall'ambiente, deve impostare / disinserire esplicitamente IFS per difendersi dalle intrusioni ambientali.
NB È importante capire che per questa discussione la parola "invocato" ha un significato particolare. Una shell viene invocata solo quando viene esplicitamente chiamata usando il suo nome (incluso uno #!/path/to/shell
shebang). Una subshell - come potrebbe essere creata da $(...)
o cmd1 || cmd2 &
- non è una shell invocata e il suo IFS (insieme alla maggior parte del suo ambiente di esecuzione) è identico a quello del suo genitore. Una shell invocata imposta il valore su $
pid, mentre le subshell lo ereditano.
Questa non è semplicemente una inquietudine pedante; c'è un'effettiva divergenza in questo settore. Ecco un breve script che verifica lo scenario usando diverse shell. Esporta un IFS modificato (impostato su :
) in una shell invocata che quindi stampa il suo IFS predefinito.
$ cat export-IFS.sh
export IFS=:
for sh in bash ksh93 mksh dash busybox:sh; do
printf '\n%s\n' "$sh"
$sh -c 'printf %s "$IFS"' | hexdump -C
done
IFS non è generalmente contrassegnato per l'esportazione, ma, se lo fosse, nota come bash, ksh93 e mksh ignorano l'ambiente IFS=:
, mentre dash e busybox lo onorano.
$ sh export-IFS.sh
bash
00000000 20 09 0a | ..|
00000003
ksh93
00000000 20 09 0a | ..|
00000003
mksh
00000000 20 09 0a | ..|
00000003
dash
00000000 3a |:|
00000001
busybox:sh
00000000 3a |:|
00000001
Alcune informazioni sulla versione:
bash: GNU bash, version 4.3.11(1)-release
ksh93: sh (AT&T Research) 93u+ 2012-08-01
mksh: KSH_VERSION='@(#)MIRBSD KSH R46 2013/05/02'
dash: 0.5.7
busybox: BusyBox v1.21.1
Anche se bash, ksh93 e mksh non inizializzano l'IFS dall'ambiente, riesportano l'IFS modificato.
Se per qualsiasi motivo è necessario trasferire IFS in modo portabile attraverso l'ambiente, non è possibile farlo utilizzando IFS stesso; dovrai assegnare il valore a una variabile diversa e contrassegnare quella variabile per l'esportazione. I bambini dovranno quindi assegnare esplicitamente quel valore al loro IFS.