import ipaddress
import platform
import re
import sys
from loguru import logger
dst = "C:/Windows/System32/drivers/etc/hosts"
if str(platform.system()) != "Windows":
dst = "/etc/hosts"
def input_ip():
"""
获取IP输入
:return:bool string
"""
ip = input("请输入IP地址:")
ip = str(ip).strip()
if not is_ipv4_or_ipv6(ip):
print("无效的IP地址,请重新操作")
return False, "Invalid"
return True, ip
def input_domain():
"""
获取域名输入
:return: bool string
"""
domain = input("请输入域名:")
domain = str(domain).strip()
if not is_valid_domain(domain):
print("无效的域名,请重新操作")
return False, "Invalid"
return True, domain
def read_hosts():
with open(dst, 'r') as file:
data = file.readlines()
return data
def write_hosts(data):
with open(dst, 'w') as file:
file.writelines(data)
def is_valid_domain(domain):
pattern = re.compile(r'^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$')
return bool(pattern.match(domain))
def is_ipv4_or_ipv6(ip_str):
try:
ip = ipaddress.ip_address(ip_str)
if isinstance(ip, ipaddress.IPv4Address) or isinstance(ip, ipaddress.IPv6Address):
return True
except ValueError:
logger.warning(f"IP地址格式错误")
return False
def domain_to_dict_index_name():
"""
将域名信息绑定到字典
:return: dict{int str}
"""
data = read_hosts()
index = 1
domain_dict = {}
for line in data:
ip, domain = line.split()
if is_valid_domain(domain):
domain_dict[index] = domain
return domain_dict
def domain_to_dict_index_ip():
"""
将IP信息绑定到字典
:return: dict{int str}
"""
data = read_hosts()
index = 1
ip_dict = {}
for line in data:
ip, domain = line.split()
if is_valid_domain(domain):
ip_dict[index] = ip
return ip_dict
def domain_to_dict_ip_name():
"""
将域名信息绑定到字典
:return: dict{int str}
"""
data = read_hosts()
index = 1
domain_dict = {}
for line in data:
ip, domain = line.split()
if is_valid_domain(domain) and is_ipv4_or_ipv6(ip):
domain_dict[ip] = domain
return domain_dict
def add_entry(ip, domain):
data = read_hosts()
for line in data:
if ip in line and domain in line:
print("条目已存在,无需新增。")
return
data.append(f'{ip} {domain}')
write_hosts(data)
def delete_entry():
domain_dict = domain_to_dict_index_name()
for index in domain_dict:
print(f"[ {index} ] -> [ {domain_dict[index]} ]")
se = input("请输入需要删除的域名ID\n")
try:
index = int(se)
except ValueError:
logger.warning("输入类型错误")
return
if 0 <= index <= len(domain_dict):
domain = domain_dict[index]
else:
logger.warning("选择范围超出...")
return
data = read_hosts()
data = [line for line in data if domain not in line]
write_hosts(data)
def update_entry():
print("请选择需要更新的类型")
print("[1] 将解析的域名值修改(IP不变)")
print("[2] 将解析的IP值修改(域名不变)")
ut = input("\n")
ut = str(ut).strip()
domain_dict = domain_to_dict_ip_name()
index_dict = domain_to_dict_index_name()
index_dict_ip = domain_to_dict_index_ip()
if ut == "1":
for key in index_dict.keys():
print(f"[ {key} ] -> [ {index_dict[key]} ]")
se = input("请输入需要修改的域名ID\n")
try:
index = int(se)
except ValueError:
logger.warning("输入类型错误")
return
if 0 <= index <= len(domain_dict):
domain = index_dict[index]
else:
logger.warning("选择范围超出...")
return
new_in, new_ip = input_domain()
if not new_in:
logger.warning("新域名格式错误")
return
for i in domain_dict:
if domain_dict[i] == domain:
domain_dict[i] = new_ip
write_hosts(domain_dict)
logger.info("更新结束...")
return
elif ut == "2":
for key in index_dict_ip.keys():
print(f"[ {key} ] -> [ {index_dict_ip[key]} ]")
se = input("请输入需要修改的IP ID\n")
try:
index = int(se)
except ValueError:
logger.warning("输入类型错误")
return
if 0 <= index <= len(index_dict_ip):
ip = index_dict_ip[index]
else:
logger.warning("选择范围超出...")
return
new_in, new_ip = input_ip()
if not new_in:
logger.warning("新域名格式错误")
return
write_dict = {}
for i in domain_dict:
if i == ip:
write_dict[i] = domain_dict[i]
else:
write_dict[i] = domain_dict[i]
if len(write_dict) == len(domain_dict):
print(write_dict)
write_hosts(write_dict)
logger.info("更新结束...")
def auto_clean():
"""
自动清理不符合格式的条目
:return:
"""
data = domain_to_dict_ip_name()
for key in data.keys():
if not is_valid_domain(data[key]) or not is_ipv4_or_ipv6(key):
del data[key]
write_hosts(data)
def main():
while True:
print("1. 查看hosts文件")
print("2. 新增条目")
print("3. 删除条目")
print("4. 更新条目")
print("5. 清空条目")
print("6. 优化条目(自动清理不符合格式的条目)")
print("q. 退出")
choice = input("请选择操作: \n")
choice = str(choice).strip()
if choice == '1':
print(''.join(read_hosts()))
elif choice == '2':
out, ip = input_ip()
if not out:
continue
out, domain = input_domain()
if not out:
continue
add_entry(ip, domain)
elif choice == '3':
delete_entry()
elif choice == '4':
update_entry()
elif choice == '5':
write_hosts({"": ""})
elif choice == '6':
auto_clean()
elif choice.lower() == 'q'.lower():
sys.exit(0)
else:
print("无效的选择,请重新选择。")
if __name__ == "__main__":
main()
效果
PS D:\code\coding\ywgl\tools\运维自动化> python .\HOSTS.py
1. 查看hosts文件
2. 新增条目
3. 删除条目
4. 更新条目
5. 清空条目
6. 优化条目(自动清理不符合格式的条目)
q. 退出
请选择操作:
1
1. 查看hosts文件
2. 新增条目
3. 删除条目
4. 更新条目
5. 清空条目
6. 优化条目(自动清理不符合格式的条目)
q. 退出
请选择操作:
2
请输入IP地址:192.178.22.2
请输入域名:baidu.cc
1. 查看hosts文件
2. 新增条目
3. 删除条目
4. 更新条目
5. 清空条目
6. 优化条目(自动清理不符合格式的条目)
q. 退出
请选择操作:
1
192.178.22.2 baidu.cc
1. 查看hosts文件
2. 新增条目
3. 删除条目
4. 更新条目
5. 清空条目
6. 优化条目(自动清理不符合格式的条目)
q. 退出
请选择操作:
3
[ 1 ] -> [ baidu.cc ]
请输入需要删除的域名ID
1
1. 查看hosts文件
2. 新增条目
3. 删除条目
4. 更新条目
5. 清空条目
6. 优化条目(自动清理不符合格式的条目)
q. 退出
请选择操作:
1
1. 查看hosts文件
2. 新增条目
3. 删除条目
4. 更新条目
5. 清空条目
6. 优化条目(自动清理不符合格式的条目)
q. 退出
请选择操作: