(Desculpe, longa explicação)
Sim, a variável IFS
em while IFS=" " read; do …
não tem efeito no restante do código.
Vamos primeiro precisar que a linha de comando do shell apresenta dois tipos diferentes de variáveis:
- variáveis de shell (que só existem em um shell e são locais no shell)
- variáveis de ambiente, que existem para todos os processos. Geralmente, eles são preservados em
fork()
eexec()
, de modo que os processos filhos os herdam.
Quando você chama um comando com:
A=foo B=bar command
o comando é executado em um ambiente no qual a variável (ambiente) A
está definida como foo
e B
está definida como bar
. Mas com esta linha de comando, as variáveis atuais do shell A
e B
são deixadas inalteradas .
Isso é diferente de:
A=foo; B=bar; command
Aqui, as variáveis de shell A
e B
são definidas e o comando é executado sem as variáveis de ambiente A
e B
defined. Os valores de A
e B
são inacessíveis em command
.
No entanto, se algumas variáveis do shell forem export
-ed, as variáveis de ambiente correspondentes serão sincronizadas com suas respectivas variáveis do shell. Exemplo:
export A
export B
A=foo; B=bar; command
Com este código, as duas variáveis shell e as variáveis ambiente shell são definidas como foo
e bar
. Como as variáveis de ambiente são herdadas por subprocessos, command
poderá acessar seus valores.
Para voltar à sua pergunta original, em:
IFS='a' read
apenas read
é afetado. E, de fato, nesse caso, read
não se importa com o valor da variável IFS
. Ele usa IFS
somente quando você pede que a linha seja dividida (e armazenada em diversas variáveis), como em:
echo "a : b : c" | IFS=":" read i j k; \
printf "i is '%s', j is '%s', k is '%s'" "$i" "$j" "$k"
IFS
não é usado por read
, a menos que seja chamado com argumentos. ( Editar: Isso não é exatamente verdade: caracteres em branco, ou seja, espaço e tabulação, presentes em IFS
, são sempre ignorados no início / fim da linha de entrada.)