Você pode salvar e atribuir ao IFS conforme necessário. Não há nada errado em fazer isso. Não é incomum salvar seu valor para restauração após uma modificação temporária e rápida, como o exemplo de atribuição de matriz.
Como @llua menciona em seu comentário à sua pergunta, simplesmente desabilitar o IFS restaurará o comportamento padrão, equivalente a atribuir uma nova linha de aba de espaço.
Vale a pena considerar como pode ser mais problemático não definir / desabilitar explicitamente o IFS do que fazê-lo.
Na edição POSIX 2013, 2.5.3 Shell Variables :
As implementações podem ignorar o valor do IFS no ambiente ou a ausência do IFS no ambiente no momento em que o shell é chamado; nesse caso, o shell deve definir o IFS para <espaço> <tab> <novaline> quando é chamado .
Um shell invocado compatível com POSIX pode ou não herdar o IFS de seu ambiente. A partir disso, segue-se:
- Um script portátil não pode herdar o IFS de maneira confiável por meio do ambiente.
- Um script que pretende usar apenas o comportamento de divisão padrão (ou ingressar, no caso de
"$*"
), mas que pode ser executado em um shell que inicializa o IFS a partir do ambiente, deve explicitamente definir / desabilitar o IFS para se defender contra invasões ambientais.
NB É importante entender que, para esta discussão, a palavra "invocado" tem um significado particular. Um shell é chamado apenas quando é chamado explicitamente usando seu nome (incluindo um #!/path/to/shell
shebang). Um subshell - como pode ser criado por $(...)
ou cmd1 || cmd2 &
- não é um shell invocado e seu IFS (junto com a maior parte de seu ambiente de execução) é idêntico ao do pai. Um shell invocado define o valor de $
para seu pid, enquanto os subshells o herdam.
Isso não é meramente uma disquisição pedante; existe divergência real nessa área. Aqui está um breve script que testa o cenário usando vários shells diferentes. Ele exporta um IFS modificado (definido como :
) para um shell chamado que, em seguida, imprime seu IFS padrão.
$ 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
O IFS geralmente não é marcado para exportação, mas, se assim for, observe como o bash, ksh93 e mksh ignoram o ambiente IFS=:
, enquanto o dash e o busybox o honram.
$ 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
Algumas informações da versão:
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
Embora bash, ksh93 e mksh não inicializem o IFS do ambiente, eles reexportam o IFS modificado.
Se, por qualquer motivo, você precisar passar o IFS de maneira portável pelo ambiente, não poderá fazê-lo usando o próprio IFS; você precisará atribuir o valor a uma variável diferente e marcar essa variável para exportação. As crianças precisarão atribuir explicitamente esse valor ao seu IFS.