我正在努力解决这个问题。我有这条线:
mplayer *.* 2>/dev/null | grep Playing
Run Code Online (Sandbox Code Playgroud)
刚刚启动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
Run Code Online (Sandbox Code Playgroud)
那么我会有类似的东西:
Mplayer: Playing Pink_Floyd-Wish_You_Were_Here.mp3
Mplayer: Playing Pearl_Jam-Once.mp3
Run Code Online (Sandbox Code Playgroud)
为此,我决定使用 awk:
mplayer *.* 2>/dev/null | grep Playing | awk '{print "Mplayer: "$1}'
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,什么也没有发生;我没有输出!!!
我的问题不是为了解决mplayer的问题,而是为了更深入地了解bash中的管道。
例如,如果我使用以下内容:
echo a_song.mp3 | awk '{print "Mplayer: "$1}'
Run Code Online (Sandbox Code Playgroud)
我得到我想要的
Mplayer: a_song.mp3
Run Code Online (Sandbox Code Playgroud)
为什么第一个命令不起作用?
如果我想在后台运行多个这样的进程,我必须做什么?
当标准输出为终端时,许多grep实现将使用行缓冲。当标准输出是终端时,它通常是一个交互式会话,您希望尽快获取数据。因此grep
,一旦看到换行符,就会将数据写入标准输出。
当标准输出不是终端(通常意味着非交互式会话)时,grep
将使用块缓冲区代替。这意味着grep
在看到换行符时不会立即写入标准输出。grep
在写入标准输出之前收集数据量(Linux 中为 4096 字节)。
某些grep
版本,如GNU grep或BSD grep有--line-buffered选项。grep
当看到换行符时,它总是写入标准输出。所以你的例子变成:
mplayer *.* 2>/dev/null | grep --line-buffered Playing | awk '{print "Mplayer: "$1}'
Run Code Online (Sandbox Code Playgroud)
如果您的grep
版本没有--line-buffer
,您可以使用awk
:
mplayer *.* 2>/dev/null | awk '/Playing/{print "Mplayer: "$1}'
Run Code Online (Sandbox Code Playgroud)
GNU coreutils 有一个工具stdbuf用于修改命令的缓冲。您始终可以通过以下方式强制标准输出中的行缓冲区:
stdbuf -oL command
Run Code Online (Sandbox Code Playgroud)
还有unbuffer命令仅禁用输出缓冲。
进一步阅读
归档时间: |
|
查看次数: |
5992 次 |
最近记录: |