So, I have a problem very similar to Bash: How to read one line at a time from output of a command?, I am doing:

while read path; do mplayer $path; done < <(find-me-random-mp3s)


find-me-random-mp3s | while read path; do mplayer $path; done

The command find-me-random-mp3s outputs file paths each on a new line. The problem starts when mplayer runs, it starts consuming lines from find-me-random-mp3s output, i.e. lines that were supposed to be filled inside the path variable on each iteration.

I went on with this dirty fix:

find-me-random-mp3s | while read path; do cat /dev/null | mplayer $path; done

But I don't really like it, it blocks my terminal interaction with mplayer too.

Is there any alternative method that I can use in such case?

3 Answers 3


You can use a different file descriptor:

exec 3< <(find-me-random-mp3s)
while IFS= read -r -u3 path; do mplayer "$path"; done
exec 3<&-
exec 3<&0
while read line
    mplayer "$line" <&3
done < <(find-me-random-mp3s)

This copies terminal input to file descriptor 3. In the while loop, stdin is everywhere read from your find-me-random-mp3s program except for the mplayer line which gets its stdin from file descriptor 3 which is your terminal. Hence, you can still interact with mplayer.


A simpler variation of @glenn-jackman's solution that should work too, I think:

while read -u3 path; do mplayer "$path"; done 3< <(find-me-random-mp3s)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .