我可以收到通知并处理系统事件吗(尤其好奇 wifi 关闭的情况)

我可以收到通知并处理系统事件吗(尤其好奇 wifi 关闭的情况)

自从 ubuntu 14.04 LTS 以来,我一直遇到这个问题,我的无线连接“混乱” - 更具体地说,我有时会失去连接。

我目前正在通过断开连接然后重新连接来解决这个问题。我可以通过点击右上角的统一栏图标,或者通过发出rfkill block wifi命令来rfkill unblock wifi解决这个问题

我还没有找到读取问题的解决方案,但我有这样的想法,如果我可以使用在断开连接时触发的脚本以编程方式处理这种情况,那就没问题了。

我也不想创建一个不断轮询 wifi 状态的脚本,我想针对这一特定事件,并在收到通知后采取行动。

这可能吗?

答案1

首先:

您期望的答案是什么你实际上称之为:我也不想创建一个不断轮询的脚本。Inotify 还用于持续循环以“监听”当前状态的变化。换句话说:如果没有某种循环,您认为存在的其他选项就不存在。

我还认为你对循环的描述太过沉重。在每个系统上,在每个应用程序中,都有大量循环处于活动状态以等待触发。它应该不会对你的资源产生明显的影响。

这种“解剖学”针对事件采取行动机制基本上是:

在一段时间循环中:

check the current status;
if a is True:
    take action A
if a is False:
    do nothing
wait a few seconds

在 Bash 脚本中

整合脚本(检查您的连接)在 while 循环中(进行一些小改动)应该执行您描述的操作:重新建立您的连接并发送通知。

#!/bin/bash

while :
do
  wget -q --tries=10 --timeout=20 --spider http://google.com
  if [[ $? -eq 0 ]]; then
          :
  else
          rfkill block wifi
          rfkill unblock wifi
          notify-send "connection re-established"
  fi
  sleep 4
done

在 Python 脚本中

函数check()返回真的或者错误的。 如果真的(连接已建立),则不会发生任何事情。如果错误的,你的rfkill block wifi/rfkill ublock wifi被执行。

#!/usr/bin/env python3

import socket
import time
import subprocess

def check():
    try:
        host = socket.gethostbyname("www.google.com")
        s = socket.create_connection((host, 80), 2)
        return True
    except Exception:
        return False

while True:
    if check() == True:
        pass
    else:
        subprocess.call(["/bin/bash", "-c", "rfkill", "block", "wifi"])
        subprocess.call(["/bin/bash", "-c", "rfkill", "unblock", "wifi"])
        subprocess.Popen(["/bin/bash", "-c", "notify-send 'conncection re-established'"])
    time.sleep(4)

答案2

我的脚本用于处理免费 WIFI 登录/注销和无线连接重新连接和修复。

它连接到免费的 wifi,登录,获取剩余连接时间并等待时间到并检查 wifi 和登录状态和互联网连接,注销并重复。

要向桌面环境发送通知,请使用

notify-send "YOUR MESSAGE HERE"

函数中处理 Wifi 连接修复重新连接()

#!/bin/bash
WIFI_DEVICE="wlp3s2"
USER_PC="T-00%3AC0%3AA8%3AC7%3AF0%3AF1"
USER_USB="T-00%3AE0%3A4C%3A84%3AD2%3A5C"
USER_NAME="$USER_PC"
LOGIN_URL="http://starse.hotspot/login?username="
LOGOUT_URL="http://starse.hotspot/logout"
STATUS_URL="http://starse.hotspot/status"
WIFI_NETWORK="starse.WiFiPoint"
WIFI_PROFILE_FILE_SEARCH="starse"
PORT=5555
LOGIN_RETRY=5
REPEAT_HOURS=10000
SECONDS_LEFT="0"
ONE_MINUTE=15
MINUTES=0
START=0
END=0
ONE=1
ZERO=0

function CleanConnections()
{
    MYDIR=$(pwd)
    #remove all connections from network manager
    cd /etc/NetworkManager/system-connections/ &> /dev/null
    rm "$WIFI_PROFILE_FILE_SEARCH.*" &> /dev/null
    cd $MYDIR &> /dev/null
}

