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?

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.

| improve this answer | |

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<&-
| improve this answer | |

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)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.