From d33eda92d1d9ea0331b2b844ef36d7a929ec8ae0 Mon Sep 17 00:00:00 2001 From: Feng Yu Date: Mon, 29 Jun 2026 22:59:43 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E5=86=85=E6=A0=B8=E5=8E=9F=E7=94=9F?= =?UTF-8?q?=E6=8C=81=E4=B9=85=E5=8C=96=E6=9B=BF=E4=BB=A3=20web=5Fsave,=20c?= =?UTF-8?q?ache.db=20cp=20=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 启用 mihomo profile.store-selected 与 singbox cache_file, cache.db 运行于 tmpfs(bbolt 依赖 mmap, 持久分区 jffs2/ubifs 不支持): - mihomo cache.db 路径不可配(-d $BINDIR), bfstart 启动前软链 $BINDIR/cache.db 到 $TMPDIR; 小内存模式($BINDIR=$TMPDIR)守卫跳过防自指 - singbox 直接 cache_file.path 指向 $TMPDIR/cache.db web_save/web_restore 保留原函数名与 hook 位置(向后兼容旧 crontab), 内部改为 cache.db cp 同步: - start.sh stop 调 web_save 备份(kill 前) - bfstart 调 web_restore 启动前恢复(仅 tmpfs 无时恢复, 防覆盖更新) - task 106 web_save_auto 每10分钟定时备份 - 小内存模式 web_save 守卫跳过(与软链守卫一致) 解决面板配置丢失类 issue #1264 #1276 #998。 close #1296 --- scripts/init.sh | 22 ++-- scripts/libs/web_restore.sh | 12 +- scripts/libs/web_save.sh | 60 ++++------ scripts/menus/task_cmd.sh | 76 ++++++------ scripts/start.sh | 195 +++++++++++++++---------------- scripts/starts/afstart.sh | 76 ++++++------ scripts/starts/bfstart.sh | 20 +++- scripts/starts/clash_modify.sh | 7 +- scripts/starts/singbox_modify.sh | 15 +-- 9 files changed, 237 insertions(+), 246 deletions(-) diff --git a/scripts/init.sh b/scripts/init.sh index 45c0603a5..bcb89d866 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -3,7 +3,7 @@ #特殊固件识别及标记 [ -f "/etc/storage/started_script.sh" ] && { #老毛子固件 - systype=Padavan + systype=Padavan initdir='/etc/storage/started_script.sh' } [ -d "/jffs" ] && { #华硕固件 @@ -83,8 +83,8 @@ done setconfig versionsh_l $version #生成用于执行启动服务的变量文件 [ ! -f "$CRASHDIR"/configs/command.env ] && { - echo 'TMPDIR=/tmp/ShellCrash' > "$CRASHDIR"/configs/command.env - echo "BINDIR=$CRASHDIR" >> "$CRASHDIR"/configs/command.env + echo 'TMPDIR=/tmp/ShellCrash' >"$CRASHDIR"/configs/command.env + echo "BINDIR=$CRASHDIR" >>"$CRASHDIR"/configs/command.env } if [ -n "$(grep 'crashcore=singbox' "$CFG_PATH")" ]; then COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"' @@ -102,7 +102,7 @@ grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || { [ -n "$url" ] && setconfig update_url "$url" [ -n "$release_type" ] && setconfig release_type "$release_type" #设置语言 -[ -n "$language" ] && echo "$language" > "$CRASHDIR/configs/i18n.cfg" +[ -n "$language" ] && echo "$language" >"$CRASHDIR/configs/i18n.cfg" #设置环境变量 [ -w /opt/etc/profile ] && [ "$systype" = "Padavan" ] && profile=/opt/etc/profile [ -w /jffs/configs/profile.add ] && profile=/jffs/configs/profile.add @@ -130,11 +130,11 @@ fi #镜像化OpenWrt(snapshot)额外设置 if [ "$systype" = "mi_snapshot" -o "$systype" = "ng_snapshot" ]; then chmod 755 "$CRASHDIR"/starts/snapshot_init.sh - if [ "$systype" = "mi_snapshot" ];then + if [ "$systype" = "mi_snapshot" ]; then path="/data/shellcrash_init.sh" sed -i "s#^CRASHDIR=.*#CRASHDIR=$CRASHDIR#" "$CRASHDIR"/starts/snapshot_init.sh mv -f "$CRASHDIR"/starts/snapshot_init.sh "$path" - [ ! -f /data/auto_start.sh ] && echo '#用于自定义需要开机启动的功能或者命令,会在开机后自动运行' > /data/auto_start.sh + [ ! -f /data/auto_start.sh ] && echo '#用于自定义需要开机启动的功能或者命令,会在开机后自动运行' >/data/auto_start.sh else path="$CRASHDIR"/starts/snapshot_init.sh fi @@ -166,14 +166,14 @@ fi setconfig firewall_mod 'nftables' setconfig release_type 'master' setconfig start_old 'OFF' - echo "$CRASHDIR/menu.sh" >> /etc/profile - cat > /usr/bin/crash <<'EOF' + echo "$CRASHDIR/menu.sh" >>/etc/profile + cat >/usr/bin/crash <<'EOF' #!/bin/sh CRASHDIR=${CRASHDIR:-/etc/ShellCrash} export CRASHDIR exec "$CRASHDIR/menu.sh" "$@" EOF - chmod 755 /usr/bin/crash + chmod 755 /usr/bin/crash } setconfig systype $systype #删除临时文件 @@ -189,7 +189,7 @@ for file in config.yaml.bak user.yaml proxies.yaml proxy-groups.yaml rules.yaml mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/yamls/"$file" 2>/dev/null done [ ! -L "$CRASHDIR"/config.yaml ] && mv -f "$CRASHDIR"/config.yaml "$CRASHDIR"/yamls/config.yaml 2>/dev/null -for file in fake_ip_filter mac web_save servers_chs.list servers_en.list fake_ip_filter.list singbox_providers.list clash_providers.list; do +for file in fake_ip_filter mac servers_chs.list servers_en.list fake_ip_filter.list singbox_providers.list clash_providers.list; do mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/configs/"$file" 2>/dev/null done #迁移任务状态文件到新目录 @@ -239,7 +239,7 @@ sed -i "s/redir_mod=Tun模式/redir_mod=Tun/g" "$CFG_PATH" sed -i "s/redir_mod=混合模式/redir_mod=Mix/g" "$CFG_PATH" sed -i "s/redir_mod=纯净模式/firewall_area=4/g" "$CFG_PATH" #变量统一使用ON/OFF -sed -i 's/=\(已启用\|已开启\)$/=ON/' "$CFG_PATH" +sed -i 's/=\(已启用\|已开启\)$/=ON/' "$CFG_PATH" sed -i 's/=\(未启用\|未开启\)$/=OFF/' "$CFG_PATH" printf '\033[32m脚本初始化完成,请输入\033[30;47m %s \033[0;33m命令开始使用!\033[0m\n' "$my_alias" diff --git a/scripts/libs/web_restore.sh b/scripts/libs/web_restore.sh index 9907059d0..e06e1682e 100644 --- a/scripts/libs/web_restore.sh +++ b/scripts/libs/web_restore.sh @@ -1,4 +1,3 @@ - # put_save() { #推送面板选择 [ -z "$3" ] && request_type=PUT || request_type=$3 @@ -8,13 +7,6 @@ put_save() { #推送面板选择 wget -q --method="$request_type" --header="Authorization: Bearer $secret" --header="Content-Type:application/json" --body-data="$2" "$1" >/dev/null fi } -web_restore() { #还原面板选择 - num=$(cat "$CRASHDIR"/configs/web_save | wc -l) - i=1 - while [ "$i" -le "$num" ]; do - group_name=$(awk -F ',' 'NR=="'${i}'" {print $1}' "$CRASHDIR"/configs/web_save | sed 's/ /%20/g') - now_name=$(awk -F ',' 'NR=="'${i}'" {print $2}' "$CRASHDIR"/configs/web_save) - put_save "http://127.0.0.1:${db_port}/proxies/${group_name}" "{\"name\":\"${now_name}\"}" - i=$((i + 1)) - done +web_restore() { #还原面板配置(恢复 cache.db 到 $TMPDIR;tmpfs 已有则跳过,避免覆盖更新的) + [ ! -f "$TMPDIR"/cache.db ] && [ -s "$BINDIR"/configs/cache.db ] && cp -f "$BINDIR"/configs/cache.db "$TMPDIR"/cache.db } diff --git a/scripts/libs/web_save.sh b/scripts/libs/web_save.sh index e734a6c09..0ad9aa953 100644 --- a/scripts/libs/web_save.sh +++ b/scripts/libs/web_save.sh @@ -1,42 +1,24 @@ get_save() { #获取面板信息并内部处理所有异常 - local response exit_code - if curl --version >/dev/null 2>&1; then - response=$(curl -sf -H "Authorization: Bearer ${secret}" -H "Content-Type:application/json" "$1" 2>&1) - exit_code=$? - [ $exit_code -eq 0 ] && [ -n "$response" ] && [ "$response" != "{}" ] && { - echo "$response" - return 0 - } - return 1 - elif [ -n "$(wget --help 2>&1 | grep '\-\-method')" ]; then - response=$(wget -q --header="Authorization: Bearer ${secret}" --header="Content-Type:application/json" -O - "$1" 2>&1) - exit_code=$? - [ $exit_code -eq 0 ] && [ -n "$response" ] && [ "$response" != "{}" ] && { - echo "$response" - return 0 - } - return 1 - fi - return 1 + local response exit_code + if curl --version >/dev/null 2>&1; then + response=$(curl -sf -H "Authorization: Bearer ${secret}" -H "Content-Type:application/json" "$1" 2>&1) + exit_code=$? + [ $exit_code -eq 0 ] && [ -n "$response" ] && [ "$response" != "{}" ] && { + echo "$response" + return 0 + } + return 1 + elif [ -n "$(wget --help 2>&1 | grep '\-\-method')" ]; then + response=$(wget -q --header="Authorization: Bearer ${secret}" --header="Content-Type:application/json" -O - "$1" 2>&1) + exit_code=$? + [ $exit_code -eq 0 ] && [ -n "$response" ] && [ "$response" != "{}" ] && { + echo "$response" + return 0 + } + return 1 + fi + return 1 } - -web_save() { #最小化保存面板节点选择 - #使用get_save获取面板节点设置,失败自动退出 - response=$(get_save "http://127.0.0.1:${db_port}/proxies") || return 1 - - echo "$response" | sed 's/{}//g' | sed 's/:{/\ -/g' | grep -aE '"Selector"' >"$TMPDIR"/web_proxies - - >"$TMPDIR"/web_save - [ -s "$TMPDIR"/web_proxies ] && while read line; do - def=$(echo "$line" | grep -oE '"all".*",' | awk -F "[\"]" '{print $4}') - now=$(echo "$line" | grep -oE '"now".*",' | awk -F "[\"]" '{print $4}') - [ "$def" != "$now" ] && { - name=$(echo "$line" | grep -oE '"name".*",' | awk -F "[\"]" '{print $4}') - echo "${name},${now}" >>"$TMPDIR"/web_save - } - done <"$TMPDIR"/web_proxies - rm -f "$TMPDIR"/web_proxies - . "$CRASHDIR"/libs/compare.sh && compare "$TMPDIR"/web_save "$CRASHDIR"/configs/web_save - [ "$?" = 0 ] && rm -f "$TMPDIR"/web_save || mv -f "$TMPDIR"/web_save "$CRASHDIR"/configs/web_save +web_save() { #保存面板配置(备份 cache.db 到 $BINDIR/configs;小内存模式跳过) + [ "$BINDIR" != "$TMPDIR" ] && [ -s "$TMPDIR"/cache.db ] && cp -f "$TMPDIR"/cache.db "$BINDIR"/configs/cache.db } diff --git a/scripts/menus/task_cmd.sh b/scripts/menus/task_cmd.sh index 026eae86e..2b5e2cfe7 100644 --- a/scripts/menus/task_cmd.sh +++ b/scripts/menus/task_cmd.sh @@ -2,7 +2,11 @@ # Copyright (C) Juewuy #加载全局变量 -[ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd) +[ -z "$CRASHDIR" ] && CRASHDIR=$( + cd $(dirname $0) + cd .. + pwd +) . "$CRASHDIR"/libs/get_config.sh #加载工具 . "$CRASHDIR"/libs/check_cmd.sh @@ -14,11 +18,11 @@ load_lang task_cmd -task_logger(){ +task_logger() { [ "$task_push" = 1 ] && push= || push=off [ -n "$2" -a "$2" != 0 ] && echo -e "\033[$2m$1\033[0m" [ "$3" = 'off' ] && push=off - echo "$1" |grep -qE "($TASK_CMD_EVERY|$TASK_CMD_HOURLY)([1-9]|[1-9][0-9])$TASK_CMD_MIN" && { + echo "$1" | grep -qE "($TASK_CMD_EVERY|$TASK_CMD_HOURLY)([1-9]|[1-9][0-9])$TASK_CMD_MIN" && { push=off cover=on } @@ -26,47 +30,47 @@ task_logger(){ } #任务命令 -check_update(){ #检查更新工具 +check_update() { #检查更新工具 get_bin "$TMPDIR"/crashversion "$1" echooff [ "$?" = "0" ] && . "$TMPDIR"/crashversion 2>/dev/null rm -rf "$TMPDIR"/crashversion } -update_core(){ #自动更新内核 +update_core() { #自动更新内核 #检查版本 check_update bin/version crash_v_new=$(eval echo \$${crashcore}_v) - if [ -z "$crash_v_new" -o "$crash_v_new" = "$core_v" ];then + if [ -z "$crash_v_new" -o "$crash_v_new" = "$core_v" ]; then task_logger "$TASK_CMD_CORE_SKIP" return 0 else . "$CRASHDIR"/libs/core_tools.sh && core_webget #调用下载工具 case "$?" in - 0) - task_logger "$TASK_CMD_CORE_DONE" - "$CRASHDIR"/start.sh start - return 0 - ;; - 1) - task_logger "$TASK_CMD_CORE_DL_FAIL" - return 1 - ;; - *) - task_logger "$TASK_CMD_CORE_VERIFY_FAIL" - "$CRASHDIR"/start.sh start - return 1 - ;; + 0) + task_logger "$TASK_CMD_CORE_DONE" + "$CRASHDIR"/start.sh start + return 0 + ;; + 1) + task_logger "$TASK_CMD_CORE_DL_FAIL" + return 1 + ;; + *) + task_logger "$TASK_CMD_CORE_VERIFY_FAIL" + "$CRASHDIR"/start.sh start + return 1 + ;; esac fi } -update_scripts(){ #自动更新脚本 +update_scripts() { #自动更新脚本 #检查版本 check_update version - if [ -z "$versionsh" -o "$versionsh" = "versionsh_l" ];then + if [ -z "$versionsh" -o "$versionsh" = "versionsh_l" ]; then task_logger "$TASK_CMD_SCRIPT_SKIP" return 0 else get_bin "$TMPDIR"/ShellCrash.tar.gz "ShellCrash.tar.gz" - if [ "$?" != "0" ];then + if [ "$?" != "0" ]; then rm -rf "$TMPDIR"/ShellCrash.tar.gz task_logger "$TASK_CMD_CORE_DL_FAIL" return 1 @@ -75,7 +79,7 @@ update_scripts(){ #自动更新脚本 "$CRASHDIR"/start.sh stop #解压 tar -zxf "$TMPDIR"/ShellCrash.tar.gz ${tar_para} -C "$CRASHDIR"/ - if [ $? -ne 0 ];then + if [ $? -ne 0 ]; then rm -rf "$TMPDIR"/ShellCrash.tar.gz task_logger "$TASK_CMD_SCRIPT_UNZIP_FAIL" "$CRASHDIR"/start.sh start @@ -88,19 +92,19 @@ update_scripts(){ #自动更新脚本 fi fi } -update_mmdb(){ #自动更新数据库 - getgeo(){ +update_mmdb() { #自动更新数据库 + getgeo() { #检查版本 check_update bin/version geo_v="$(echo $2 | awk -F "." '{print $1}')_v" #获取版本号类型比如Country_v geo_v_new=$GeoIP_v geo_v_now=$(eval echo \$$geo_v) - if [ -z "$geo_v_new" -o "$geo_v_new" = "$geo_v_now" ];then + if [ -z "$geo_v_new" -o "$geo_v_new" = "$geo_v_now" ]; then task_logger "$TASK_CMD_DB_SKIP_PREFIX$2$TASK_CMD_DB_SKIP_SUFFIX" else #更新文件 get_bin "$TMPDIR"/$1 "bin/geodata/$2" - if [ "$?" != "0" ];then + if [ "$?" != "0" ]; then task_logger "$TASK_CMD_DB_DL_FAIL_PREFIX$2$TASK_CMD_DB_DL_FAIL_SUFFIX" rm -rf "$TMPDIR"/$1 else @@ -118,14 +122,14 @@ update_mmdb(){ #自动更新数据库 [ -n "${geosite_cn_v}" -a -s "$CRASHDIR"/geosite.db ] && getgeo geosite.db geosite_cn.db return 0 } -reset_firewall(){ #重设透明路由防火墙 +reset_firewall() { #重设透明路由防火墙 "$CRASHDIR"/start.sh stop_firewall "$CRASHDIR"/start.sh afstart } -ntp(){ +ntp() { ckcmd ntpd && ntpd -n -q -p 203.107.6.88 >/dev/null 2>&1 || exit 0 } -web_save_auto(){ +web_save_auto() { . "$CRASHDIR"/libs/web_save.sh && web_save } update_config() { #更新订阅并重启 @@ -133,9 +137,9 @@ update_config() { #更新订阅并重启 } hotupdate() { #热更新订阅 . "$CRASHDIR"/starts/core_config.sh && get_core_config && - . "$CRASHDIR"/starts/check_core.sh && check_core && - . "$CRASHDIR"/starts/"$target"_modify.sh && modify_"$format" && rm -rf "$TMPDIR"/CrashCore && - . "$CRASHDIR"/libs/web_restore.sh && put_save "http://127.0.0.1:$db_port/configs" "{\"path\":\"$CRASHDIR/config.$format\"}" + . "$CRASHDIR"/starts/check_core.sh && check_core && + . "$CRASHDIR"/starts/"$target"_modify.sh && modify_"$format" && rm -rf "$TMPDIR"/CrashCore && + . "$CRASHDIR"/libs/web_restore.sh && put_save "http://127.0.0.1:$db_port/configs" "{\"path\":\"$CRASHDIR/config.$format\"}" exit $? } @@ -146,8 +150,8 @@ case "$1" in #task_logger "任务$task_name 开始执行" eval $task_command && task_res="$TASK_CMD_RES_OK" || task_res="$TASK_CMD_RES_FAIL" task_logger "$TASK_CMD_EXEC_PREFIX$2$TASK_CMD_EXEC_MID$task_res" - ;; + ;; *) "$1" - ;; + ;; esac diff --git a/scripts/start.sh b/scripts/start.sh index 97e9247fa..dab12e363 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -15,17 +15,17 @@ . "$CRASHDIR"/libs/logger.sh . "$CRASHDIR"/libs/web_save.sh #特殊脚本 -bfstart(){ +bfstart() { "$CRASHDIR"/starts/bfstart.sh } -afstart(){ +afstart() { "$CRASHDIR"/starts/afstart.sh } -stop_firewall(){ +stop_firewall() { "$CRASHDIR"/starts/fw_stop.sh } #保守模式启动 -start_l(){ +start_l() { bfstart && { . "$CRASHDIR"/starts/start_legacy.sh start_legacy "$COMMAND" 'shellcrash' @@ -33,102 +33,101 @@ start_l(){ } case "$1" in - -start) - [ -n "$(pidof CrashCore)" ] && $0 stop #禁止多实例 - stop_firewall #清理路由策略 - rm -f "$CRASHDIR"/\.start_error #移除自启失败标记 - #使用不同方式启动服务 - if [ "$firewall_area" = "5" ]; then #主旁转发 - . "$CRASHDIR"/starts/fw_start.sh - elif [ "$start_old" = "ON" ]; then - start_l - elif [ -f /etc/rc.common ] && grep -q 'procd' /proc/1/comm; then - /etc/init.d/shellcrash start - elif [ "$USER" = "root" ] && grep -q 'systemd' /proc/1/comm; then - FragmentPath=$(systemctl show -p FragmentPath shellcrash | sed 's/FragmentPath=//') - [ -f "$FragmentPath" ] && { - sed -i "s#^ExecStart=.*#ExecStart=$COMMAND >/dev/null#" "$FragmentPath" - systemctl daemon-reload - } - systemctl start shellcrash.service || . "$CRASHDIR"/starts/start_error.sh - elif grep -q 's6' /proc/1/comm; then - bfstart && /command/s6-svc -u /run/service/shellcrash && { - [ ! -f "$CRASHDIR"/.dis_startup ] && touch /etc/s6-overlay/s6-rc.d/user/contents.d/afstart - afstart & - } - elif rc-status -r >/dev/null 2>&1; then - rc-service shellcrash stop >/dev/null 2>&1 - rc-service shellcrash start - else - start_l - fi - ;; -stop) - logger ShellCrash服务即将关闭...... - [ -n "$(pidof CrashCore)" ] && web_save #保存面板配置 - #清理定时任务 - cronload | grep -vE '^$|start_legacy_wd.sh|运行时每' > "$TMPDIR"/cron_tmp - cronadd "$TMPDIR"/cron_tmp - rm -f "$TMPDIR"/cron_tmp - #停止tg_bot - . "$CRASHDIR"/menus/bot_tg_service.sh && bot_tg_stop - #多种方式结束进程 - if [ -f "$TMPDIR/shellcrash.pid" ];then - kill -TERM "$(cat "$TMPDIR/shellcrash.pid")" 2>/dev/null - rm -f "$TMPDIR/shellcrash.pid" - stop_firewall - elif [ "$USER" = "root" ] && grep -q 'systemd' /proc/1/comm; then - systemctl stop shellcrash.service >/dev/null 2>&1 - elif [ -f /etc/rc.common ] && grep -q 'procd' /proc/1/comm; then - /etc/init.d/shellcrash stop >/dev/null 2>&1 - elif grep -q 's6' /proc/1/comm; then - /command/s6-svc -d /run/service/shellcrash - stop_firewall - elif rc-status -r >/dev/null 2>&1; then - rc-service shellcrash stop >/dev/null 2>&1 - else - stop_firewall - fi - killall CrashCore 2>/dev/null - #清理缓存目录 - rm -rf "$TMPDIR"/CrashCore - ;; -restart) - $0 stop - $0 start - ;; -init) - . "$CRASHDIR"/starts/general_init.sh - ;; -daemon) - if [ -f $TMPDIR/crash_start_time ]; then + start) + [ -n "$(pidof CrashCore)" ] && $0 stop #禁止多实例 + stop_firewall #清理路由策略 + rm -f "$CRASHDIR"/\.start_error #移除自启失败标记 + #使用不同方式启动服务 + if [ "$firewall_area" = "5" ]; then #主旁转发 + . "$CRASHDIR"/starts/fw_start.sh + elif [ "$start_old" = "ON" ]; then + start_l + elif [ -f /etc/rc.common ] && grep -q 'procd' /proc/1/comm; then + /etc/init.d/shellcrash start + elif [ "$USER" = "root" ] && grep -q 'systemd' /proc/1/comm; then + FragmentPath=$(systemctl show -p FragmentPath shellcrash | sed 's/FragmentPath=//') + [ -f "$FragmentPath" ] && { + sed -i "s#^ExecStart=.*#ExecStart=$COMMAND >/dev/null#" "$FragmentPath" + systemctl daemon-reload + } + systemctl start shellcrash.service || . "$CRASHDIR"/starts/start_error.sh + elif grep -q 's6' /proc/1/comm; then + bfstart && /command/s6-svc -u /run/service/shellcrash && { + [ ! -f "$CRASHDIR"/.dis_startup ] && touch /etc/s6-overlay/s6-rc.d/user/contents.d/afstart + afstart & + } + elif rc-status -r >/dev/null 2>&1; then + rc-service shellcrash stop >/dev/null 2>&1 + rc-service shellcrash start + else + start_l + fi + ;; + stop) + logger ShellCrash服务即将关闭...... + [ -n "$(pidof CrashCore)" ] && web_save #保存面板配置 + #清理定时任务 + cronload | grep -vE '^$|start_legacy_wd.sh|运行时每' >"$TMPDIR"/cron_tmp + cronadd "$TMPDIR"/cron_tmp + rm -f "$TMPDIR"/cron_tmp + #停止tg_bot + . "$CRASHDIR"/menus/bot_tg_service.sh && bot_tg_stop + #多种方式结束进程 + if [ -f "$TMPDIR/shellcrash.pid" ]; then + kill -TERM "$(cat "$TMPDIR/shellcrash.pid")" 2>/dev/null + rm -f "$TMPDIR/shellcrash.pid" + stop_firewall + elif [ "$USER" = "root" ] && grep -q 'systemd' /proc/1/comm; then + systemctl stop shellcrash.service >/dev/null 2>&1 + elif [ -f /etc/rc.common ] && grep -q 'procd' /proc/1/comm; then + /etc/init.d/shellcrash stop >/dev/null 2>&1 + elif grep -q 's6' /proc/1/comm; then + /command/s6-svc -d /run/service/shellcrash + stop_firewall + elif rc-status -r >/dev/null 2>&1; then + rc-service shellcrash stop >/dev/null 2>&1 + else + stop_firewall + fi + killall CrashCore 2>/dev/null + #清理缓存目录 + rm -rf "$TMPDIR"/CrashCore + ;; + restart) + $0 stop $0 start - else - sleep 60 && touch $TMPDIR/crash_start_time - fi - ;; -debug) - [ -n "$(pidof CrashCore)" ] && $0 stop >/dev/null #禁止多实例 - stop_firewall >/dev/null #清理路由策略 - bfstart - if [ -n "$2" ]; then - if echo "$crashcore" | grep -q 'singbox'; then - sed -i "s/\"level\": \"info\"/\"level\": \"$2\"/" "$TMPDIR"/jsons/log.json 2>/dev/null + ;; + init) + . "$CRASHDIR"/starts/general_init.sh + ;; + daemon) + if [ -f $TMPDIR/crash_start_time ]; then + $0 start + else + sleep 60 && touch $TMPDIR/crash_start_time + fi + ;; + debug) + [ -n "$(pidof CrashCore)" ] && $0 stop >/dev/null #禁止多实例 + stop_firewall >/dev/null #清理路由策略 + bfstart + if [ -n "$2" ]; then + if echo "$crashcore" | grep -q 'singbox'; then + sed -i "s/\"level\": \"info\"/\"level\": \"$2\"/" "$TMPDIR"/jsons/log.json 2>/dev/null + else + sed -i "s/log-level: info/log-level: $2/" "$TMPDIR"/config.yaml + fi + [ "$3" = flash ] && dir="$CRASHDIR" || dir="$TMPDIR" + $COMMAND >"$dir"/debug.log 2>&1 & + sleep 2 + logger "已运行debug模式!如需停止,请使用重启/停止服务功能!" 33 else - sed -i "s/log-level: info/log-level: $2/" "$TMPDIR"/config.yaml + $COMMAND >/dev/null 2>&1 & fi - [ "$3" = flash ] && dir="$CRASHDIR" || dir="$TMPDIR" - $COMMAND >"$dir"/debug.log 2>&1 & - sleep 2 - logger "已运行debug模式!如需停止,请使用重启/停止服务功能!" 33 - else - $COMMAND >/dev/null 2>&1 & - fi - afstart - ;; -*) - "$1" "$2" "$3" "$4" "$5" "$6" "$7" - ;; + afstart + ;; + *) + "$1" "$2" "$3" "$4" "$5" "$6" "$7" + ;; esac diff --git a/scripts/starts/afstart.sh b/scripts/starts/afstart.sh index d798a5179..cbd789dbe 100644 --- a/scripts/starts/afstart.sh +++ b/scripts/starts/afstart.sh @@ -3,9 +3,9 @@ #初始化目录 [ -z "$CRASHDIR" ] && CRASHDIR=$( - cd $(dirname $0) - cd .. - pwd + cd $(dirname $0) + cd .. + pwd ) . "$CRASHDIR"/libs/get_config.sh #加载工具 @@ -16,45 +16,43 @@ [ -z "$firewall_area" ] && firewall_area=1 #延迟启动 [ ! -f "$TMPDIR"/crash_start_time ] && [ -n "$start_delay" ] && [ "$start_delay" -gt 0 ] && { - logger "ShellCrash将延迟$start_delay秒启动" 31 - sleep "$start_delay" + logger "ShellCrash将延迟$start_delay秒启动" 31 + sleep "$start_delay" } #设置循环检测面板端口以判定服务启动是否成功 . "$CRASHDIR"/libs/start_wait.sh if [ -n "$test" -o -n "$(pidof CrashCore)" ]; then - [ "$start_old" = "ON" ] && [ ! -L "$TMPDIR"/CrashCore ] && rm -f "$TMPDIR"/CrashCore #删除缓存目录内核文件 - . "$CRASHDIR"/starts/fw_start.sh #配置防火墙流量劫持 - date +%s >"$TMPDIR"/crash_start_time #标记启动时间 - #还原面板配置 - [ -s "$CRASHDIR"/configs/web_save ] && { - . "$CRASHDIR"/libs/web_restore.sh - web_restore >/dev/null 2>&1 - } - #推送日志 - { - sleep 5 - logger ShellCrash服务已启动! - } & - ckcmd mtd_storage.sh && mtd_storage.sh save >/dev/null 2>&1 #Padavan保存/etc/storage - #加载定时任务 - cronload | grep -v '^$' >"$TMPDIR"/cron_tmp - [ -s "$TASKCFGDIR"/cron ] && cat "$TASKCFGDIR"/cron >>"$TMPDIR"/cron_tmp - [ -s "$TASKCFGDIR"/running ] && cat "$TASKCFGDIR"/running >>"$TMPDIR"/cron_tmp - [ "$bot_tg_service" = ON ] && echo "* * * * * /bin/sh $CRASHDIR/starts/start_legacy_wd.sh bot_tg #ShellCrash-TG_BOT守护进程" >>"$TMPDIR"/cron_tmp - [ "$start_old" = ON ] && echo "* * * * * /bin/sh $CRASHDIR/starts/start_legacy_wd.sh shellcrash #ShellCrash保守模式守护进程" >>"$TMPDIR"/cron_tmp - awk '!x[$0]++' "$TMPDIR"/cron_tmp >"$TMPDIR"/cron_tmp2 #删除重复行 - cronadd "$TMPDIR"/cron_tmp2 - rm -f "$TMPDIR"/cron_tmp "$TMPDIR"/cron_tmp2 - #加载条件任务 - [ -s "$TASKCFGDIR"/afstart ] && { . "$TASKCFGDIR"/afstart; } & - [ -s "$TASKCFGDIR"/affirewall -a -s /etc/init.d/firewall -a ! -f /etc/init.d/firewall.bak ] && { - #注入防火墙 - line=$(grep -En "fw.* restart" /etc/init.d/firewall | cut -d ":" -f 1) - sed -i.bak "${line}a\\. $TASKCFGDIR/affirewall" /etc/init.d/firewall - line=$(grep -En "fw.* start" /etc/init.d/firewall | cut -d ":" -f 1) - sed -i "${line}a\\. $TASKCFGDIR/affirewall" /etc/init.d/firewall - } & - exit 0 + [ "$start_old" = "ON" ] && [ ! -L "$TMPDIR"/CrashCore ] && rm -f "$TMPDIR"/CrashCore #删除缓存目录内核文件 + . "$CRASHDIR"/starts/fw_start.sh #配置防火墙流量劫持 + date +%s >"$TMPDIR"/crash_start_time #标记启动时间 + #推送日志 + { + sleep 5 + logger ShellCrash服务已启动! + } & + ckcmd mtd_storage.sh && mtd_storage.sh save >/dev/null 2>&1 #Padavan保存/etc/storage + #加载定时任务 + #清理旧版守护残条(/bin/ash),重新生成 /bin/sh 版避免堆积 + [ -f "$TASKCFGDIR"/cron ] && sed -i '/start_legacy_wd\.sh/d;/bot_tg\.sh/d' "$TASKCFGDIR"/cron 2>/dev/null + [ -f "$TASKCFGDIR"/running ] && sed -i '/start_legacy_wd\.sh/d;/bot_tg\.sh/d' "$TASKCFGDIR"/running 2>/dev/null + cronload | grep -vE '^$|start_legacy_wd\.sh|bot_tg\.sh' >"$TMPDIR"/cron_tmp + [ -s "$TASKCFGDIR"/cron ] && cat "$TASKCFGDIR"/cron >>"$TMPDIR"/cron_tmp + [ -s "$TASKCFGDIR"/running ] && cat "$TASKCFGDIR"/running >>"$TMPDIR"/cron_tmp + [ "$bot_tg_service" = ON ] && echo "* * * * * /bin/sh $CRASHDIR/starts/start_legacy_wd.sh bot_tg #ShellCrash-TG_BOT守护进程" >>"$TMPDIR"/cron_tmp + [ "$start_old" = ON ] && echo "* * * * * /bin/sh $CRASHDIR/starts/start_legacy_wd.sh shellcrash #ShellCrash保守模式守护进程" >>"$TMPDIR"/cron_tmp + awk '!x[$0]++' "$TMPDIR"/cron_tmp >"$TMPDIR"/cron_tmp2 #删除重复行 + cronadd "$TMPDIR"/cron_tmp2 + rm -f "$TMPDIR"/cron_tmp "$TMPDIR"/cron_tmp2 + #加载条件任务 + [ -s "$TASKCFGDIR"/afstart ] && { . "$TASKCFGDIR"/afstart; } & + [ -s "$TASKCFGDIR"/affirewall -a -s /etc/init.d/firewall -a ! -f /etc/init.d/firewall.bak ] && { + #注入防火墙 + line=$(grep -En "fw.* restart" /etc/init.d/firewall | cut -d ":" -f 1) + sed -i.bak "${line}a\\. $TASKCFGDIR/affirewall" /etc/init.d/firewall + line=$(grep -En "fw.* start" /etc/init.d/firewall | cut -d ":" -f 1) + sed -i "${line}a\\. $TASKCFGDIR/affirewall" /etc/init.d/firewall + } & + exit 0 else - . "$CRASHDIR"/starts/start_error.sh + . "$CRASHDIR"/starts/start_error.sh fi diff --git a/scripts/starts/bfstart.sh b/scripts/starts/bfstart.sh index ce8450f85..780833358 100644 --- a/scripts/starts/bfstart.sh +++ b/scripts/starts/bfstart.sh @@ -2,7 +2,11 @@ # Copyright (C) Juewuy #初始化目录 -[ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd) +[ -z "$CRASHDIR" ] && CRASHDIR=$( + cd $(dirname $0) + cd .. + pwd +) . "$CRASHDIR"/libs/get_config.sh [ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1 [ ! -d "$TMPDIR" ] && mkdir -p "$TMPDIR" @@ -73,7 +77,6 @@ EOF [ "$?" = 0 ] && rm -rf "$TMPDIR"/shellcrash_pac || mv -f "$TMPDIR"/shellcrash_pac "$BINDIR"/ui/pac } - #检测网络连接 [ "$network_check" != "OFF" ] && [ ! -f "$TMPDIR"/crash_start_time ] && ckcmd ping && . "$CRASHDIR"/starts/check_network.sh && check_network [ ! -d "$BINDIR"/ui ] && mkdir -p "$BINDIR"/ui @@ -104,19 +107,28 @@ catpac #生成pac文件 if echo "$crashcore" | grep -q 'singbox'; then . "$CRASHDIR"/starts/singbox_check.sh && singbox_check [ -d "$TMPDIR"/jsons ] && rm -rf "$TMPDIR"/jsons/* || mkdir -p "$TMPDIR"/jsons #准备目录 - if [ "$disoverride" != "1" ];then + if [ "$disoverride" != "1" ]; then . "$CRASHDIR"/starts/singbox_modify.sh && modify_json else ln -sf "$core_config" "$TMPDIR"/jsons/config.json fi else . "$CRASHDIR"/starts/clash_check.sh && clash_check - if [ "$disoverride" != "1" ];then + if [ "$disoverride" != "1" ]; then . "$CRASHDIR"/starts/clash_modify.sh && modify_yaml else ln -sf "$core_config" "$TMPDIR"/config.yaml fi fi +#恢复 cache.db 到 tmpfs(内核启动前);tmpfs 已有则跳过,避免覆盖更新的 +. "$CRASHDIR"/libs/web_restore.sh && web_restore +#mihomo 路径不可配(-d $BINDIR),软链到 tmpfs;小内存模式跳过防自指 +if ! echo "$crashcore" | grep -q 'singbox'; then + [ "$BINDIR" != "$TMPDIR" ] && { + rm -f "$BINDIR"/cache.db + ln -sf "$TMPDIR"/cache.db "$BINDIR"/cache.db + } +fi #检查下载cnip绕过相关文件 [ "$cn_ip_route" = "ON" ] && [ "$dns_mod" != "fake-ip" ] && { [ "$firewall_mod" = nftables ] || ckcmd ipset && { diff --git a/scripts/starts/clash_modify.sh b/scripts/starts/clash_modify.sh index 8e539fa7e..0748476fe 100644 --- a/scripts/starts/clash_modify.sh +++ b/scripts/starts/clash_modify.sh @@ -18,7 +18,7 @@ prepare_clash_base_config() { #ecs优化 [ "$ecs_subnet" = ON ] && { . "$CRASHDIR"/libs/get_ecsip.sh - if [ -n "$ecs_address" ];then + if [ -n "$ecs_address" ]; then dns_fallback=$(echo "$dns_fallback, " | sed "s|, |#ecs-override=true\&ecs=$ecs_address, |g" | sed 's|, $||') else logger "自动获取ecs网段失败!" @@ -89,6 +89,9 @@ $sniffer_set $find_process routing-mark: $routing_mark unified-delay: true +profile: + store-selected: true + store-fake-ip: true EOF #读取本机hosts并生成配置文件 if [ "$hosts_opt" != "OFF" ] && [ -z "$(grep -aE '^hosts:' "$CRASHDIR"/yamls/user.yaml 2>/dev/null)" ]; then @@ -133,7 +136,7 @@ split_and_customize_yaml_parts() { space_name=$(grep -aE '^ *- \{?name: ' "$TMPDIR"/proxy-groups.yaml | head -n 1 | grep -oE '^ *') space_proxy="$space_name " #合并自定义策略组到proxy-groups.yaml - cat "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | sed "s/#.*//g" | sed '1i\ #自定义策略组开始' | sed '$a\ #自定义策略组结束' | sed "s/^ */${space_name} /g" | sed "s/^ *- /${space_proxy}- /g" | sed "s/^ *- name: /${space_name}- name: /g" | sed "s/^ *- {name: /${space_name}- {name: /g" >"$TMPDIR"/proxy-groups_add.yaml + cat "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | sed "s/#.*//g" | sed '1i\ #自定义策略组开始' | sed '$a\ #自定义策略组结束' | sed "s/^ */${space_name} /g" | sed "s/^ *- /${space_proxy}- /g" | sed "s/^ *- name: /${space_name}- name: /g" | sed "s/^ *- {name: /${space_name}- {name: /g" >"$TMPDIR"/proxy-groups_add.yaml cat "$TMPDIR"/proxy-groups.yaml >>"$TMPDIR"/proxy-groups_add.yaml mv -f "$TMPDIR"/proxy-groups_add.yaml "$TMPDIR"/proxy-groups.yaml oldIFS="$IFS" diff --git a/scripts/starts/singbox_modify.sh b/scripts/starts/singbox_modify.sh index 3a9180cdb..4253adadb 100644 --- a/scripts/starts/singbox_modify.sh +++ b/scripts/starts/singbox_modify.sh @@ -1,7 +1,7 @@ #!/bin/sh # Copyright (C) Juewuy - #修饰singbox配置文件 +#修饰singbox配置文件 parse_singbox_dns() { #dns转换 first_dns=$(echo "$1" | cut -d',' -f1 | cut -d' ' -f1) type="" @@ -32,9 +32,9 @@ parse_singbox_dns() { #dns转换 esac if [ -z "$port" ]; then case "$type" in - udp|tcp) port=53 ;; - doh|https) port=443 ;; - dot|tls) port=853 ;; + udp | tcp) port=53 ;; + doh | https) port=443 ;; + dot | tls) port=853 ;; *) port=53 ;; esac fi @@ -159,7 +159,7 @@ generate_dns_related_jsons() { } } EOF -} + } cat >"$TMPDIR"/jsons/dns.json <"$TMPDIR"/jsons/add_route.json <