我编写了一个 bash 脚本以在导航栏自定义模块。我试图将其用作无限循环,但自定义模块永远不会更新。
我的脚本 ( volume.sh
) 从终端看来没问题。 (以供参考:
#!/bin/bash
# Loop forever
while : ; do
# Mangle the output of amixer into json
amixer get Master | grep 'Mono:' |\
sed -nre 's/.*\[off\].*/\{"text": " M x ", "class": "muted", "percentage": 0\}/p; s/.*\[(.*)%\].*/\{"text": "\1% ", "class": "unmuted", "percentage": \1\}/p'
# Wait until the next alsa event
/usr/sbin/alsactl monitor | grep -m 0 .
# Exit if alsactl monitor was interrupted
if (( ${PIPESTATUS[0]} != 141 )); then
break;
fi
done
)我的 waybar 配置是
"custom/alsa": {
"exec": "~/.config/waybar/volume.sh",
"return-type": "json",
"on-click": "amixer set Master toggle",
"on-scroll-up": "amixer set Master 5+",
"on-scroll-down": "amixer set Master 5-",
"tooltip": false
}
启动 waybar 时,自定义模块会正确显示,但它永远不会更新。
./volume.sh
每次更改音量或静音/取消静音时,终端都会输出一行,这就是我想要的。终端的输出显示正确:
$ ./volume.sh
{"text": "43% ", "class": "unmuted", "percentage": 43}
{"text": "50% ", "class": "unmuted", "percentage": 50}
{"text": " M x ", "class": "muted", "percentage": 0}
{"text": "57% ", "class": "unmuted", "percentage": 57}
(这将是在 4 个事件之后),我相信这是 waybar 的合理输出。因此,我预计问题在于输出应采用什么形式(这可能特定于 waybar)或模块的配置方式。
如果我删除循环volume.sh
并将间隔放入我的自定义模块配置中,那么模块就会正确更新,但我希望避免轮询。
为什么我的自定义 Waybar 模块没有更新?谢谢!
附录
对于利息,输出amixer get Master
为
Simple mixer control 'Master',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback 0 - 74
Mono: Playback 49 [66%] [-25.00dB] [on]
但是,脚本的文本输出似乎是正确的,因此该amixer
行似乎不是问题。
答案1
我有一个可行的解决方案,因此可以猜测原因。
工作解决方案是
#!/bin/bash
set -e
createJson(){
amixer get Master |
grep 'Mono:' |
sed -nre 's/.*\[(.*)%\].*\[off\].*/\{"text": "\1% x", "class": "muted", "percentage": \1\}/p'\
-e 's/.*\[(.*)%\].*/\{"text": "\1% ", "class": "unmuted", "percentage": \1\}/p'
}
createJson
while read line; do
createJson
done < <( /usr/sbin/alsactl monitor )
这会一次读取一行 的输出alsactl
,每次都会抽取相关信息amixer
(并忽略 中的行alsactl
)。我还调整了 sed 行,以便您在静音时仍然可以看到音量,但这只是装饰性的。
我希望这能起作用,因为包含 输出的管道alsactl
永远不会损坏。在原始脚本中,grep
每行后都会终止,从而破坏管道。不知何故,这分离了alsactl
(发送一个SIGCHLD
出现在 Waybar 的调试输出中的文件)并破坏了脚本(但仅限于非交互模式)。在较新的脚本中,alsactl
只是继续通过管道传输到 while 循环,直到我们退出。