Tree
1.起因
自从把博客迁移到了Next.js,我就把代码放在了GitHub,尽管我之前写了一套我自己的Devops,但是服务器有时候不能访问GitHub导致不能拉取仓库代码,所以我写了一个自动化脚本,用于服务器定时更新Host文件以确保我的服务器能正常访问GitHub
2.脚本内容
创建一个名为 update_github_hosts.sh
的脚本:
#!/bin/bash
# GitHub访问优化脚本# 作者: 系统管理员# 用途: 定期更新GitHub相关域名的hosts记录
HOSTS_FILE="/etc/hosts"BACKUP_DIR="/etc/hosts_backups"BACKUP_FILE="$BACKUP_DIR/hosts.backup.$(date +%Y%m%d_%H%M%S)"
# 创建备份目录create_backup_dir() { if [ ! -d "$BACKUP_DIR" ]; then mkdir -p "$BACKUP_DIR" fi}
# 备份hosts文件并管理备份数量manage_backups() { create_backup_dir
# 创建新备份 cp "$HOSTS_FILE" "$BACKUP_FILE" echo "已备份hosts文件到: $BACKUP_FILE"
# 只保留最新的3个备份文件 cd "$BACKUP_DIR" ls -t hosts.backup.* 2>/dev/null | tail -n +4 | xargs rm -f 2>/dev/null
echo "当前保留的备份文件:" ls -la "$BACKUP_DIR"/hosts.backup.* 2>/dev/null || echo "无备份文件"}
# 获取IP地址函数get_ip() { local domain=$1 local ip=""
# 尝试多个DNS服务器 for dns in "8.8.8.8" "1.1.1.1" "114.114.114.114"; do ip=$(nslookup "$domain" "$dns" 2>/dev/null | grep -A 1 "Name:" | grep "Address:" | awk '{print $2}' | head -1) if [ -n "$ip" ] && [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "$ip" return 0 fi done
# 如果nslookup失败,尝试dig ip=$(dig +short "$domain" @8.8.8.8 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1) if [ -n "$ip" ]; then echo "$ip" return 0 fi
return 1}
# GitHub相关域名列表GITHUB_DOMAINS=( "github.com" "api.github.com" "www.github.com" "raw.githubusercontent.com" "gist.githubusercontent.com" "cloud.githubusercontent.com" "camo.githubusercontent.com" "avatars0.githubusercontent.com" "avatars1.githubusercontent.com" "avatars2.githubusercontent.com" "avatars3.githubusercontent.com" "avatars.githubusercontent.com" "github.githubassets.com" "assets-cdn.github.com")
main() { echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始更新GitHub hosts记录"
# 备份hosts文件并管理备份数量 manage_backups
# 移除旧的GitHub记录 sed -i '/# GitHub Start/,/# GitHub End/d' "$HOSTS_FILE"
# 添加新的GitHub记录 echo "" >> "$HOSTS_FILE" echo "# GitHub Start - $(date)" >> "$HOSTS_FILE"
local updated_count=0 local failed_domains=()
for domain in "${GITHUB_DOMAINS[@]}"; do echo "正在解析域名: $domain" ip=$(get_ip "$domain")
if [ $? -eq 0 ] && [ -n "$ip" ]; then echo "$ip $domain" >> "$HOSTS_FILE" echo "成功更新: $ip $domain" ((updated_count++)) else echo "警告: 无法解析域名 $domain" failed_domains+=("$domain") fi
# 避免请求过于频繁 sleep 1 done
echo "# GitHub End - $(date)" >> "$HOSTS_FILE"
# 刷新DNS缓存 if command -v systemctl &> /dev/null; then systemctl restart systemd-resolved 2>/dev/null || true fi
# 输出统计信息 echo "$(date '+%Y-%m-%d %H:%M:%S') - 更新完成! 成功更新 $updated_count 个域名"
if [ ${#failed_domains[@]} -gt 0 ]; then echo "失败的域名: ${failed_domains[*]}" fi
echo "GitHub hosts更新任务完成" echo "----------------------------------------"}
# 检查是否为root用户if [ "$EUID" -ne 0 ]; then echo "请使用root权限运行此脚本" exit 1fi
# 执行主函数main
3.安装和配置步骤
1. 创建脚本文件
sudo vim /usr/local/bin/update_github_hosts.sh
2. 赋予执行权限
sudo chmod +x /usr/local/bin/update_github_hosts.sh
3. 设置定时任务
编辑crontab:
sudo crontab -e
添加以下行(每天凌晨2点执行):
0 2 * * * /usr/local/bin/update_github_hosts.sh
或者每12小时执行一次:
0 2,14 * * * /usr/local/bin/update_github_hosts.sh
5. 手动测试脚本
sudo /usr/local/bin/update_github_hosts.sh
4.额外的优化脚本
如果你想要一个更简单的版本,这里还有一个轻量级的脚本:
#!/bin/bash# 简化版GitHub hosts更新脚本
HOSTS_FILE="/etc/hosts"
# 移除旧记录sed -i '/# GitHub/d' "$HOSTS_FILE"
# 获取并添加新记录{ echo "# GitHub - $(date)" echo "$(dig +short github.com @8.8.8.8) github.com" echo "$(dig +short api.github.com @8.8.8.8) api.github.com" echo "$(dig +short raw.githubusercontent.com @8.8.8.8) raw.githubusercontent.com"} >> "$HOSTS_FILE"
echo "GitHub hosts已更新 - $(date)"
5.使用说明
- 日志查看:脚本运行日志保存在
/var/log/github_hosts_update.log
- 备份恢复:如果出现问题,可以从
/etc/hosts.backup.日期
恢复 - 手动执行:可以随时手动运行脚本进行更新
- 监控效果:可以通过
ping github.com
测试连接效果