Код выдаёт ложный успешный ping
Странная проблема: Код, который дважды проверяет пинг, после чего перезагружает компьютер работает только если изначально был интернет или появился в процессе но потом упал. Если при включении нет интернета то он считает пинг успешным. (Также код добавляет себя в автозагрузку, для удобной перезагрузки сервера)
import time
import datetime
import platform
import os
import subprocess
import getpass
import sys
USER_NAME = getpass.getuser()
ping_problem = 0
def add_to_startup():
file_path = get_full_script_name() # Путь к файлу скрипту
bat_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' % USER_NAME
with open(bat_path + '\\' + "ReloadForServer.bat", "w+") as bat_file:
bat_file.write(r'start "" "%s"' % file_path)
add_to_startup()
def ping(host):
parameter = '-n' if platform.system().lower() == 'windows' else '-c'
command = ['ping', parameter, '1', host]
return subprocess.run(command, stdout=subprocess.PIPE).returncode == 0
while ping_problem != 2:
host = "google.com"
ping(host)
if ping(host):
print("Ping is successful :)")
ping_problem = 0
time.sleep(120)
else:
print(":(")
current_time = datetime.datetime.now().time()
print(current_time, 'Ping has been failed')
ping_problem += 1
time.sleep(120)
print('Ошибка! Лимит попыток восстановления соединения был исчерпан'
'Начинаю перезагрузку системы')
os.system('shutdown /r /t 0')
p.s всё это дело на Windows 10 P.p.s Иные предложения по улучшению кода приветствуются, я новичок
Ответы (1 шт):
Если командная строка на английском, то оно не сработает, нужно менять параметры для отсеивания (для мультифункциональности можно переделать, используя библиотеку icmplib
Код вылавливает слова с информацией об ошибке и отправляет False, если есть.
Это основная часть кода:
def ping():
try:
# Выполнение пинга
parameter = subprocess.run( # Получение результата
["ping", "-n", config["Main_Data"]["files_send"], config["Main_Data"]["host"]],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
) # не рекомендую ставить автоматическую декодировку через text = True
output = parameter.stdout.decode('866') # не на Windows может понадобиться другой номер
print(output)
if "Общий сбой." in output \
or "Превышен интервал ожидания для запроса." in output \
or "Заданный узел недоступен." in output: # Проверка на наличие сообщений об ошибках
return False
return True
except Exception as error: # если всё полностью поломалось
print(f"Ошибка при выполнении ping: {error}")
return False
Также был изменён код для батника, если надо:
def get_full_script_name(): # получаем путь файла + имя файла с расширением
route_path = Path(sys.argv[0])
return route_path.resolve()
def add_to_startup():
file_path = get_full_script_name() # Путь к файлу скрипту
bat_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' % USER_NAME
with open(bat_path + '\\' + "ReloadForServer.bat", "w+") as bat_file:
bat_file.write(r'start "" "%s"' % file_path)
Для пластичности программы был добавлен ini
-файл:
# settings.ini
[Main_Data]
timesup = 60
first_ping = 20
host = 8.8.8.8
files_send = 4
errors_in_a_row = 2
timer_is_visible = True
Полный код программы на данный момент:
import os
import time
from datetime import datetime
import subprocess
import getpass
import sys
from pathlib import Path
import configparser
USER_NAME = getpass.getuser() # парсим имя пользователя
config = configparser.ConfigParser() # парсим инишник
config.read("settings.ini") # данные в ini файле для гибкости программы
def timer(first): # ожидание между пингами
timers_time = 0
target_time = int(config["Main_Data"]["first_ping"]) if first else int(config["Main_Data"]["timesup"])
while timers_time < target_time:
timers_time += 1
time.sleep(1)
if config["Main_Data"]["timer_is_visible"] == 'True': # опциональный отсчёт
print(timers_time)
print('Ping...')
def get_script_name(): # получаем имя файла с расширением
script_path = Path(sys.argv[0])
return script_path.name
def get_full_script_name(): # получаем путь файла + имя файла с расширением
route_path = Path(sys.argv[0])
return route_path.resolve()
def add_to_startup():
file_path = get_full_script_name() # Путь к файлу скрипту
bat_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' % USER_NAME
with open(bat_path + '\\' + "ReloadForServer.bat", "w+") as bat_file:
bat_file.write(r'start "" "%s"' % file_path)
add_to_startup()
def ping():
try:
# Выполнение пинга
parameter = subprocess.run( # Получение результата
["ping", "-n", config["Main_Data"]["files_send"], config["Main_Data"]["host"]],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
) # не рекомендую ставить автоматическую декодировку через text = True
output = parameter.stdout.decode('866') # не на Windows может понадобиться другой номер
print(output)
if "Общий сбой." in output \
or "Превышен интервал ожидания для запроса." in output \
or "Заданный узел недоступен." in output: # Проверка на наличие сообщений об ошибках
return False
return True
except Exception as error: # если всё полностью поломалось
print(f"Ошибка при выполнении ping: {error}")
return False
# выводим информацию о конфигурациях
print(get_script_name(), 'запущен')
print('Ping\'s host', config["Main_Data"]["host"])
print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
print('Частота ожидания между каждым пингом на', config["Main_Data"]
["host"], '-', config["Main_Data"]["timesup"], 'секунд')
print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
print('Первичный пинг', config["Main_Data"]["first_ping"], 'секунд')
timer(True)
# Проверка наличия интернета сразу при запуске, чтобы не тратить время
if not ping():
print("Ошибка! Интернет недоступен при запуске")
print('Начинаю перезагрузку системы')
os.system('shutdown /r /t 0')
print("Первичный пинг успешен :)")
ping_problem = 0
while ping_problem < int(config["Main_Data"]["errors_in_a_row"]): # общее выполнение программы
timer(False)
if ping():
print("Пинг успешен :)")
ping_problem = 0
else:
print(":(")
print('Ошибка пинга')
ping_problem += 1
now = datetime.now()
time_info = now.strftime("%d/%m/%Y %H:%M:%S") # настройка локального времени
print(time_info)
print('Ошибка! Лимит попыток восстановления соединения был исчерпан. Начинаю перезагрузку системы')
os.system('shutdown /r /t 0')
P.S. За информацию спасибо @mrgervant. Я позже, возможно, прикреплю код через icmplib.