(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.)