イベント(音量変更とミュート)を「受信」amixer
し、音量とミュート状態をxob
。うまくいきますが(誤用が)stdbuf -oL <command>
間違っているようで、私が望むことを実行する他の方法があるかどうか疑問に思います。私はスクリプト行のすべてのコマンドをバッファリングする方法を探していると思います。
このスクリプトは移植性が高くはありませんが、移植可能な回答に感謝します。
私はシェルスクリプトが初めてなので、このスクリプトへの追加の改善に特に感謝します!
スクリプトは次のとおりです。
#!/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
。出力を1行ずつバッファリングするように指示します。
tail -n+2
また、シェルで簡単に実行してフィルタリングできるため、次のようになります。
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