Sie können IFS nach Bedarf speichern und zuweisen. Daran ist nichts auszusetzen. Es ist nicht ungewöhnlich, den Wert für die Wiederherstellung nach einer vorübergehenden, schnellen Änderung zu speichern, wie z. B. in Ihrem Beispiel für die Array-Zuweisung.
Wie @llua in seinem Kommentar zu Ihrer Frage erwähnt, wird durch einfaches Deaktivieren von IFS das Standardverhalten wiederhergestellt, das dem Zuweisen einer Leerzeichen-Tabulator-Zeile entspricht.
Es lohnt sich zu überlegen, wie problematischer es sein kann, IFS nicht explizit zu setzen / zu entfernen, als dies zu tun.
Ab der POSIX 2013 Edition, 2.5.3 Shell-Variablen :
Implementierungen ignorieren möglicherweise den Wert von IFS in der Umgebung oder das Fehlen von IFS in der Umgebung zum Zeitpunkt des Aufrufs der Shell. In diesem Fall setzt die Shell IFS beim Aufruf auf <Leerzeichen> <Tabulator> <Zeilenumbruch> .
Eine POSIX-kompatible, aufgerufene Shell kann IFS von ihrer Umgebung erben oder nicht. Daraus folgt:
- Ein portierbares Skript kann IFS nicht zuverlässig über die Umgebung erben.
- Ein Skript, das nur das standardmäßige Aufteilungsverhalten (oder im Fall von Joining
"$*"
) verwenden möchte, jedoch möglicherweise unter einer Shell ausgeführt wird, die IFS aus der Umgebung heraus initialisiert, muss IFS explizit aktivieren / deaktivieren, um sich gegen das Eindringen in die Umgebung zu schützen.
NB Es ist wichtig zu verstehen, dass für diese Diskussion das Wort "angerufen" eine bestimmte Bedeutung hat. Eine Shell wird nur aufgerufen, wenn sie explizit mit ihrem Namen (einschließlich eines #!/path/to/shell
Shebang) aufgerufen wird . Eine Subshell, wie sie beispielsweise von $(...)
oder erstellt wird, cmd1 || cmd2 &
ist keine aufgerufene Shell, und ihr IFS ist (zusammen mit dem Großteil ihrer Ausführungsumgebung) mit dem der übergeordneten Shell identisch. Eine aufgerufene Shell setzt den Wert von $
auf ihre PID, während Subshells ihn erben.
Dies ist nicht nur eine pedantische Auseinandersetzung; In diesem Bereich gibt es tatsächliche Abweichungen. Hier ist ein kurzes Skript, das das Szenario mit verschiedenen Shells testet. Es exportiert ein modifiziertes IFS (gesetzt auf :
) in eine aufgerufene Shell, die dann ihr Standard-IFS druckt.
$ 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 ist im Allgemeinen nicht für den Export markiert, aber wenn dies der Fall ist, beachten Sie, dass bash, ksh93 und mksh die Umgebungen ignorieren IFS=:
, während dash und busybox dies berücksichtigen.
$ 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
Einige Versionsinformationen:
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
Obwohl bash, ksh93 und mksh IFS nicht aus der Umgebung initialisieren, exportieren sie ihr modifiziertes IFS erneut.
Wenn Sie IFS aus irgendeinem Grund portabel über die Umgebung übergeben müssen, können Sie dies nicht mit IFS selbst tun. Sie müssen den Wert einer anderen Variablen zuweisen und diese Variable für den Export markieren. Kinder müssen diesen Wert dann explizit ihrem IFS zuweisen.