Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash/zsh input process substitution gives syntax error in conjunction with while

Tags:

bash

zsh

These work fine and do what they should (print the contents of the file foo):

cat <foo
while read line; do echo $line; done <foo
cat <(cat foo)

However this gives me a syntax error in zsh:

zsh$ while read line; do echo $line; done <(cat foo)
zsh: parse error near `<(cat foo)'

and bash:

bash$ while read line; do echo $line; done <(cat foo)
bash: syntax error near unexpected token `<(cat foo)'

Does anybody know the reason and maybe a workaround?

Note: This is obviously a toy example. In the real code I need the body of the while loop to be executed in the main shell process, so I can't just use

cat foo | while read line; do echo $line; done
like image 642
Mika Fischer Avatar asked Jan 17 '12 15:01

Mika Fischer


3 Answers

You need to redirect the process substitution into the while loop:

You wrote

while read line; do echo $line; done <(cat foo)

You need

while read line; do echo $line; done < <(cat foo)
# ...................................^

Treat a process substitution like a filename.

like image 56
glenn jackman Avatar answered Oct 21 '22 04:10

glenn jackman


bash/zsh replaces <(cat foo) by a pipe (kind of file) having a name as /dev/fd/n where n is the file descriptor (number).

You can check the pipe name using the command echo <(cat foo).

As you may know, bash/zsh also runs the command cat foo in another process. The output of this second process is written to that named pipe.

without process substitution:

while ... do ... done   inputfile #error
while ... do ... done < inputfile #correct

same rules using process substitution:

while ... do ... done   <(cat foo) #error
while ... do ... done < <(cat foo) #correct

Alternative:

cat foo >3 & while read line; do echo $line; done <3;
like image 21
oHo Avatar answered Oct 21 '22 02:10

oHo


I can suggest only workaround like this:

theproc() { for((i=0;i<5;++i)) do echo $i; }

while read line ; do echo $line ; done <<<"$(theproc)"
like image 36
Michael Krelin - hacker Avatar answered Oct 21 '22 03:10

Michael Krelin - hacker