本文目录导读:

我来提供一个自动切换网络代理的脚本方案,以下是几种常见的实现方式:
基于网络的自动代理切换脚本(macOS/Linux)
#!/bin/bash
# 自动代理切换脚本 v1.0
# 适用于 macOS 和 Linux
# 配置区域
declare -A PROXIES=(
["work"]="http://192.168.1.100:8080"
["home"]="http://192.168.1.101:8080"
["public"]="http://proxy.company.com:3128"
)
# 网络检测函数
detect_network() {
# 检测当前网络类型
# 这里可以根据需要修改检测逻辑
# 检测是否在公司网络
if ping -c 1 -W 1 192.168.1.1 &>/dev/null; then
echo "work"
# 检测是否在家
elif ping -c 1 -W 1 10.0.0.1 &>/dev/null; then
echo "home"
# 其他网络
else
echo "public"
fi
}
# 设置系统代理
set_proxy() {
local proxy_type=$1
local proxy_url=${PROXIES[$proxy_type]}
# macOS 使用 networksetup
if [[ "$(uname)" == "Darwin" ]]; then
networksetup -setwebproxy "Wi-Fi" "$(echo $proxy_url | cut -d'/' -f3 | cut -d':' -f1)" "$(echo $proxy_url | cut -d':' -f3)"
networksetup -setsecurewebproxy "Wi-Fi" "$(echo $proxy_url | cut -d'/' -f3 | cut -d':' -f1)" "$(echo $proxy_url | cut -d':' -f3)"
# Linux 使用 gsettings 或 proxychains
else
gsettings set org.gnome.system.proxy mode 'manual'
gsettings set org.gnome.system.proxy.http host "$(echo $proxy_url | cut -d'/' -f3 | cut -d':' -f1)"
gsettings set org.gnome.system.proxy.http port "$(echo $proxy_url | cut -d':' -f3)"
gsettings set org.gnome.system.proxy.https host "$(echo $proxy_url | cut -d'/' -f3 | cut -d':' -f1)"
gsettings set org.gnome.system.proxy.https port "$(echo $proxy_url | cut -d':' -f3)"
fi
echo "[$(date)] 切换到: $proxy_type 网络,使用代理: $proxy_url"
}
# 主函数
main() {
local current_network=$(detect_network)
echo "[$(date)] 检测到网络: $current_network"
# 检查是否切换了网络
if [[ "$current_network" != "$LAST_NETWORK" ]]; then
set_proxy $current_network
LAST_NETWORK=$current_network
else
echo "[$(date)] 网络未变化,保持当前代理设置"
fi
# 添加延迟避免频繁检测
sleep 10
}
# 初始化
LAST_NETWORK=""
echo "[$(date)] 启动网络代理自动切换守护进程"
tskill -9 $$ 2>/dev/null
trap 'echo "脚本已停止"; exit' INT TERM
# 主循环
while true; do
main
done
基于 ping 的去抖动版本(更稳定)
#!/bin/bash
# 稳定的代理切换脚本
# 使用多 ping 来确定网络状态
declare -A NETWORK_TARGETS=(
["work"]="192.168.1.1"
["home"]="10.0.0.1"
["public"]="8.8.8.8"
)
declare -A PROXIES=(
["work"]="http://proxy.work.com:8080"
["home"]="http://proxy.home.com:8080"
["public"]=""
)
# 使用多个 ping 检查网络稳定性
check_network_stable() {
local target=$1
local success=0
local ping_count=5
for ((i=1; i<=$ping_count; i++)); do
if ping -c 1 -W 1 $target &>/dev/null; then
success=$((success + 1))
fi
sleep 0.2
done
# 要求至少 80% 的成功率
if (( success >= 4 )); then
return 0
else
return 1
fi
}
find_network() {
for net in "${!NETWORK_TARGETS[@]}"; do
if check_network_stable "${NETWORK_TARGETS[$net]}"; then
echo $net
return
fi
done
echo "unknown"
}
# 应用代理设置(跨平台)
apply_proxy() {
local proxy_address=$1
if [[ -z "$proxy_address" ]]; then
echo "关闭代理"
# 关闭代理的代码...
return
fi
# 提取 IP 和端口
local ip=$(echo $proxy_address | sed 's|http://||' | cut -d: -f1)
local port=$(echo $proxy_address | sed 's|http://||' | cut -d: -f2)
if [[ "$(uname)" == "Darwin" ]]; then
# macOS
networksetup -setwebproxy "Wi-Fi" $ip $port
networksetup -setsecurewebproxy "Wi-Fi" $ip $port
else
# Linux
export http_proxy="$proxy_address"
export https_proxy="$proxy_address"
export HTTP_PROXY="$proxy_address"
export HTTPS_PROXY="$proxy_address"
if command -v gsettings &>/dev/null; then
gsettings set org.gnome.system.proxy mode 'manual'
gsettings set org.gnome.system.proxy.http host $ip
gsettings set org.gnome.system.proxy.http port $port
gsettings set org.gnome.system.proxy.https host $ip
gsettings set org.gnome.system.proxy.https port $port
fi
fi
}
main() {
local current_net=$(find_network)
local proxy_url="${PROXIES[$current_net]}"
if [[ "$current_net" != "$last_net" || "$proxy_url" != "$last_proxy" ]]; then
echo "[$(date)] 网络变化: $last_net -> $current_net (代理: $proxy_url)"
apply_proxy "$proxy_url"
last_net=$current_net
last_proxy=$proxy_url
fi
sleep 5
}
# 运行
last_net=""
last_proxy=""
echo "代理切换脚本启动 (PID: $$)"
while true; do
main
done
Python 版本(跨平台)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
import platform
import time
import os
import sys
class AutoProxySwitcher:
def __init__(self):
self.system = platform.system()
self.config = {
'work': {
'test_ip': '192.168.1.1',
'proxy': 'http://192.168.1.100:8080'
},
'home': {
'test_ip': '10.0.0.1',
'proxy': 'http://192.168.1.101:8080'
},
'public': {
'test_ip': '8.8.8.8',
'proxy': '' # 无代理
}
}
self.current_network = None
def ping_host(self, host, count=3):
"""Ping 测试主机"""
if self.system == "Windows":
cmd = ['ping', '-n', str(count), '-w', '1000', host]
else:
cmd = ['ping', '-c', str(count), '-W', '1', host]
try:
result = subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return result.returncode == 0
except Exception as e:
print(f"Ping 错误: {e}")
return False
def detect_network(self):
"""检测当前网络"""
for network, config in self.config.items():
if self.ping_host(config['test_ip']):
return network
return 'public'
def set_proxy_mac(self, proxy_url):
"""macOS 设置代理"""
if not proxy_url:
# 关闭代理
subprocess.run(['networksetup', '-setwebproxystate', 'Wi-Fi', 'off'])
subprocess.run(['networksetup', '-setsecurewebproxystate', 'Wi-Fi', 'off'])
return
# 解析代理地址
proxy_part = proxy_url.replace('http://', '').split(':')
ip = proxy_part[0]
port = proxy_part[1]
subprocess.run(['networksetup', '-setwebproxy', 'Wi-Fi', ip, port])
subprocess.run(['networksetup', '-setsecurewebproxy', 'Wi-Fi', ip, port])
def set_proxy_linux(self, proxy_url):
"""Linux 设置代理"""
if not proxy_url:
os.environ.pop('http_proxy', None)
os.environ.pop('https_proxy', None)
return
os.environ['http_proxy'] = proxy_url
os.environ['https_proxy'] = proxy_url
# 设置系统代理(如果使用 GNOME)
if proxy_url:
proxy_part = proxy_url.replace('http://', '').split(':')
ip = proxy_part[0]
port = proxy_part[1]
subprocess.run(['gsettings', 'set', 'org.gnome.system.proxy', 'mode', 'manual'])
subprocess.run(['gsettings', 'set', 'org.gnome.system.proxy.http', 'host', ip])
subprocess.run(['gsettings', 'set', 'org.gnome.system.proxy.http', 'port', port])
def set_proxy_windows(self, proxy_url):
"""Windows 设置代理(通过注册表)"""
import winreg
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r'Software\Microsoft\Windows\CurrentVersion\Internet Settings',
0, winreg.KEY_SET_VALUE)
if proxy_url:
winreg.SetValueEx(key, 'ProxyEnable', 0, winreg.REG_DWORD, 1)
winreg.SetValueEx(key, 'ProxyServer', 0, winreg.REG_SZ, proxy_url)
else:
winreg.SetValueEx(key, 'ProxyEnable', 0, winreg.REG_DWORD, 0)
# 通知系统更改
import ctypes
INTERNET_OPTION_SETTINGS_CHANGED = 39
INTERNET_OPTION_REFRESH = 37
internet_settings = ctypes.windll.Wininet.InternetSetOption
internet_settings(0, INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)
internet_settings(0, INTERNET_OPTION_REFRESH, 0, 0)
def apply_proxy(self, proxy_url):
"""根据系统平台应用代理设置"""
if self.system == "Darwin":
self.set_proxy_mac(proxy_url)
elif self.system == "Linux":
self.set_proxy_linux(proxy_url)
elif self.system == "Windows":
self.set_proxy_windows(proxy_url)
else:
print(f"不支持的平台: {self.system}")
def run(self):
"""主运行循环"""
print(f"自动代理切换脚本启动 (PID: {os.getpid()})")
while True:
try:
network = self.detect_network()
proxy = self.config[network]['proxy']
if network != self.current_network:
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 网络: {network}, 代理: {proxy}")
self.apply_proxy(proxy)
self.current_network = network
# 等待 10 秒后再次检测
time.sleep(10)
except KeyboardInterrupt:
print("\n脚本已停止")
break
except Exception as e:
print(f"错误: {e}")
time.sleep(5)
if __name__ == "__main__":
switcher = AutoProxySwitcher()
switcher.run()
使用方式
保存和执行
# 保存脚本 chmod +x auto_proxy_switch.sh # 后台运行 nohup ./auto_proxy_switch.sh & # 查看日志 tail -f /tmp/proxy_switch.log
配置自定义
根据你的网络环境修改配置:
- 修改检测目标(IP地址)
- 修改代理服务器地址和端口
- 调整检测频率
- 添加更多网络场景
集成到系统
macOS (launchd):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.proxyswitch</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/auto_proxy_switch.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Linux (systemd):
[Unit] Description=Auto Proxy Switch [Service] Type=simple ExecStart=/path/to/auto_proxy_switch.sh [Install] WantedBy=multi-user.target
这个脚本会根据当前网络环境自动切换代理设置,适用于办公、家庭、公共网络等多种场景,你可以根据实际需求修改配置。