Могу ли я получать уведомления и обрабатывать системные события (особенно любопытно, что Wi-Fi отключен)
Начиная с Ubuntu 14.04 LTS у меня возникла проблема, связанная с тем, что мое беспроводное соединение "испортилось" - точнее, иногда я теряю соединение.
В настоящее время я решаю эту проблему, отключив и снова подключившись. Это работает либо путем нажатия на верхнюю правую иконку единства, либо путем выдачи rfkill block wifi
с последующим rfkill unblock wifi
команда
Я еще не нашел решения проблемы чтения, но мне пришла в голову мысль, что если я смогу программно обработать эту ситуацию с помощью скрипта, который срабатывает при отключении, то у меня все будет хорошо.
Я также не хочу создавать сценарий, который опрашивает константы для определения статуса Wi-Fi, я бы хотел прослушать это конкретное событие и действовать как уведомление.
Это как-то возможно?
2 ответа
Прежде всего:
То, что вы описываете как желаемый ответ, это то, что вы на самом деле называете: я также не хочу создавать скрипт, который опрашивает констант. Inotify также используется в константном цикле для "прослушивания" изменений в текущем состоянии. Другими словами: другой вариант, который вы предполагаете существовать, не существует без какого-либо цикла.
Я также думаю, что ваше изображение петли слишком тяжелое. В каждой системе, в каждом приложении есть множество активных циклов, ожидающих триггеров. Это не должно оказывать заметного влияния на ваши ресурсы.
"Анатомия" такого механизма " действие на событие" в основном:
в цикле while:
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()
возвращает True или False. Если True (соединение установлено), ничего не происходит. Если Ложь, ваш 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)
Мой скрипт для обработки БЕСПЛАТНОГО WIFI входа / выхода из системы и повторного подключения и ремонта БЕСПРОВОДНОГО соединения.
Он подключается к бесплатному Wi-Fi, входит в систему, получает оставшееся время подключения и ждет, пока время истечет, проверяет состояние Wi-Fi и входа в систему и подключение к Интернету, выходит из системы и повторяется.
Для отправки уведомлений на рабочий стол используйте
notify-send "YOUR MESSAGE HERE"
Восстановление Wi-Fi соединения выполняется в функции ReConnect()
#!/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