function ReConnect()
{
    # check if WIFI_DEVICE is connected to WIFI_NETWORK
    WIFI_OK=$(iwconfig $WIFI_DEVICE | grep -c $WIFI_NETWORK)

    # while not connected, try to repair connection
    while [ $WIFI_OK = "0" ]
    do
        # check if wifi radio is on / turn it on
        RADIO=$(nmcli radio wifi)
        sleep 1
        if [ "$RADIO" = "onemogočeno" ]
        then
            nmcli radio wifi on
            echo "$(date), WIFI RADIO OMOGOČEN!"
        fi
        sleep 1
        # check if WIFI_DEVICE is connected to WIFI_NETWORK again
        WIFI_OK=$(iwconfig $WIFI_DEVICE | grep -c $WIFI_NETWORK)
        if [ $WIFI_OK = "0" ]
        then
            # if not connected, connect to WIFI_NETWORK
            echo "$(date), POVEZAVA WIFI PREKINJENA!"
            nmcli d wifi connect "$WIFI_NETWORK" &> /dev/null
            sleep 1

            # check if WIFI_DEVICE is connected to WIFI_NETWORK again
            WIFI_OK=$(iwconfig $WIFI_DEVICE | grep -c $WIFI_NETWORK)
            sleep 1

            # if connection is still not established, restart network-manager and check connection
            if [ $WIFI_OK = "0" ] 
            then
                service network-manager restart
                sleep 2
                WIFI_OK=$(iwconfig $WIFI_DEVICE | grep -c $WIFI_NETWORK)
                echo "$(date), NETWORK MANAGER PONOVNO ZAGNAN!" 
            else
                echo "$(date), POVEZAVA WIFI VZPOSTAVLJENA!"
                sleep 2         
            fi
        fi
    done
}


function Login()
{
    RETRY_COUNT=0
    LOGIN_OK=0
    # while not logged in
    while [ $LOGIN_OK = "0" ]
    do
        # try to login
        LOGIN_OK=$(curl -s -m 2 "$LOGIN_URL$USER_NAME" | grep -c "You are logged in")
        if [ $LOGIN_OK = "1" ] 
        then
            echo "$(date), PRIJAVA USPEŠNA."
            break
        else
            # if could not login, try for RETRY_COUN
            echo "$(date), PRIJAVA NEUSPEŠNA! Ponavljam $RETRY_COUNT od $LOGIN_RETRY"
            RETRY_COUNT=$((RETRY_COUNT+1))
            sleep 1
        fi

        # if RETRY_COUNT expired then ReConnect and continue
        if [ $RETRY_COUNT -gt $LOGIN_RETRY ]
        then
            ReConnect
            RETRY_COUNT=0
            continue
        fi
    done
}


function GetSecondsLeft()
{
    STATUS_PAGE=$(wget -T 2 -q -O - "$@" "$STATUS_URL") 
    sleep 10
    MIN1=$(echo $STATUS_PAGE | grep -o '[0-9| ][0-9]m' | tail -1 | tr -d 'm' | tr -d ' ')
    sleep 1
    SEC1=$((MIN1*60))
    echo "$(date), ČAS PRIDOBLJEN. NA VOLJO: $((SEC1))s"
    eval "$1"="$SEC1"
}

#ReConnect

LOGIN_NR=1
while  [ "$LOGIN_NR" -lt "$REPEAT_HOURS" ]
do


    # try to login first
    Login

    #set counters
    START=$(date +%s)

    # get time left from status page
    GetSecondsLeft SECONDS_LEFT

    # clean wifi profiles dir
    CleanConnections

    # get first ELPASED_SEC
    END=$(date +%s)
    ELPASED_SEC=$((END-START))

    # count till next login
    while [ $ELPASED_SEC -lt $SECONDS_LEFT ]
    do  
        # display info
        echo "$(date), LOGIN: $LOGIN_NR, PRETEKLO: $((ELPASED_SEC))s,  NA VOLJO ŠE: $((SECONDS_LEFT-ELPASED_SEC))s"


        # wait ONE_MINUTE and periodicaly check for wifi and internet connection every two/three seconds    
        ELPASED_MINUTE_SEC=0
        while [ $ELPASED_MINUTE_SEC -lt $ONE_MINUTE ]
        do
            # start timer
            S=$(date +%s)

            # check for wifi connection
            WIFI_OK=$(iwconfig $WIFI_DEVICE | grep -c $WIFI_NETWORK)
            if [ $WIFI_OK = "1" ]
            then
                #  if wifi connection OK, check for internet connection
                PING="0"
                PING=$(ping -c 1 -w 2000 -s 1 www.google.si | grep -c "9 bytes")
                sleep 2
                if [ "$PING" = "0" ]
                then
                    echo "$(date), INTERNETNA POVEZAVA PREKINJENA! Vzpostavljam ..."
                    # if no internet connection then Login()
                    Login
                    # on reconnect caculate SECONDS_LEFT and reset ELPASED_SEC
                    GetSecondsLeft SECONDS_LEFT
                    ELPASED_SEC=0
                else
                    sleep 1
                fi
            else
                # if wifi connection is lost ReConnect()
                ReConnect   
            fi                  

            # check if whole time is up and break
            END=$(date +%s)
            ELPASED_SEC=$((END-START))
            if [ $SECONDS_LEFT -le $ELPASED_SEC ]
            then
                break
            fi

            # add used seconds to ELPASED MINUTE            
            E=$(date +%s)
            ELPASED_MINUTE_SEC=$((ELPASED_MINUTE_SEC+(E-S)))            
        done    
        END=$(date +%s)
        ELPASED_SEC=$((END-START))
    done


    # TIME IS UP
    # logout and increase LOGIN_NR
    curl -s -m 2 "$LOGOUT_URL" &> /dev/null
    LOGIN_NR=$((LOGIN_NR+1))

done

相关内容