Иногда возникает необходимость внести изменения в файл hosts в Windows. Вместе с этой потребностью родилась идея создать небольшую утилиту на Python, которая бы упростила процесс редактирования этого файла. В результате появился WindowsHostsManager — инструмент, созданный всего за 30 минут и предназначенный для удобного управления файлом hosts.

Описание программы

WindowsHostsManager — это простая консольная утилита, написанная на Python с использованием стандартных библиотек (os, sys, ctypes и shutil). Она предназначена исключительно для Windows и позволяет добавлять, удалять и просматривать записи в файле hosts, а также создавать резервные копии и восстанавливать файл из них.

Основные команды

  1. add <IP> <hostname> — Добавить запись в файл hosts. Пример: add 127.0.0.1 example.com

  2. remove — Удалить запись по имени хоста. Пример: remove example.com

  3. list — Показать все текущие записи в файле hosts.

  4. backup — Создать резервную копию файла hosts.

  5. restore — Восстановить файл hosts из резервной копии.

  6. clear — Очистить экран терминала.

  7. help — Показать список доступных команд.

  8. exit — Выйти из программы.

Примеры использования

Добавление записи:

Enter command: add 127.0.0.1 example.com
Вывод:
Added: 127.0.0.1 example.com

Удаление записи:

Enter command: remove example.com
Вывод:
Removed entries for: example.com

Просмотр всех записей:

Enter command: list
Вывод:
Current entries in hosts file:
127.0.0.1 localhost
127.0.0.1 example.com

Создание резервной копии:

Enter command: backup
Вывод:
Backup created: C:\Windows\System32\drivers\etc\hosts.back

Восстановление файла:

Enter command: restore
Вывод:
Are you sure you want to restore the hosts file from backup? (yes/no): yes
Hosts file restored from backup: C:\Windows\System32\drivers\etc\hosts.back

Важные замечания

Программа WindowsHostsManager автоматически запускается с правами администратора, поскольку для внесения изменений в файл hosts требуется наличие привилегий. В противном случае, программа перезапустится с запросом прав администратора.

Отличия от аналогов

Так как я сначала делаю, а потом думаю, то после проделанной работы я нашёл аналогичные программы. Первая — это HostsMan, вторая — Hosts Manager. Отличие моей программы от этих двух в том, что они имеют графический интерфейс (GUI), а моя утилита является чисто консольной.

Код программы

Программа написана всего за 30 минут, но уже обладает всеми необходимыми функциями для базового управления файлом hosts.

import os
import sys
import ctypes
import shutil

HOSTS_PATH = r'C:\Windows\System32\drivers\etc\hosts'
BACKUP_PATH = HOSTS_PATH + '.back'

def is_admin():
    try:
        return os.getuid() == 0
    except AttributeError:
        return ctypes.windll.shell32.IsUserAnAdmin() != 0

def read_hosts():
    with open(HOSTS_PATH, 'r') as file:
        return file.readlines()

def write_hosts(lines):
    with open(HOSTS_PATH, 'w') as file:
        file.writelines(lines)

def add_entry(ip, hostname):
    lines = read_hosts()
    entry = f"{ip} {hostname}\n"
    
    if entry not in lines:
        lines.append(entry)
        write_hosts(lines)
        print(f"Added: {entry.strip()}")
    else:
        print(f"Entry already exists: {entry.strip()}")

def remove_entry(hostname):
    lines = read_hosts()
    lines = [line for line in lines if not line.endswith(f"{hostname}\n")]
    write_hosts(lines)
    print(f"Removed entries for: {hostname}")

def list_entries():
    lines = read_hosts()
    if lines:
        print("Current entries in hosts file:")
        for line in lines:
            print(line.strip())
    else:
        print("No entries found in the hosts file.")

def print_help():
    print("Commands:")
    print("  add      - Add an entry (e.g., add <IP> <hostname>)")
    print("  remove   - Remove an entry (e.g., remove <hostname>)")
    print("  list     - List all entries in the hosts file")
    print("  backup   - Create a backup of the hosts file")
    print("  restore  - Restore the hosts file from backup")
    print("  clear    - Clear the terminal screen")
    print("  help     - Show this help message")
    print("  exit     - Exit the application")

def clear_screen():
    os.system('cls' if os.name == 'nt' else 'clear')

def backup_hosts():
    try:
        shutil.copy2(HOSTS_PATH, BACKUP_PATH)
        print(f"Backup created: {BACKUP_PATH}")
    except IOError as e:
        print(f"Failed to create backup: {e}")

def restore_hosts():
    if os.path.exists(BACKUP_PATH):
        confirm = input("Are you sure you want to restore the hosts file from backup? (yes/no): ").strip().lower()
        if confirm == 'yes':
            try:
                shutil.copy2(BACKUP_PATH, HOSTS_PATH)
                print(f"Hosts file restored from backup: {BACKUP_PATH}")
            except IOError as e:
                print(f"Failed to restore hosts file: {e}")
        else:
            print("Restore operation canceled.")
    else:
        print("No backup file found.")

def main():
    while True:
        print("Enter command:", end=' ')
        command = input().strip().lower()

        if command.startswith('add'):
            _, ip, hostname = command.split(maxsplit=2)
            add_entry(ip, hostname)
        elif command.startswith('remove'):
            _, hostname = command.split(maxsplit=1)
            remove_entry(hostname)
        elif command == 'list':
            list_entries()
        elif command == 'backup':
            backup_hosts()
        elif command == 'restore':
            restore_hosts()
        elif command == 'help':
            print_help()
        elif command == 'clear':
            clear_screen()
        elif command == 'exit':
            print("Exiting the application...")
            break
        else:
            print("Invalid command. Type 'help' for a list of commands.")

