web-dev-qa-db-ja.com

標準入力を混合せずに、コマンド出力を1行ずつ処理します

だから、私は Bash:コマンドの出力から一度に1行を読み取る方法? と非常によく似た問題を抱えています、私はやっています:

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

または

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

コマンドfind-me-random-mp3sは、ファイルパスをそれぞれ新しい行に出力します。この問題は、mplayerが実行されると始まり、find-me-random-mp3s出力からの行、つまり、各反復でpath変数内に入力されるはずの行の消費を開始します。

私はこの汚い修正を続けました:

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

しかし、私はそれが本当に好きではありません、それは私の端末とmplayerとの相互作用もブロックします。

そのような場合に使用できる代替方法はありますか?

5
aularon
exec 3<&0
while read line
do
    mplayer "$line" <&3
done < <(find-me-random-mp3s)

これにより、端末入力がファイル記述子3にコピーされます。whileループでは、端末であるファイル記述子3からstdinを取得するmplayer行を除いて、stdinはfind-me-random-mp3sプログラムから読み取られます。したがって、引き続きmplayerを操作できます。

4
John1024

別のファイル記述子を使用できます。

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

@ glenn-jackman のソリューションのより単純なバリエーションで、これも機能するはずです。

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