153 lines
6.8 KiB
Bash
153 lines
6.8 KiB
Bash
#!/bin/bash
|
||
# ** 自动更新 Shadowrocket 配置文件 **
|
||
#
|
||
# 脚本功能:
|
||
# 1. 从 Git 仓库拉取最新的 PAC 文件。
|
||
# 2. 下载已存在的 Shadowrocket 配置文件。
|
||
# 3. 从 PAC 文件中提取规则并插入到已存在的 Shadowrocket 配置文件中。
|
||
# 4. 将合并后的配置文件保存为新的文件。
|
||
# ** 切换到脚本所在目录 **
|
||
cd "$(dirname "$0")"
|
||
|
||
# 定义 PAC 文件路径 (假设 PAC 文件在当前 Git 仓库的 pac_file.pac), 已存在配置文件URL, 已存在配置文件名, 输出的自定义配置文件名, 代理组名称, 日志文件名
|
||
pac_file="gfw2.pac" # 假设 PAC 文件名为 pac_file.pac 且在当前目录
|
||
sr_cnip_ad_conf_url="https://johnshall.github.io/Shadowrocket-ADBlock-Rules-Forever/sr_cnip_ad.conf" # 已存在的 Shadowrocket 配置文件 URL
|
||
sr_cnip_ad_conf="sr_cnip_ad.conf" # 下载的已存在的 Shadowrocket 配置文件名 (本地保存文件名)
|
||
sr_cnip_ad_custom_conf="sr_cnip_ad_custom.conf" # 输出的自定义 Shadowrocket 配置文件名
|
||
#proxy_group_name="select_group" # 默认代理组名称,可根据需要修改
|
||
https_proxy_address="http://127.0.0.1:1099" # 代理服务器地址,可根据需要修改
|
||
log_file="update.log" # 日志文件名
|
||
direct_keyword="var directDomains"
|
||
proxy_keyword="var domainsUsingProxy"
|
||
|
||
# 定义日志输出函数,方便记录日志并同时输出到终端 (可选)
|
||
log() {
|
||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$log_file"
|
||
}
|
||
|
||
# 记录日志开始标记
|
||
log "# --- BEGIN SHADOWROCKET LOG --- $(date '+%Y-%m-%d %H:%M:%S') --- #"
|
||
|
||
# 设置 HTTPS 代理
|
||
export https_proxy="$https_proxy_address"
|
||
export http_proxy="$https_proxy_address" # 建议同时设置 http_proxy
|
||
|
||
log "已设置 HTTPS 代理: $https_proxy"
|
||
|
||
# Git pull 拉取最新的 PAC 文件
|
||
log "正在从 Git 仓库拉取最新的 PAC 文件..."
|
||
git pull 2>&1 | tee -a "$log_file" # 将 git pull 的输出也记录到日志
|
||
git_pull_status=$?
|
||
if [ $git_pull_status -ne 0 ]; then
|
||
log "错误:Git pull 命令执行失败,请检查 Git 仓库状态或网络连接。"
|
||
log "# --- END LOG --- $(date '+%Y-%m-%d %H:%M:%S') --- #" # 记录日志结束标记,即使出错也要记录
|
||
exit 1
|
||
fi
|
||
log "PAC 文件 Git pull 完成。"
|
||
|
||
# 检查 PAC 文件是否存在 (Git pull 后,PAC 文件应该存在于指定位置)
|
||
if [ ! -f "$pac_file" ]; then
|
||
log "错误:PAC 文件未找到:$pac_file,请确认 Git 仓库中存在此文件。"
|
||
log "# --- END SHADOWROCKET LOG --- $(date '+%Y-%m-%d %H:%M:%S') --- #" # 记录日志结束标记,即使出错也要记录
|
||
exit 1
|
||
fi
|
||
|
||
# 下载 sr_cnip_ad.conf 文件
|
||
log "正在下载 sr_cnip_ad.conf 文件..."
|
||
curl -m 30 -sSL -o "$sr_cnip_ad_conf" "$sr_cnip_ad_conf_url" 2>&1 | tee -a "$log_file" # 将 curl 的输出也记录到日志
|
||
curl_status=$?
|
||
if [ $curl_status -ne 0 ]; then
|
||
log "错误:下载 sr_cnip_ad.conf 文件失败,请检查网络连接或 URL 是否正确:$sr_cnip_ad_conf_url"
|
||
log "# --- END LOG --- $(date '+%Y-%m-%d %H:%M:%S') --- #" # 记录日志结束标记,即使出错也要记录
|
||
exit 1
|
||
fi
|
||
log "sr_cnip_ad.conf 文件下载完成。"
|
||
|
||
# 初始化用于存储规则的变量
|
||
rule_content=""
|
||
|
||
# 提取 directDomains 列表 (优化 sed 命令,减少反斜杠)
|
||
direct_domains_str=$(awk -v direct_keyword="$direct_keyword" '
|
||
$0 ~ direct_keyword {flag=1; next}
|
||
/}/ {flag=0}
|
||
flag
|
||
' $pac_file)
|
||
# direct_domains_str=$(grep -oP 'var directDomains = \{\K[^\}]*' "$pac_file")
|
||
if [ -n "$direct_domains_str" ]; then
|
||
while IFS= read -r -d ',' domain_line; do # 使用逗号作为分隔符逐行读取对象内的内容
|
||
# 优化后的 sed 命令:使用单引号包裹 sed 命令,并假设域名用双引号包裹,减少转义
|
||
domain=$(echo "$domain_line" | awk -F '"' '/:/ {print $2}')
|
||
# domain=$(echo "$domain_line" | sed -E 's/^\s*"([^"]+)":.*/\1/;s/^\s+//;s/\s+$//')
|
||
if [[ -n "$domain" && "$domain" != "}" ]]; then # 确保域名非空且不是对象结束符
|
||
rule_content+="DOMAIN-SUFFIX,$domain,Direct\n"
|
||
# rule_content+=",DOMAIN,$domain,direct\n"
|
||
fi
|
||
done <<< "$(echo "$direct_domains_str" | tr '\n' ',' )" # 将换行符替换为逗号,方便循环处理
|
||
fi
|
||
|
||
|
||
# 提取 domainsUsingProxy 列表 (优化 sed 命令,减少反斜杠)
|
||
proxy_domains_str=$(awk -v proxy_keyword="$proxy_keyword" '
|
||
$0 ~ proxy_keyword {flag=1; next}
|
||
/}/ {flag=0}
|
||
flag
|
||
' $pac_file)
|
||
# proxy_domains_str=$(grep -oP 'var domainsUsingProxy = \{\K[^\}]*' "$pac_file")
|
||
if [ -n "$proxy_domains_str" ]; then
|
||
while IFS= read -r -d ',' domain_line; do # 使用逗号作为分隔符逐行读取对象内的内容
|
||
# 优化后的 sed 命令:使用单引号包裹 sed 命令,并假设域名用双引号包裹,减少转义
|
||
domain=$(echo "$domain_line" | awk -F '"' '/:/ {print $2}')
|
||
#domain=$(echo "$domain_line" | sed -E 's/^\s*"([^"]+)":.*/\1/;s/^\s+//;s/\s+$//')
|
||
if [[ -n "$domain" && "$domain" != "}" ]]; then # 确保域名非空且不是对象结束符
|
||
rule_content+="DOMAIN-SUFFIX,$domain,Proxy\n"
|
||
#rule_content+=",DOMAIN,$domain,$proxy_group_name\n"
|
||
fi
|
||
done <<< "$(echo "$proxy_domains_str" | tr '\n' ',' )" # 将换行符替换为逗号,方便循环处理
|
||
fi
|
||
|
||
|
||
|
||
# 去除 rule_content 变量开头多余的逗号 (如果存在)
|
||
rule_content=$(echo "$rule_content" | sed 's/^,//g')
|
||
|
||
# 读取已下载的配置文件内容并插入规则
|
||
existing_conf_content=""
|
||
rule_section_found=false
|
||
while IFS= read -r line; do
|
||
existing_conf_content+="$line\n"
|
||
if [[ "$line" == "[Rule]" ]]; then
|
||
rule_section_found=true
|
||
existing_conf_content+="#自定义规则\n"
|
||
existing_conf_content+="$rule_content"
|
||
fi
|
||
done < "$sr_cnip_ad_conf"
|
||
|
||
if ! $rule_section_found; then
|
||
log "警告:在已下载的配置文件中未找到 [Rule] 区块,规则将添加到文件末尾。"
|
||
existing_conf_content+="\n[Rule]\n#自定义规则\n$rule_content"
|
||
fi
|
||
|
||
# 将合并后的配置内容写入新的文件
|
||
echo -e "$existing_conf_content" > "$sr_cnip_ad_custom_conf"
|
||
|
||
log "Shadowrocket 规则已合并到 '$sr_cnip_ad_conf' 并保存为 '$sr_cnip_ad_custom_conf'"
|
||
log "已将自定义规则插入到 [Rule] 区块下方,并添加了 '#自定义规则' 备注。"
|
||
log "请检查新的配置文件 '$sr_cnip_ad_custom_conf' 是否符合您的预期。"
|
||
log "开始执行 Git push..."
|
||
git add .
|
||
git commit -m "update $sr_cnip_ad_custom_conf"
|
||
git push 2>&1 | tee -a "$log_file" # 将 git push 的输出也记录到日志
|
||
git_push_final_status=$?
|
||
if [ $git_push_final_status -ne 0 ]; then
|
||
log "错误:Git push 命令执行失败。"
|
||
log "# --- END LOG --- $(date '+%Y-%m-%d %H:%M:%S') --- #" # 记录日志结束标记,即使出错也要记录
|
||
exit 1
|
||
fi
|
||
log "Git push 命令执行完成。"
|
||
log "脚本执行完毕,日志记录在 '$log_file' 文件中。"
|
||
|
||
# 记录日志结束标记
|
||
log "# --- END LOG --- $(date '+%Y-%m-%d %H:%M:%S') --- #"
|
||
|
||
exit 0
|