When reading a file line by line, I only get to ex

2019-01-28 09:10发布

问题:

I'm writing a Bash script in which I read a file line by line ( well, <(find /home/user/ -iname "*.MP4") to be exact ) , and for each line I execute ffmpeg, so I'm doing something like this:

while read -r line; do
    ffmpeg -i "$line" [ MORE OPTIONS ... ]
done < <(find /home/user/ -iname "*.MP4")

Though, for some reason, only the first line is being processed successfuly.

Any idea why my code ignores all other lines ?

回答1:

That's a frequent problem which is caused by the special behavior of ffmpeg (also happens with ssh ).

Quoted from Bash FAQ 89 which handles your case almost exactly:

What's happening here? Let's take the first example. read reads a line from standard input (FD 0), puts it in the file parameter, and then ffmpeg is executed. Like any program you execute from BASH, ffmpeg inherits standard input, which for some reason it reads. I don't know why. But in any case, when ffmpeg reads stdin, it sucks up all the input from the find command, starving the loop.

TL;DR :

There are two main options:

  • Adding a </dev/null at the end of ffmpeg's line ( i.e. ffmpeg -i "$line" [ MORE OPTIONS ] ... </dev/null ) will fix the issue and will make ffmpeg behave as expected.

  • Let read read from a File Descriptor which is unlikely to be used by a random program:

       while IFS= read -r line <&3; do
           # Here read is reading from FD 3, to which 'file' is redirected.
       done 3<file