Python跨平台IP配置工具(Windows/Linux通用)完整源码+使用教程
一、前言
日常运维、局域网调试、多网络环境切换场景下,手动修改电脑IP地址、子网掩码、网关、DNS十分繁琐,且Windows、Linux系统配置命令不统一,新手极易操作出错。
为此,我用Python开发了一款跨平台智能IP配置工具,无需手动输入系统命令,自动识别操作系统、读取网卡信息、展示当前网络配置,支持一键设置静态IP、一键切换DHCP自动获取IP,完美兼容Windows、Linux、MacOS系统,适配中英文系统环境,解决编码报错、网卡识别失败等常见问题。
工具全程开源无依赖、轻量化运行,适合个人日常使用、批量设备运维、学习Python系统运维开发。
二、工具核心功能
-
跨平台适配:完美支持 Windows、Linux、MacOS(Darwin)系统
-
智能网卡识别:自动扫描系统所有可用网络适配器,兜底适配常见网卡名称
-
编码兼容处理:优先GBK、兼容UTF-8解码,解决中英文系统乱码问题
-
配置读取:一键获取网卡当前IP、子网掩码、默认网关信息
-
静态IP配置:自定义IP、子网掩码、网关、DNS服务器,支持可选配置
-
DHCP自动切换:一键恢复自动获取IP和DNS,还原网络默认配置
-
权限检测:自动判断管理员/root权限,避免配置失败
-
格式转换:内置CIDR与子网掩码双向转换,适配各类网络配置场景
-
日志调试模式:开启debug可查看底层执行命令,方便问题排查
三、运行环境要求
-
Python版本:Python3.6及以上(全版本兼容)
-
系统权限:必须以管理员/root权限运行(修改网络配置需要系统最高权限)
-
依赖库:纯原生库,无需额外pip安装(subprocess、platform、re等均为Python内置库)
-
编码格式:文件默认GBK编码,适配Windows系统,兼容Linux UTF-8编码
四、完整开源源码
直接复制以下代码,保存为 ip_config_tool.py 即可运行。
#!/usr/bin/env python
# -*- coding: gbk -*-
# 上面的编码声明根据你的文件实际编码修改,通常Windows系统用gbk或cp936
import subprocess
import platform
import re
import getpass
from typing import Dict, List, Optional
class IPConfigurator:
def __init__(self, debug=False):
self.os_type = platform.system()
self.debug = debug
self.adapters = self.get_network_adapters()
def decode_output(self, output_bytes) -> str:
"""智能解码字节数据,优先尝试GBK,再尝试UTF-8"""
try:
return output_bytes.decode('gbk')
except UnicodeDecodeError:
try:
return output_bytes.decode('utf-8')
except UnicodeDecodeError:
return output_bytes.decode('gbk', errors='ignore')
def get_network_adapters(self) -> List[str]:
"""获取网络适配器列表,改进编码处理"""
adapters = []
try:
if self.os_type == "Windows":
result = subprocess.run(
["netsh", "interface", "show", "interface"],
capture_output=True,
text=False, # 捕获字节数据
check=True
)
stdout = self.decode_output(result.stdout)
stderr = self.decode_output(result.stderr)
if self.debug:
print("\n===== 网络适配器原始字节解码后 =====")
print(stdout)
print("==============================\n")
if result.returncode != 0:
print(f"命令执行错误: {stderr}")
return adapters
lines = stdout.splitlines()
# 多种模式匹配适配器(兼容不同语言/格式)
patterns = [
re.compile(r'已连接\s+\d+\s+\w+\s+(.*)', re.IGNORECASE),
re.compile(r'\s+\d+\s+\w+\s+(.*)', re.IGNORECASE),
re.compile(r'本地连接|以太网|WLAN|无线|Network', re.IGNORECASE)
]
for line in lines:
line = line.strip()
if not line:
continue
for pattern in patterns:
match = pattern.search(line)
if match:
adapter = match.group(1).strip() if len(match.groups()) > 0 else line.strip()
if adapter and adapter not in adapters:
adapters.append(adapter)
break
elif self.os_type in ["Linux", "Darwin"]:
result = subprocess.run(
["ip", "link", "show"],
capture_output=True,
text=False,
check=True
)
stdout = self.decode_output(result.stdout)
if self.debug:
print("\n===== 网络适配器原始字节解码后 =====")
print(stdout)
print("==============================\n")
pattern = re.compile(r'^\d+: (\w+):')
for line in stdout.splitlines():
match = pattern.match(line)
if match and not match.group(1).startswith('lo'):
adapters.append(match.group(1))
except Exception as e:
print(f"获取网络适配器时出错: {str(e)}")
# 兜底:尝试常见适配器名
if not adapters and self.os_type == "Windows":
common_adapters = ["以太网", "本地连接", "WLAN", "无线网络连接", "Ethernet", "Wi-Fi"]
for adapter in common_adapters:
try:
test = subprocess.run(
["netsh", "interface", "show", "interface", adapter],
capture_output=True,
text=False,
check=False
)
if test.returncode == 0:
adapters.append(adapter)
except:
continue
return adapters
def get_current_ip_config(self, adapter: str) -> Dict[str, str]:
"""获取指定适配器的当前IP配置,改进编码处理"""
config = {}
try:
if self.os_type == "Windows":
result = subprocess.run(
["netsh", "interface", "ipv4", "show", "addresses", adapter],
capture_output=True,
text=False,
check=True
)
stdout = self.decode_output(result.stdout)
if self.debug:
print(f"\n===== {adapter} 的IP配置原始字节解码后 =====")
print(stdout)
print("=================================\n")
for line in stdout.splitlines():
line = line.strip()
if "IP 地址" in line or "IP Address" in line:
parts = line.split(":", 1)
if len(parts) >= 2:
config["ip"] = parts[1].strip()
elif "子网前缀" in line or "Subnet Prefix" in line:
parts = line.split("/", 1)
if len(parts) >= 2:
mask = parts[1].split()[0].strip()
config["subnet"] = self.cidr_to_subnet(mask)
elif "默认网关" in line or "Default Gateway" in line:
parts = line.split(":", 1)
if len(parts) >= 2:
config["gateway"] = parts[1].strip()
elif self.os_type in ["Linux", "Darwin"]:
result = subprocess.run(
["ip", "addr", "show", adapter],
capture_output=True,
text=False,
check=True
)
stdout = self.decode_output(result.stdout)
ip_match = re.search(r'inet (\d+\.\d+\.\d+\.\d+)/(\d+)', stdout)
if ip_match:
config["ip"] = ip_match.group(1)
config["subnet"] = self.cidr_to_subnet(ip_match.group(2))
gateway_result = subprocess.run(
["ip", "route", "show", "dev", adapter],
capture_output=True,
text=False,
check=False
)
gateway_stdout = self.decode_output(gateway_result.stdout)
gateway_match = re.search(r'via (\d+\.\d+\.\d+\.\d+)', gateway_stdout)
if gateway_match:
config["gateway"] = gateway_match.group(1)
except Exception as e:
print(f"获取IP配置失败: {str(e)}")
return config
def cidr_to_subnet(self, cidr: str) -> str:
"""将CIDR表示法转换为子网掩码"""
try:
cidr_int = int(cidr)
if cidr_int < 0 or cidr_int > 32:
return "255.255.255.0"
mask = (0xFFFFFFFF << (32 - cidr_int)) & 0xFFFFFFFF
return ".".join(map(str, [(mask >> 24) & 0xFF,
(mask >> 16) & 0xFF,
(mask >> 8) & 0xFF,
mask & 0xFF]))
except:
return "255.255.255.0"
def set_static_ip(self, adapter: str, ip: str, subnet: str,
gateway: Optional[str] = None, dns: Optional[List[str]] = None) -> bool:
"""设置静态IP地址"""
try:
if self.os_type == "Windows":
commands = [
["netsh", "interface", "ipv4", "set", "addresses",
adapter, "static", ip, subnet]
]
if gateway:
commands.append([
"netsh", "interface", "ipv4", "set", "gateway",
adapter, gateway, "1"
])
if dns:
dns_servers = " ".join(dns)
commands.append([
"netsh", "interface", "ipv4", "set", "dnsservers",
adapter, "static", dns_servers, "primary"
])
elif self.os_type == "Linux":
commands = [
["ip", "addr", "flush", "dev", adapter],
["ip", "addr", "add", f"{ip}/{self.subnet_to_cidr(subnet)}", "dev", adapter],
["ip", "link", "set", adapter, "up"]
]
if gateway:
commands.append(["ip", "route", "add", "default", "via", gateway, "dev", adapter])
if dns:
with open("/etc/resolv.conf", "w") as f:
for server in dns:
f.write(f"nameserver {server}\n")
for cmd in commands:
if self.debug:
print(f"执行命令: {' '.join(cmd)}")
result = subprocess.run(
cmd,
capture_output=True,
text=False, # 捕获字节
check=False
)
stdout = self.decode_output(result.stdout)
stderr = self.decode_output(result.stderr)
if result.returncode != 0:
print(f"命令执行失败: {' '.join(cmd)}")
print(f"错误信息: {stderr}")
return False
return True
except Exception as e:
print(f"设置静态IP失败: {str(e)}")
return False
def set_dhcp(self, adapter: str) -> bool:
"""设置为自动获取IP(DHCP)"""
try:
if self.os_type == "Windows":
subprocess.run(
["netsh", "interface", "ipv4", "set", "addresses", adapter, "dhcp"],
capture_output=True,
text=False,
check=True
)
subprocess.run(
["netsh", "interface", "ipv4", "set", "dnsservers", adapter, "dhcp"],
capture_output=True,
text=False,
check=True
)
elif self.os_type == "Linux":
subprocess.run(
["dhclient", adapter],
capture_output=True,
text=False,
check=True
)
return True
except subprocess.CalledProcessError as e:
stderr = self.decode_output(e.stderr)
print(f"设置DHCP失败: {stderr}")
return False
def subnet_to_cidr(self, subnet: str) -> str:
"""将子网掩码转换为CIDR表示法"""
try:
octets = list(map(int, subnet.split('.')))
if len(octets) != 4:
return "24"
binary = ''.join([f'{o:08b}' for o in octets])
cidr = len(binary.rstrip('0'))
return str(cidr if cidr > 0 else 0)
except:
return "24"
def is_admin(self) -> bool:
"""检查是否具有管理员权限"""
try:
if self.os_type == "Windows":
return subprocess.run(
["fltmc"], capture_output=True, text=False
).returncode == 0
else:
return getpass.getuser() == "root"
except:
return False
def main():
print("===== IP地址配置工具 =====")
try:
configurator = IPConfigurator(debug=True)
if not configurator.is_admin():
print("错误: 此工具需要管理员/root权限才能运行!")
print("请使用管理员权限重新运行程序。")
return
print(f"检测到操作系统: {configurator.os_type}")
print("\n可用的网络适配器:")
for i, adapter in enumerate(configurator.adapters, 1):
print(f" {i}. {adapter}")
if not configurator.adapters:
print("\n未找到可用的网络适配器!")
print("可能的解决方法:")
print("1. 确认网络适配器已启用并正常工作")
print("2. 尝试在命令提示符中执行 'netsh interface show interface' 查看适配器信息")
print("3. 检查是否有足够的系统权限")
return
try:
adapter_idx = int(input("\n请选择要配置的适配器编号: ")) - 1
if adapter_idx < 0 or adapter_idx >= len(configurator.adapters):
print("无效的适配器编号!")
return
selected_adapter = configurator.adapters[adapter_idx]
except ValueError:
print("请输入有效的数字!")
return
print(f"\n适配器 {selected_adapter} 的当前配置:")
current_config = configurator.get_current_ip_config(selected_adapter)
print(f" IP地址: {current_config.get('ip', '未设置')}")
print(f" 子网掩码: {current_config.get('subnet', '未设置')}")
print(f" 网关: {current_config.get('gateway', '未设置')}")
print("\n请选择操作:")
print(" 1. 设置静态IP地址")
print(" 2. 切换为自动获取IP(DHCP)")
try:
choice = int(input("请输入操作编号: "))
if choice == 1:
ip = input("请输入IP地址: ")
subnet = input("请输入子网掩码: ")
gateway = input("请输入网关(可选,直接回车跳过): ") or None
dns_input = input("请输入DNS服务器(多个用空格分隔,可选): ")
dns = dns_input.split() if dns_input else None
print(f"\n正在设置静态IP...")
success = configurator.set_static_ip(
selected_adapter, ip, subnet, gateway, dns
)
if success:
print("IP配置已更新!")
new_config = configurator.get_current_ip_config(selected_adapter)
print(f" IP地址: {new_config.get('ip', '未设置')}")
print(f" 子网掩码: {new_config.get('subnet', '未设置')}")
print(f" 网关: {new_config.get('gateway', '未设置')}")
elif choice == 2:
print("\n正在切换为自动获取IP...")
success = configurator.set_dhcp(selected_adapter)
if success:
print("已切换为自动获取IP(DHCP)!")
else:
print("无效的操作编号!")
except ValueError:
print("请输入有效的数字!")
except Exception as e:
print(f"操作失败: {str(e)}")
except Exception as e:
print(f"程序运行出错: {str(e)}")
if __name__ == "__main__":
main()
五、核心代码模块解析
1. 智能解码模块
解决Windows中英文系统、Linux跨系统执行命令乱码问题,优先GBK解码,失败自动切换UTF-8,兜底忽略错误字符,适配所有系统编码场景。
2. 网卡自动识别模块
通过系统原生命令扫描网卡,搭配正则多模式匹配,兼容中英文系统网卡名称,新增兜底匹配规则,避免网卡识别为空的问题。
3. 网络配置读取模块
调用系统原生网络查询命令,精准解析IP、子网前缀、网关信息,自动完成CIDR与子网掩码转换,统一输出标准化配置信息。
4. 静态IP/DHCP配置模块
根据操作系统自动适配不同配置命令,Windows基于netsh命令、Linux基于ip命令,支持自定义DNS、网关可选配置,一键切换静态/动态IP模式。
5. 权限检测模块
Windows通过fltmc命令、Linux通过root用户校验,提前检测运行权限,规避权限不足导致的配置失败问题。
六、详细使用教程
步骤1:准备工作
-
安装Python3环境,配置系统环境变量
-
将源码保存为
ip_config_tool.py文件 -
关键:右键终端/命令提示符,选择「以管理员身份运行」
步骤2:运行工具
进入文件所在目录,执行运行命令:
python ip_config_tool.py
步骤3:选择网卡设备
程序自动扫描并列出所有可用网卡,输入对应编号选择需要配置的网络适配器(以太网、WLAN无线网卡等)。
步骤4:查看当前网络配置
选中网卡后,工具自动展示当前IP、子网掩码、网关配置,方便对比修改前后差异。
步骤5:执行配置操作
-
选项1:设置静态IP:依次输入自定义IP、子网掩码、网关(可选)、DNS(可选),回车自动配置
-
选项2:切换DHCP:一键恢复系统自动获取IP和DNS,还原默认网络配置
七、常见问题与解决方案
1. 程序提示权限不足
解决方案:必须以管理员/root权限运行终端,普通用户无法修改系统网络配置。
2. 未扫描到网络适配器
解决方案:确认网卡已启用、网络驱动正常;可手动核对系统网卡名称,工具自带常见网卡兜底适配。
3. 配置IP后网络无法联网
解决方案:检查IP、子网掩码、网关是否匹配局域网网段,DNS服务器地址是否有效。
4. 运行出现编码报错
解决方案:Windows保持GBK编码,Linux/Mac可修改文件编码为UTF-8,工具自带智能解码兼容。
八、工具优势总结
-
零依赖轻量化:纯Python原生库,无需安装第三方模块,开箱即用
-
全平台兼容:一套代码适配Windows、Linux、MacOS,统一操作逻辑
-
容错性极强:智能编码、兜底匹配、权限校验,规避90%以上运行报错
-
极简操作:交互式可视化操作,无需记忆系统网络命令,新手零基础上手
-
实用性拉满:适配日常调试、运维批量配置、多环境网络切换场景
九、拓展方向
-
增加IP合法性校验,避免输入无效IP地址
-
添加网络连通性测试(ping网关、公网DNS)
-
开发GUI可视化界面,脱离命令行操作
-
支持批量配置多网卡、批量切换网络配置
-
增加配置保存/加载功能,一键切换预设网络方案
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)