本文目录导读:

#!/usr/bin/env python3
"""
定时挂断网络连接脚本
支持 Windows (netsh) 和 Linux/macOS (nmcli/ifconfig)
"""
import argparse
import os
import platform
import subprocess
import sys
import time
from datetime import datetime, timedelta
def get_os():
"""检测操作系统类型"""
system = platform.system().lower()
if system == 'windows':
return 'windows'
elif system in ['linux', 'darwin']:
return 'unix'
else:
raise OSError(f"不支持的操作系统: {system}")
def get_network_interfaces_windows():
"""获取Windows网络接口列表"""
try:
output = subprocess.check_output(
["netsh", "interface", "show", "interface"],
text=True,
stderr=subprocess.DEVNULL
)
interfaces = []
for line in output.splitlines():
if "已连接" in line or "Connected" in line:
parts = line.split()
if len(parts) >= 4:
# 接口名称一般在最后
iface_name = parts[-1] if parts[-1] != "专用" else parts[-2]
interfaces.append(iface_name)
return interfaces
except subprocess.CalledProcessError:
return []
def get_network_interfaces_unix():
"""获取Unix/Linux/macOS网络接口列表"""
try:
if platform.system().lower() == 'darwin':
# macOS
output = subprocess.check_output(
["networksetup", "-listallhardwareports"],
text=True,
stderr=subprocess.DEVNULL
)
interfaces = []
for line in output.splitlines():
if "Hardware Port" in line or "Device" in line:
if "Device" in line:
iface = line.split(":")[-1].strip()
if iface and iface != "lo0":
interfaces.append(iface)
return interfaces
else:
# Linux - 使用 nmcli 或 ip
try:
output = subprocess.check_output(
["nmcli", "-t", "-f", "DEVICE,TYPE", "device", "status"],
text=True,
stderr=subprocess.DEVNULL
)
interfaces = []
for line in output.splitlines():
device, dtype = line.split(":")
if dtype in ["ethernet", "wifi"]:
interfaces.append(device)
return interfaces
except (subprocess.CalledProcessError, FileNotFoundError):
# 回退到 ip 命令
output = subprocess.check_output(
["ip", "link", "show"],
text=True,
stderr=subprocess.DEVNULL
)
interfaces = []
for line in output.splitlines():
if ": <" in line and "LOOPBACK" not in line:
iface = line.split(":")[1].strip()
if iface:
interfaces.append(iface)
return interfaces
except subprocess.CalledProcessError:
return []
def disconnect_interface_windows(interface_name):
"""Windows 断开指定接口"""
try:
subprocess.run(
["netsh", "interface", "set", "interface", interface_name, "disable"],
check=True,
capture_output=True,
text=True
)
print(f"[√] Windows 接口 '{interface_name}' 已禁用 (断开连接)")
return True
except subprocess.CalledProcessError as e:
print(f"[×] 断开失败: {e.stderr}")
return False
def disconnect_interface_unix(interface_name):
"""Unix/Linux/macOS 断开指定接口"""
try:
if platform.system().lower() == 'darwin':
# macOS 使用 networksetup
subprocess.run(
["networksetup", "-setairportpower", interface_name, "off"],
check=True,
capture_output=True,
text=True
)
print(f"[√] macOS 接口 '{interface_name}' 已断开")
else:
# Linux 使用 nmcli 或 ip
try:
subprocess.run(
["nmcli", "device", "disconnect", interface_name],
check=True,
capture_output=True,
text=True
)
print(f"[√] Linux 接口 '{interface_name}' 已断开")
except (subprocess.CalledProcessError, FileNotFoundError):
# 回退到 ip link set down
subprocess.run(
["sudo", "ip", "link", "set", interface_name, "down"],
check=True,
capture_output=True,
text=True
)
print(f"[√] Linux 接口 '{interface_name}' 已断开 (使用 ip link)")
return True
except subprocess.CalledProcessError as e:
print(f"[×] 断开失败: {e.stderr}")
return False
def reconnect_interface_windows(interface_name):
"""Windows 重新启用接口"""
try:
subprocess.run(
["netsh", "interface", "set", "interface", interface_name, "enable"],
check=True,
capture_output=True,
text=True
)
print(f"[√] Windows 接口 '{interface_name}' 已重新启用")
return True
except subprocess.CalledProcessError as e:
print(f"[×] 重连失败: {e.stderr}")
return False
def reconnect_interface_unix(interface_name):
"""Unix/Linux/macOS 重新连接接口"""
try:
if platform.system().lower() == 'darwin':
subprocess.run(
["networksetup", "-setairportpower", interface_name, "on"],
check=True,
capture_output=True,
text=True
)
print(f"[√] macOS 接口 '{interface_name}' 已重新连接")
else:
try:
subprocess.run(
["nmcli", "device", "connect", interface_name],
check=True,
capture_output=True,
text=True
)
print(f"[√] Linux 接口 '{interface_name}' 已重新连接")
except (subprocess.CalledProcessError, FileNotFoundError):
subprocess.run(
["sudo", "ip", "link", "set", interface_name, "up"],
check=True,
capture_output=True,
text=True
)
print(f"[√] Linux 接口 '{interface_name}' 已重新连接 (使用 ip link)")
return True
except subprocess.CalledProcessError as e:
print(f"[×] 重连失败: {e.stderr}")
return False
def parse_duration(duration_str):
"""解析时间字符串为秒数 (支持格式: 30s, 5m, 2h, 1d)"""
duration_str = duration_str.strip().lower()
if duration_str.endswith('s'):
return int(duration_str[:-1])
elif duration_str.endswith('m'):
return int(duration_str[:-1]) * 60
elif duration_str.endswith('h'):
return int(duration_str[:-1]) * 3600
elif duration_str.endswith('d'):
return int(duration_str[:-1]) * 86400
else:
try:
return int(duration_str)
except ValueError:
raise ValueError(f"无法解析时间格式: {duration_str},请使用 30s, 5m, 2h, 1d 格式")
def main():
parser = argparse.ArgumentParser(
description="定时挂断/重连网络连接脚本",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
使用示例:
# 10秒后断开WiFi (自动检测接口)
python hangup.py --duration 10s
# 5分钟后断开以太网并重连
python hangup.py --duration 5m --interface eth0 --reconnect
# 2小时后断开,指定接口名
python hangup.py --duration 2h --interface "WLAN"
# 列出可用接口
python hangup.py --list
"""
)
parser.add_argument(
"--duration", "-d",
help="挂断前等待时间 (格式: 30s, 5m, 2h, 1d 或纯秒数)",
default="10s"
)
parser.add_argument(
"--interface", "-i",
help="要断开的网络接口名称 (若不指定则自动选择)"
)
parser.add_argument(
"--reconnect", "-r",
action="store_true",
help="断开后自动重新连接"
)
parser.add_argument(
"--list", "-l",
action="store_true",
help="列出可用的网络接口"
)
args = parser.parse_args()
os_type = get_os()
print(f"[信息] 操作系统: {os_type.capitalize()}")
# 如果只是列出接口
if args.list:
if os_type == 'windows':
interfaces = get_network_interfaces_windows()
else:
interfaces = get_network_interfaces_unix()
if interfaces:
print("可用接口列表:")
for i, iface in enumerate(interfaces, 1):
print(f" {i}. {iface}")
else:
print("未检测到活动网络接口")
return
# 获取接口
if args.interface:
interface = args.interface
print(f"[信息] 使用指定接口: {interface}")
else:
# 自动检测第一个活动接口
if os_type == 'windows':
interfaces = get_network_interfaces_windows()
else:
interfaces = get_network_interfaces_unix()
if not interfaces:
print("[错误] 未检测到活动网络接口,请使用 --interface 手动指定")
sys.exit(1)
interface = interfaces[0]
print(f"[信息] 自动选择接口: {interface}")
# 解析时间
try:
seconds = parse_duration(args.duration)
except ValueError as e:
print(f"[错误] {e}")
sys.exit(1)
# 计算挂断时间
disconnect_time = datetime.now() + timedelta(seconds=seconds)
print(f"[计划] 将在 {disconnect_time.strftime('%H:%M:%S')} 断开接口 '{interface}'")
if args.reconnect:
print("[计划] 断开后自动重新连接")
# 等待
try:
for remaining in range(seconds, 0, -1):
mins, secs = divmod(remaining, 60)
time_format = f"{mins:02d}:{secs:02d}"
print(f"\r[倒计时] 剩余 {time_format} ", end="", flush=True)
time.sleep(1)
print("\r[倒计时] 时间到! ")
except KeyboardInterrupt:
print("\n[取消] 用户取消操作")
sys.exit(0)
# 执行断开
print(f"[操作] 正在断开接口 '{interface}'...")
if os_type == 'windows':
success = disconnect_interface_windows(interface)
else:
success = disconnect_interface_unix(interface)
# 如果需要重连
if success and args.reconnect:
print("[操作] 正在重新连接...")
wait_time = 3
print(f"[等待] 等待 {wait_time} 秒后重连...")
time.sleep(wait_time)
if os_type == 'windows':
reconnect_interface_windows(interface)
else:
reconnect_interface_unix(interface)
if __name__ == "__main__":
main()
脚本功能说明
- 跨平台支持:自动检测 Windows 或 Linux/macOS,使用对应的网络管理命令。
- 灵活的时间设置:支持
30s、5m、2h、1d或直接输入秒数。 - 自动或手动选择接口:不指定接口时自动选择第一个活动接口;也可用
--interface指定。 - 断线重连:使用
--reconnect参数可在断开后自动恢复连接。 - 接口列表查看:使用
--list查看当前可用的网络接口。
使用示例
# 10秒后自动断开当前网络 python hangup.py # 5分钟后断开指定接口,并自动重连 python hangup.py -d 5m -i "WLAN" --reconnect # 查看可用接口 python hangup.py --list
注意事项
- Windows 需以管理员权限运行(接口禁用需要管理员权限)。
- Linux/macOS 可能需要
sudo权限来执行ip或networksetup命令。 - 自动重连功能在 Windows 上可能因驱动差异导致恢复时间较长,建议等待 3-5 秒。