私はこの問題を解決しようとしています。私は次の行を持っています:
mplayer *.* 2>/dev/null | grep Playing
開始されたばかりで、mplayer
一致する行だけが画面に印刷されました。これは、現在再生中のメディアを変更するたびに機能します。Playing filename
grepの出力を「フォーマット化」することが可能かどうか疑問に思います。たとえば、出力が次のような場合:
Playing Pink_Floyd-Wish_You_Were_Here.mp3 # I get this at the beginning
Playing Pearl_Jam-Once.mp3 # I get this after I change media inside mplayer
それから私は次のようになります:
Mplayer: Playing Pink_Floyd-Wish_You_Were_Here.mp3
Mplayer: Playing Pearl_Jam-Once.mp3
そのためにawkを使用することにしました。
mplayer *.* 2>/dev/null | grep Playing | awk '{print "Mplayer: "$1}'
しかし、この場合は何も起こりません。
私の質問はmplayerの問題を解決するのではなく、bashのパイプのより深い理解を得ることです。
たとえば、次のような場合:
echo a_song.mp3 | awk '{print "Mplayer: "$1}'
欲しいものを手に入れる
Mplayer: a_song.mp3
最初のコマンドが機能しないのはなぜですか?
バックグラウンドでこれらのプロセスを複数実行するにはどうすればよいですか?
答え1
たくさんgrep標準出力が端末の場合、実装はラインバッファリングを使用します。標準出力が端末の場合は通常対話型セッションなので、できるだけ早くデータを取得しようとします。したがって、grep
改行文字が表示されるとすぐにデータが標準出力に書き込まれます。
標準出力が端末でない場合(通常は非対話型セッションを意味する)、grep
ブロックバッファが使用されます。これはgrep
、改行文字が表示されたときに標準出力がすぐに書き込まれないことを意味します。grep
標準出力に書き込む前に、大量のデータ(Linuxでは4096バイト)を収集します。
いくつかのgrep
バージョン、例:GNU grepまたはBSD grep持つ--ラインバッファリングオプション。grep
改行文字が表示されたら、常に標準出力に書き込みます。したがって、あなたの例は次のとおりです。
mplayer *.* 2>/dev/null | grep --line-buffered Playing | awk '{print "Mplayer: "$1}'
grep
あなたのバージョンがそうでない場合は、--line-buffer
以下を使用してすべての操作を実行できますawk
。
mplayer *.* 2>/dev/null | awk '/Playing/{print "Mplayer: "$1}'
GNU coreutilsにはツールがあります標準バッファコマンドを修正するためのバッファです。以下を使用して、いつでも標準出力にラインバッファを強制的に適用できます。
stdbuf -oL command
しかもバッファリング解除出力バッファリングを無効にするコマンドのみが適用されます。
追加読書