if __name__ == "__main__":
    if not is_admin():
        print("This script needs to be run with administrator privileges.")
        ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
    else:
        main()

Репозиторий на GitHub

Исходный код утилиты WindowsHostsManager доступен в моём репозитории на GitHub. Вы можете скачать, протестировать и при необходимости изменить код под свои нужды. Буду рад, если оставите свои предложения или улучшения в разделе issues или pull requests.

Эта утилита — отличный пример того, как Python позволяет создавать простые, но эффективные инструменты для решения повседневных задач.

Комментарии (32)


  1. censor2005
    06.09.2024 12:43

    Есть ли какие-то технические ограничения, почему нельзя то же самое запустить на Linux? По идее, отличается только путь к файлу, в Linux это будет как правило /etc/hosts. Тем более, судя по методу clear_screen, такой функционал планировался?


    1. king_tri_ton Автор
      06.09.2024 12:43

      да, думал, как сделать универсальное решение, следите на git


    1. Testman2023
      06.09.2024 12:43
      +1

      В Linux своя простая настройка /etc/hostname и /etc/hosts

      Все через sudo
      cat /etc/hostname (было ub)
      echo ub24 > /etc/hostname
      или
      hostnamectl set-hostname ub24
      cat /etc/hosts
      sed -i 's:^127.0.1.1      ub:127.0.1.1    ub24:' /etc/hosts
      или любым редактором: nano, mcedit, gedit меняем ub на ub24 в /etc/hosts
      Чтобы все сервисы начали использовать новое имя без перезарузки
      hostname `cat /etc/hostname`
      или
      systemctl restart systemd-hostnamed
      На сервере Ubuntu
      systemctl restart systemd-networkd.service
      systemctl status systemd-networkd.service


  1. unreal_undead2
    06.09.2024 12:43
    +1

    entry = f"{ip} {hostname}\n"

    if entry not in lines:

    А если там табы или несколько пробельчиков для выравнивания?

    if not line.endswith(f"{hostname}\n")

    Добавили хосты foo, barfoo, bazbarfoo и после этого удаляем foo...


    1. king_tri_ton Автор
      06.09.2024 12:43

      делал на коленке, не все нюансы учел, исправлю в будущих версиях


  1. aik
    06.09.2024 12:43

    А блокнот уже не годится? :)

    Всё же не так уж часто в хостс лазишь, чтобы целого питона ради этого ставить.

    Думаю, что логичней ыбло бы на poweshell это делать, если уж cli нужно.


    1. unreal_undead2
      06.09.2024 12:43

      Самое сложное в правке hosts - вспомнить, где на винде этот hosts лежит. Но это хоть нагуглить можно, а вот вспомнить как называется скрипт, который последний раз запускал год назад, уже нетривиально )


      1. Grey83
        06.09.2024 12:43

        Самое сложное в правке hosts - вспомнить, где на винде этот hosts лежит.

        Можно в пуске папку закрепить (если он ещё остался и в нём папки можно закреплять).
        Я как раз у себя так сделал.


      1. aik
        06.09.2024 12:43
        +2

        В etc, как у всех. :)

        Другое дело, что etc в винде засунуто в какую-то задницу.


      1. Canep7
        06.09.2024 12:43
        +1

        В BAT-файл под именем edithosts.bat вставить строку:
        start "" "notepad.exe" "%WINDIR%\system32\drivers\etc\hosts"
        И сохранить его в папку доступную по Path, или сделать доступной нужную папку. И все... в командной строке пишем edithosts и ничего помнить не надо. :)


  1. Grey83
    06.09.2024 12:43

    Ну как-то совсем бедно с функционалом. Всё ещё в блокноте (не родном виндовом, правда) удобнее работать с этим файлом, кмк. Да и питон устанавливать не нужно. =)

    add — Добавить запись в файл hosts. Пример: add 127.0.0.1 example.com

    Может лучше поменять местами аргументы и если не введён айпишнег, то скрипт вводил бы дефолтный (127.0.0.1 или 0.0.0.0, как юзверю больше нравится)?

    Эта утилита — отличный пример того, как Python позволяет создавать простые, но эффективные инструменты для решения повседневных задач.

    Лаба по информатике чтоле?
    На счёт эффективности и повседневности я бы поспорил. Далеко не каждый день в этот файл лазаешь, да и не каждый год.


    1. aik
      06.09.2024 12:43

      На счёт эффективности и повседневности я бы поспорил. Далеко не каждый день в этот файл лазаешь, да и не каждый год.

      В курсовых и дипломах надо писать громкие слова. Самый запомнившийся мне диплом начинался что-то на тему "информационная система для нашего деревенского ГАИ - это большой шаг в развитии человечества"..


  1. Kahelman
    06.09.2024 12:43

    А ещё есть такая штука как ask/sed- которые по умолчанию доступны на Linux, и на винде тоже через msys2 и иже с ними.

    И питон ставить не придётся и использовать много где ещё можно.

    Следующая статья очевидно будет: консольная утилита на пистон для вывода Hello, World


    1. aik
      06.09.2024 12:43

      Я по молодости писал для комадной строки линукса утилиты для сортировки и отбора уникальных строк. Про sort и uniq я узнал уже после.