Shell

逐行配管

  • September 30, 2022

我有一個腳本可以“監聽”amixer事件(音量變化和靜音),將音量和靜音狀態傳送到xob. 它工作得很好,但是(ab)使用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

謝謝!

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

引用自:https://unix.stackexchange.com/questions/719251