hosts文件管理脚本

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. 退出
请选择操作:
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坐公交也用券

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值