2

I'm trying to write a small bash script that will take values from my mouse's horizontal scroll wheel to change my system's volume.

Using this guide, I've come up with the following command to successfully read the values:

evemu-record /dev/input/event16 | grep --line-buffered "0002 0006" | awk '{ print $10 }'

This displays the values to the terminal as they come in, but I want to be able to use conditional logic on each value to determine whether to increase or decrease the volume (and by how much).

My previous attempt at this was using a while loop (and suggestions from some other posts that seemed related to my problem), which was able to capture the output, but using grep slowed down everything too much for it to be usable:

stdbuf -oL evemu-record /dev/input/event16 |
    while IFS= read -r line; do
        g=$(echo "$line" | grep "0002 0006") # falls behind substantially on mouse movement
        # g="$line" # does not fall behind
        if [ -n "$g" ]; then
            echo "$g"
        fi
    done

This does do what I want, but when moving the mouse, data comes in much more frequently, and it seems like this implementation is too inefficient to keep up. Substituting the commented g assignment line keeps the output synced with the latest output from evemu-record.

I have tried piping the first command above into the while loop, but it doesn't seem to work.

4
  • 1
    How about putting the while/read loop behind your filtering awk pre-processor? E.g. evemu-record … | awk '/0002 0006/ { print $10 }' | while read -r col10; do … something … with … "$col10" …; done Commented Nov 7 at 17:35
  • 3
    You don't need grep, just do if [[ $line = *0002\ 0006* ]]; then Commented Nov 7 at 19:21
  • you mention wanting to perform conditional logic to adjust the volume and by how much, but nothing in the code provided shows these steps; while I understand you're looking for a 'fast way' to parse the 0002 0006 lines, adding follow-on conditional logic and volume adjustments could further delay processing; if you want some ideas on how to speed up the entire process then you should also include your conditional logic and sample system calls that adjust the volume; having said that ... you should also provide a few sample 0002 0006 lines with the desired matching system calls Commented Nov 7 at 22:37
  • ... the point being that spawning a separate set of grep + awk + conditional logic code will likely be expensive ... while it may be possible to replace all 3 bits with a single piece of 'conditional logic' ... but we would need to see a complete set of code to know for sure Commented Nov 7 at 22:42

2 Answers 2

2

This ...

        g=$(echo "$line" | grep "0002 0006") # falls behind substantially on mouse movement

... launches separate echo and grep processes for every single mouse event. Creating new processes is comparatively expensive. That echo could be replaced by a here string for some improvement (g=$(grep "0002 0006" <<<"$line")), but for what your example code is doing, it would be much better to just use a single grep process to filter the events before they even reach the while loop. For example:

stdbuf -oL evemu-record /dev/input/event16 |
    grep --line-buffered "0002 0006" |
    while IFS= read -r line; do
        printf '%s\n' "$line"
    done

That is, of course, pretty close to your grep + awk approach (in which awk alone could have done the job of both), but with the shell processing the filtered lines instead of awk doing so.

Sign up to request clarification or add additional context in comments.

Comments

0

You should try to use this faster version:

evemu-record /dev/input/event16 | awk '/0002 0006/ {v=$10; if(v>0) system("pactl set-sink-volume @DEFAULT_SINK@ +2%"); else if(v<0) system("pactl set-sink-volume @DEFAULT_SINK@ -2%")}'

This would lead to no buffering or grep delay and instantly changes volume when the scroll wheel moves.

1 Comment

That's spawning a shell to awk to call system() to spawn a subshell to call pactlt for every line that matches 0002 0006 and has non-zero $10 which is going to be slower than just calling pactl from the top level shell as in the accepted answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.