이벤트(볼륨 변경 및 음소거)를 "수신" 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
. 출력을 한 줄씩 버퍼링하도록 지시합니다.
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