Want to respond to the output of a script, but limit responses to every second; POSIX

104 views Asked by At

I am trying to write a script (for dash, so I want it posix compliant). What I want the script to do is print me the name of my currently connected SSID (in json format).

This info is to be processed by my status bar (polybar, waybar and i3status). I would like to print this information as few times as possible, and immediately on network change.

I have found the command ip monitor useful; since it prints lines when there is a network change. However, it is very verbose. (I have similar scripts set up, and for pulseaudio, I use grep to filter unwanted lines for example) I do not neccessarily want to filter the lines; since filtering doesn't really reduce the number of lines my script prints.

I managed to write a script in bash, but the redirection is not POSIX compliant, so I can't switch to dash.

This is the code I currently have, that depends on bash's redirection

#!/bin/bash

_int="wifi"

get_text () {
    _ssid="$(iwctl station "${_int}" get-networks | awk '/>/ {print $2} ' 2>/dev/null)"
    if [ -z "${_ssid}" ] ; then
        echo '{ "format": "", "mute": true, "prefix": ""}'
    else
        echo "{ \"format\":\"${_ssid}\", \"mute\": false, \"prefix\":\" \" }"
    fi
}

while : ; do
    get_text
    _time="$(date +%s)"
    while read line; do
        if [ "$_time" != "$(date +%s)" ] ; then
            break
        fi
    done < <(ip monitor)
done

If I do this, it is POSIX compliant, but the output is printed ~20 times (the number is not consistent)

#!/bin/dash

_int="wifi"

get_text () {
    _ssid="$(iwctl station "${_int}" get-networks | awk '/>/ {print $2} ' 2>/dev/null)"
    if [ -z "${_ssid}" ] ; then
        echo '{ "format": "", "mute": true, "prefix": ""}'
    else
        echo "{ \"format\":\"${_ssid}\", \"mute\": false, \"prefix\":\" \" }"
    fi
}

ip monitor | while read line; do
    if echo $line | grep -q 'wifi' ; then
        get_text
    fi

done

EDIT: I found a solution, as I was typing my question. My loop is now the following; which checks if the time of the outputs were in different seconds.

get_text
ip monitor | while read line; do
    if echo $line | grep -q "${_int}" && [ "$_time" != "$(date +%s)" ]; then
        get_text
        _time="$(date +%s)"
    fi
done

Do note that ip monitor does print output that does not indicate network connection change. But I can handle couple prints every minute. I am afraid of very closed interspaced outputs; since those cause the infobars to be redrawn. I also have a python script that parses the arguments, so many outputs in a short time multiplies my overhead.

0

There are 0 answers