É porque a parte em que você usa o vars é um novo conjunto de comandos. Use isso em vez disso:
head somefile | { read A B C D E FOO; echo $A $B $C $D $E $FOO; }
Observe que, nessa sintaxe, deve haver um espaço após o {
e um ; (ponto-e-vírgula) antes do } .
Também -n1 não é necessário; read apenas lê a primeira linha.
Para melhor compreensão, isso pode ajudá-lo; faz o mesmo que acima:
read A B C D E FOO < <(head somefile); echo $A $B $C $D $E $FOO
Editar:
Costuma-se dizer que as próximas duas afirmações fazem o mesmo:
head somefile | read A B C D E FOO
read A B C D E FOO < <(head somefile)
Bem, não exatamente. O primeiro é um canal de head a bash read builtin. Um stdout de um processo para stdin de outro processo.
A segunda instrução é redirecionamento e substituição de processo. É tratado pelo próprio bash . Ele cria um FIFO (pipe nomeado, <(...) ) ao qual a saída de head está conectada e redireciona ( < ) para o processo read .
Até agora, estes parecem equivalentes. Mas quando se trabalha com variáveis, isso pode importar. No primeiro, as variáveis não são definidas após a execução. No segundo, eles estão disponíveis no ambiente atual.
Cada shell tem outro comportamento nessa situação. Veja esse link para o qual eles são. Em bash , você pode contornar esse comportamento com o agrupamento de comandos {} , a substituição de processo ( < <() ) ou as strings Here ( <<< ).