用脚本实现定时挂断连接

wen 实用脚本 2

本文目录导读:

用脚本实现定时挂断连接

  1. 脚本功能说明
  2. 使用示例
  3. 注意事项
#!/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()

脚本功能说明

  1. 跨平台支持:自动检测 Windows 或 Linux/macOS,使用对应的网络管理命令。
  2. 灵活的时间设置:支持 30s5m2h1d 或直接输入秒数。
  3. 自动或手动选择接口:不指定接口时自动选择第一个活动接口;也可用 --interface 指定。
  4. 断线重连:使用 --reconnect 参数可在断开后自动恢复连接。
  5. 接口列表查看:使用 --list 查看当前可用的网络接口。

使用示例

# 10秒后自动断开当前网络
python hangup.py
# 5分钟后断开指定接口,并自动重连
python hangup.py -d 5m -i "WLAN" --reconnect
# 查看可用接口
python hangup.py --list

注意事项

  • Windows 需以管理员权限运行(接口禁用需要管理员权限)。
  • Linux/macOS 可能需要 sudo 权限来执行 ipnetworksetup 命令。
  • 自动重连功能在 Windows 上可能因驱动差异导致恢复时间较长,建议等待 3-5 秒。

抱歉,评论功能暂时关闭!