![逐条管道](https://linux22.com/image/211451/%E9%80%90%E6%9D%A1%E7%AE%A1%E9%81%93.png)
我有一个“监听”amixer
事件(音量变化和静音)的脚本,通过管道将音量和静音状态传递给xob
。它工作得很好,但是(滥用)stdbuf -oL <command>
对我来说看起来是错误的,我想知道是否还有其他方法可以做我想做的事情。我想我正在寻找一种方法来使脚本中的每个命令都进行行缓冲。
尽管这个脚本并不那么便携,但可移植的答案值得赞赏。
我是 shell 脚本编写的新手,因此特别感谢对该脚本的其他改进!
这是脚本:
#!/bin/sh
# Wait for amixer to become available
until [ "$(amixer)" ]; do sleep 0.1; done
get_volume () {
OUT=$(amixer sget Master)
VOLUME=$(echo $OUT | awk -F"[][]" '/Left:/ { print $2 }' | tr -d '%')
STATE=$(echo $OUT | awk -F"[][]" '/Left:/ { print $4 }')
[ "$STATE" = "off" ] && VOLUME="$VOLUME!"
echo $VOLUME
}
stdbuf -oL amixer events \
| stdbuf -oL grep -E "event value: numid=(3|4)" \
| stdbuf -oL tail -n +2 \
| while read REPLY; do get_volume; done \
| xob
谢谢!
答案1
GNU grep
(在具有 的系统上找到amixer
)确实有一个--line-buffered
选项。告诉它按行缓冲其输出。
tail -n+2
您也可以在 shell 中轻松执行和 过滤,因此:
get_volume() {
amixer sget Master |
awk -F'[][]' '/Left:/ {print 0+$2 ($4 == "off" ? "!" : "")}'
}
skip=1
stdbuf -oL amixer events |
while IFS= read -r line; do
case ${line%%,*} in
('event value: numid='[34])
if [ "$skip" -eq 0 ]; then
get_volume
else
skip=$(( skip - 1 ))
fi
esac
done | xob