W razie potrzeby możesz zapisać i przypisać do IFS. Nie ma w tym nic złego. Często zdarza się, aby zapisać jego wartość do przywrócenia po tymczasowej, szybkiej modyfikacji, takiej jak przykład przypisania tablicy.
Jak @llua wspomina w swoim komentarzu do twojego pytania, po prostu rozbrojenie IFS przywróci domyślne zachowanie, równoważne przypisaniu spacji-tab-nowej linii.
Warto zastanowić się, w jaki sposób może być bardziej problematyczne nie jawnie ustawiać / wyłączać IFS, niż to robić.
Od wersji POSIX 2013, 2.5.3 Shell Variables :
Implementacje mogą ignorować wartość IFS w środowisku lub brak IFS ze środowiska podczas wywoływania powłoki, w którym to przypadku powłoka powinna ustawić IFS na <space> <tab> <newline>, gdy jest wywoływana .
Wywołana powłoka zgodna z POSIX może, ale nie musi, dziedziczyć IFS ze swojego środowiska. Z tego wynika:
- Skrypt przenośny nie może w sposób niezawodny dziedziczyć systemu IFS przez środowisko.
- Skrypt, który zamierza używać tylko domyślnego zachowania dzielącego (lub łączenia, w przypadku
"$*"
), ale który może działać pod powłoką inicjującą IFS ze środowiska, musi jawnie ustawić / rozbroić IFS, aby bronić się przed ingerencją w środowisko.
Uwaga: Należy zrozumieć, że w tej dyskusji słowo „przywołane” ma szczególne znaczenie. Powłoka jest wywoływana tylko wtedy, gdy jest jawnie wywoływana przy użyciu jej nazwy (w tym #!/path/to/shell
shebang). Podpowłoka - taka, która może być utworzona przez $(...)
lub cmd1 || cmd2 &
- nie jest wywoływaną powłoką, a jej IFS (wraz z większością środowiska wykonawczego) jest identyczny z nadrzędnym. Wywołana powłoka ustawia wartość $
swojego pid, a podpowłoki ją dziedziczą.
To nie jest tylko pedantyczna wyprawa; w tej dziedzinie istnieje rzeczywista rozbieżność. Oto krótki skrypt, który testuje scenariusz przy użyciu kilku różnych powłok. Eksportuje zmodyfikowany IFS (ustawiony na :
) do wywoływanej powłoki, która następnie drukuje domyślny IFS.
$ 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 nie jest generalnie oznaczony do eksportu, ale jeśli tak, zwróć uwagę, jak bash, ksh93 i mksh ignorują środowisko IFS=:
, podczas gdy dash i busybox honorują to.
$ 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
Niektóre informacje o wersji:
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
Mimo że bash, ksh93 i mksh nie inicjują IFS ze środowiska, reeksportują zmodyfikowany IFS.
Jeśli z jakiegokolwiek powodu musisz przenośnie przekazać IFS przez środowisko, nie możesz tego zrobić za pomocą samego IFS; musisz przypisać wartość do innej zmiennej i oznaczyć tę zmienną do eksportu. Dzieci będą wówczas musiały wyraźnie przypisać tę wartość do swojego IFS.