man bash
diz:
... redirection operators may precede or appear anywhere within a simple command or may follow a command.
while
não é um comando simples.
Bash permite que você especifique uma entrada redirecionada antes de um comando:
$ <lines sed 's/^/line: /g'
line: foo
line: bar
O Bash também permite redirecionar a entrada para um comando composto, como um loop while
:
$ while read line; do echo "line: $line"; done <lines
line: foo
line: bar
No entanto, quando tento especificar uma entrada redirecionada antes de um loop while
, recebo um erro de sintaxe:
$ <lines while read line; do echo "line: $line"; done
bash: syntax error near unexpected token 'do'
O que há de errado com isso? Não é possível especificar uma entrada redirecionada antes de um comando composto no Bash? Se sim, porque não?
man bash
diz:
... redirection operators may precede or appear anywhere within a simple command or may follow a command.
while
não é um comando simples.
Você pode, em zsh
, não em bash
e coroba, já indicar a documentação , mas se você quiser redirecionar antes, pode fazer coisas como:
< file eval '
while IFS= read -r line; do
...
done'
Ou (em sistemas com suporte para /dev/fd/n
):
< file 3<< 'EOF' . /dev/fd/3
while IFS= read -r line; do
...
done
EOF
(não que você queira fazer isso).
Você também pode fazer:
exec 3< file
while IFS= read -r line <&3; do
...
done
exec 3<&-
(observe que exec
sairá do script se file
não puder ser aberto).
Ou use uma função:
process()
while IFS= read -r line; do
...
done
< file process
Você pode usar essa substituição se quiser preceder a entrada:
cat lines | while read line; do echo "line: $line"; done
Você pode usar exec para redirecionar o stdin.
Em um script:
exec < <(cat lines)
while read line ; do echo "line: $line"; done
Você não pode usar em um shell de login (ele irá despejar o arquivo no stdout e sair). Nesse caso, você pode abrir um descritor de arquivo diferente:
exec 3< <(cat lines)
while read -u 3 line ; do echo "line: $line"; done
Para referência: Usando o exec
Tags bash shell io-redirection