kurokirasama
kurokirasama

Reputation: 777

bash for loop doesn't loop as intented

I took this script somewhere over the internet, that automatically changes to a better wifi network. It was working fine till a few weeks ago. I modified it a little to try to find out where the problem was, and it seems that the for loop isn't iterating properly through the available wifi networks list. Any ideas will be appreciated. Here's the script:

#!/bin/bash
threshold=10

# Lets do a scan first
sudo /usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi rescan

# And get the list of known networks
known_networks_info=$(/usr/bin/nmcli -t -f name connection show | sed -e 's/^Auto //g')
echo "knowm networks"
echo $known_networks_info

# What's the current network, yet?
current_network_name=$(/usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi list | grep ':\*' | cut -d ':' -f1)
current_network_strength=$(/usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi list | grep ':\*' | cut -d ':' -f2)
echo "current net $current_network_name, strength $current_network_strength"

# Now see if we have a better network to switch to. Networks are sorted by signal strength so there's no need to check them all if the first signal's strength is not higher than current network's strength + threshold.
network_list=$(/usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi list | grep -v $current_network_name | sort -nr -k2 -t':')
echo "network list"
echo $network_list
typeset -p network_list
for network in "$network_list" ; do
        network_name=$(echo $network | cut -d ':' -f1)
        network_strength=$(echo $network | cut -d ':' -f2)
        echo "net $network_name, strength $network_strength"
        # if [[ "$network_name" == "" ]]; then continue ; fi # MESH hotspots may appear with an non existent SSID so we skip them 
        # if [[ "$known_networks_info" == *"$network_name"* ]]; then
        #         if [ $network_strength -ge $(($current_network_strength + $threshold)) ]; then
        #                 notification="Switching to network $network_name that has a better signal ($network_strength>$(($current_network_strength + $threshold)))"
        #                 echo $notification
        #                 notify-send "$notification"
        #                 sudo /usr/bin/nmcli device wifi connect $network_name
        #         else
        #                 notification="Network $network_name is well known but its signal's strength is not worth switching"
        #                 echo $notification
        #                 notify-send "$notification"
        #                 exit 0
        #         fi
        # fi
done

This is an output of the script above:

knowm networks
Amara Amara_EXT Kira Kira_5g Kira_5G Kira_5GEXT Kira_EXT RedmiGao RedmiKira VTR-2201458 VTR-2201458_EXT VTR-2201458_EXT2 VTR-9329907 VTR-9329907_EXT Wired connection 1
current net Amara, strength 82
network list
HUAWEI-B2368-472705:80:270 Mbit/s: HUAWEI-B2368-5G-472706:70:270 Mbit/s: Mi 10T Pro:62:130 Mbit/s: Irene.:50:130 Mbit/s: C L E Y A 5G:32:540 Mbit/s: C L E Y A:32:540 Mbit/s: Irene.:25:540 Mbit/s: Irene. 5G:22:540 Mbit/s: Mateo:15:130 Mbit/s:
declare -- network_list="HUAWEI-B2368-472705:80:270 Mbit/s: 
HUAWEI-B2368-5G-472706:70:270 Mbit/s: 
Mi 10T Pro:62:130 Mbit/s: 
Irene.:50:130 Mbit/s: 
C L E Y A 5G:32:540 Mbit/s: 
C L E Y A:32:540 Mbit/s: 
Irene.:25:540 Mbit/s: 
Irene. 5G:22:540 Mbit/s: 
Mateo:15:130 Mbit/s: "
net HUAWEI-B2368-472705, strength 80

Upvotes: 0

Views: 60

Answers (1)

kurokirasama
kurokirasama

Reputation: 777

Thanks to @markp-fuso and @GordonDavisson for the comments, here is a fixed script:

#!/bin/bash
threshold=10

# Lets do a scan first
sudo /usr/bin/nmcli -t -f ssid,signal,in-use dev wifi rescan

# And get the list of known networks
known_networks_info=$(/usr/bin/nmcli -t -f name connection show | sed -e 's/^Auto //g')
echo "knowm networks"
echo $known_networks_info

# What's the current network?
current_network_name=$(/usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi list | grep ':\*' | cut -d ':' -f1)
current_network_strength=$(/usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi list | grep ':\*' | cut -d ':' -f2)
echo "current net $current_network_name, strength $current_network_strength"

# Now see if we have a better network to switch to. Networks are sorted by signal strength so there's no need to check them all if the first signal's strength is not higher than current network's strength + threshold.
network_list=$(/usr/bin/nmcli -t -f ssid,signal,rate,in-use dev wifi list | grep -wv $current_network_name | sort -nr -k2 -t':')
echo "network list"
echo $network_list
echo "checking each network"
while IFS=: read -r network_name network_strength network_rate; do 
        echo "net $network_name, strength $network_strength"
        if [[ "$network_name" == "" ]]; then continue ; fi # MESH hotspots may appear with an non existent SSID so we skip them 
        if [[ "$known_networks_info" == *"$network_name"* ]]; then
                if [ $network_strength -ge $(($current_network_strength + $threshold)) ]; then
                        notification="Switching to network $network_name that has a better signal ($network_strength>$(($current_network_strength + $threshold)))"
                        echo $notification
                        notify-send "$notification"
                        sudo /usr/bin/nmcli device wifi connect $network_name
                else
                        notification="Network $network_name is well known but its signal's strength is not worth switching"
                        echo $notification
                        notify-send "$notification"
                fi
                exit 0
        fi
done <<< "${network_list}"

Upvotes: 1

Related Questions