#!/bin/sh # Copyright (C) Juewuy [ -n "$__IS_MODULE_8_TOOLS_LOADED" ] && return __IS_MODULE_8_TOOLS_LOADED=1 . "$CRASHDIR"/libs/logger.sh . "$CRASHDIR"/libs/web_get_bin.sh stop_iptables() { iptables -w -t nat -D PREROUTING -p tcp -m multiport --dports "$ssh_port" -j REDIRECT --to-ports 22 >/dev/null 2>&1 ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports "$ssh_port" -j REDIRECT --to-ports 22 >/dev/null 2>&1 } ssh_tools() { while true; do [ -n "$(cat /etc/firewall.user 2>&1 | grep '启用外网访问SSH服务')" ] && ssh_ol=禁止 || ssh_ol=开启 [ -z "$ssh_port" ] && ssh_port=10022 comp_box "\033[33m此功能仅针对使用Openwrt系统的设备生效,且不依赖服务\033[0m" \ "\033[31m本功能不支持红米AX6S等镜像化系统设备,请勿尝试!\033[0m" btm_box "1) \033[32m修改\033[0m外网访问端口:\033[36m$ssh_port\033[0m" \ "2) \033[32m修改\033[0mSSH访问密码(请连续输入2次后回车)" \ "3) \033[33m$ssh_ol\033[0m外网访问SSH" \ "" \ "0) 返回上级菜单 \033[0m" read -r -p "请输入对应标号> " num case "$num" in "" | 0) break ;; 1) line_break read -r -p "请输入端口号(1000-65535)> " num if [ -z "$num" ]; then errornum elif [ "$num" -gt 65535 ] || [ "$num" -le 999 ]; then msg_alert "\033[31m输入错误!请输入正确的数值(1000-65535)!\033[0m" elif [ -n "$(netstat -ntul | grep :$num)" ]; then msg_alert "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" else ssh_port=$num setconfig ssh_port "$ssh_port" sed -i "/启用外网访问SSH服务/d" /etc/firewall.user stop_iptables msg_alert "\033[32m设置成功,请重新开启外网访问SSH功能!" fi ;; 2) passwd sleep 1 ;; 3) if [ "$ssh_ol" = "开启" ]; then iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports "$ssh_port" -j REDIRECT --to-ports 22 [ -n "$(ckcmd ip6tables)" ] && ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports "$ssh_port" -j REDIRECT --to-ports 22 echo "iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user [ -n "$(ckcmd ip6tables)" ] && echo "ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user comp_box "已开启外网访问SSH功能!" else sed -i "/启用外网访问SSH服务/d" /etc/firewall.user stop_iptables comp_box "已禁止外网访问SSH!" fi break ;; *) errornum ;; esac done } # 工具与优化 tools() { while true; do # 获取设置默认显示 grep -qE "^\s*[^#].*otapredownload" /etc/crontabs/root >/dev/null 2>&1 && mi_update=禁用 || mi_update=启用 [ "$mi_mi_autoSSH" = "已配置" ] && mi_mi_autoSSH_type=32m已配置 || mi_mi_autoSSH_type=31m未配置 [ -f "$CRASHDIR"/tools/tun.ko ] && mi_tunfix=32mON || mi_tunfix=31mOFF comp_box "\033[30;47m工具与优化\033[0m" \ "" \ "\033[33m本页工具可能无法兼容全部Linux设备,请酌情使用!\033[0m" \ "磁盘占用/所在目录:" \ "$(du -sh "$CRASHDIR")" content_line "1) ShellCrash\033[33m测试菜单\033[0m" content_line "2) ShellCrash\033[32m新手引导\033[0m" content_line "3) \033[36m日志及推送工具\033[0m" [ -f /etc/firewall.user ] && content_line "4) \033[32m配置\033[0m外网访问SSH" [ -x /usr/sbin/otapredownload ] && content_line "5) \033[33m$mi_update\033[0m小米系统自动更新" [ "$systype" = "mi_snapshot" ] && content_line "6) 小米设备软固化SSH ———— \033[$mi_mi_autoSSH_type \033[0m" [ "$systype" = "mi_snapshot" ] && content_line "8) 小米设备Tun模块修复 ———— \033[$mi_tunfix \033[0m" btm_box "" \ "0) 返回上级菜单" read -r -p "请输入对应标号> " num case "$num" in "" | 0) break ;; 1) testcommand ;; 2) . "$CRASHDIR"/menus/userguide.sh && userguide break ;; 3) log_pusher ;; 4) ssh_tools sleep 1 ;; 5) if [ -x /usr/sbin/otapredownload ]; then if [ "$mi_update" = "禁用" ]; then grep -q "otapredownload" /etc/crontabs/root && sed -i "/^[^\#]*otapredownload/ s/^/#/" /etc/crontabs/root || echo "#15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root else grep -q "otapredownload" /etc/crontabs/root && sed -i "/^\s*#.*otapredownload/ s/^\s*#//" /etc/crontabs/root || echo "15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root fi msg_alert "已\033[33m$mi_update\033[0m小米路由器的自动更新,如未生效,请在官方APP中同步设置!" fi ;; 6) if [ "$systype" = "mi_snapshot" ]; then mi_autoSSH else msg_alert "不支持的设备!" fi ;; 7) line_break separator_line "=" if [ ! -f "$CRASHDIR"/tools/ShellDDNS.sh ]; then content_line "正在获取在线脚本......" get_bin "$TMPDIR"/ShellDDNS.sh tools/ShellDDNS.sh if [ "$?" = "0" ]; then mv -f "$TMPDIR"/ShellDDNS.sh "$CRASHDIR"/tools/ShellDDNS.sh . "$CRASHDIR"/tools/ShellDDNS.sh else content_line "\033[31m文件下载失败!\033[0m" separator_line "=" fi else . "$CRASHDIR"/tools/ShellDDNS.sh fi sleep 1 ;; 8) if [ -f "$CRASHDIR"/tools/tun.ko ]; then comp_box "是否禁用此功能并移除相关补丁?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res [ "$res" = 1 ] && { rm -rf "$CRASHDIR"/tools/tun.ko msg_alert "\033[33m补丁文件已移除,请立即重启设备以防止出错!\033[0m" } elif ckcmd modinfo && [ -z "$(modinfo tun)" ]; then comp_box "\033[33m本功能需要修改系统文件,不保证没有任何风险!\033[0m" \ "\033[33m本功能采集的Tun模块并不一定适用于你的设备!\033[0m" btm_box "1) 我已知晓,出现问题会自行承担!" \ "0) 返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then line_break separator_line "=" content_line "正在连接服务器获取Tun模块补丁文件......" get_bin "$TMPDIR"/tun.ko bin/fix/tun.ko if [ "$?" = "0" ]; then mv -f "$TMPDIR"/tun.ko "$CRASHDIR"/tools/tun.ko && /data/shellcrash_init.sh tunfix && content_line "\033[32m设置成功!请重启服务!\033[0m" else content_line "\033[31m文件下载失败,请重试!\033[0m" fi separator_line "=" else continue fi else msg_alert "\033[31m当前设备无需设置,请勿尝试!\033[0m" fi ;; *) errornum ;; esac done } mi_autoSSH() { comp_box "\033[33m本功能使用软件命令进行固化不保证100%成功!\033[0m" \ "\033[33m如有问题请加群反馈:\033[36;4mhttps://t.me/ShellClash\033[0m" btm_box "请输入需要还原的SSH密码(不影响当前密码)" \ "(回车可跳过)" read -r -p "请输入> " mi_mi_autoSSH_pwd mi_mi_autoSSH=已配置 cp -f /etc/dropbear/dropbear_rsa_host_key "$CRASHDIR"/configs/dropbear_rsa_host_key 2>/dev/null cp -f /etc/dropbear/authorized_keys "$CRASHDIR"/configs/authorized_keys 2>/dev/null ckcmd nvram && { nvram set ssh_en=1 nvram set telnet_en=1 nvram set uart_en=1 nvram set boot_wait=on nvram commit } setconfig mi_mi_autoSSH $mi_mi_autoSSH setconfig mi_mi_autoSSH_pwd "$mi_mi_autoSSH_pwd" msg_alert "\033[32m设置成功!\033[0m" } # 日志菜单 log_pusher() { while true; do [ -n "$push_TG" ] && stat_TG=32mON || stat_TG=33mOFF [ -n "$push_Deer" ] && stat_Deer=32mON || stat_Deer=33mOFF [ -n "$push_bark" ] && stat_bark=32mON || stat_bark=33mOFF [ -n "$push_Po" ] && stat_Po=32mON || stat_Po=33mOFF [ -n "$push_PP" ] && stat_PP=32mON || stat_PP=33mOFF [ -n "$push_SynoChat" ] && stat_SynoChat=32mON || stat_SynoChat=33mOFF [ -n "$push_Gotify" ] && stat_Gotify=32mON || stat_Gotify=33mOFF [ "$task_push" = 1 ] && stat_task=32mON || stat_task=33mOFF [ -n "$device_name" ] && device_s=32m$device_name || device_s=33m未设置 comp_box "1) Telegram推送 ——\033[$stat_TG\033[0m" \ "2) PushDeer推送 ——\033[$stat_Deer\033[0m" \ "3) Bark推送-IOS ——\033[$stat_bark\033[0m" \ "4) Passover推送 ——\033[$stat_Po\033[0m" \ "5) PushPlus推送 ——\033[$stat_PP\033[0m" \ "6) SynoChat推送 ——\033[$stat_SynoChat\033[0m" \ "7) Gotify推送 ——\033[$stat_Gotify\033[0m" \ "" \ "a) 查看\033[36m运行日志\033[0m" \ "b) 推送任务日志 ——\033[$stat_task\033[0m" \ "c) 设置设备名称 ——\033[$device_s\033[0m" \ "d) 清空日志文件" \ "" \ "0) 返回上级菜单" read -r -p "请输入对应标号> " num case "$num" in "" | 0) break ;; 1) if [ -n "$push_TG" ]; then comp_box "是否确认关闭TG日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_TG= chat_ID= setconfig push_TG setconfig chat_ID else continue fi else # echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" . "$CRASHDIR"/menus/bot_tg_bind.sh chose_bot() { comp_box "1) 使用公共机器人 ——不依赖内核服务" \ "2) 使用私人机器人 ——需要额外申请" \ "" \ "0) 返回上级菜单" read -r -p "请输入对应标号> " num case "$num" in 0) return 0 ;; 1) public_bot set_bot && tg_push_token || chose_bot ;; 2) private_bot set_bot && tg_push_token || chose_bot ;; *) errornum ;; esac } chose_bot fi ;; 2) if [ -n "$push_Deer" ]; then comp_box "是否确认关闭PushDeer日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_Deer= setconfig push_Deer else continue fi else # echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" comp_box "1. 请先前往 \033[32;4mhttp://www.pushdeer.com/official.html\033[0m 扫码安装快应用或下载APP" \ "2. 打开快应用/APP,并完成登陆" \ "3. \033[33m切换到「设备」标签页,点击右上角的加号,注册当前设备\033[0m" \ "4. \033[36m切换到「秘钥」标签页,点击右上角的加号,创建一个秘钥,并复制\033[0m" btm_box "\033[36m请直接输入你复制的秘钥\033[0m" \ "或输入 0 返回上级菜单" read -r -p "请输入> " url if [ "$url" = 0 ]; then continue elif [ -n "$url" ]; then push_Deer=$url setconfig push_Deer "$url" logger "已完成PushDeer日志推送设置!" 32 else msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi fi ;; 3) if [ -n "$push_bark" ]; then comp_box "是否确认关闭Bark日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_bark= bark_param= setconfig push_bark setconfig bark_param else continue fi else # echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" comp_box "\033[33mBark推送仅支持IOS系统,其他平台请使用其他推送方式!\033[0m" \ "\033[32m请安装Bark-IOS客户端,并在客户端中找到专属推送链接\033[0m" btm_box "\033[36m请直接输入你的Bark推送链接\033[0m" \ "或输入 0 返回上级菜单" read -r -p "请输入> " url if [ "$url" = 0 ]; then continue elif [ -n "$url" ]; then push_bark=$url setconfig push_bark "$url" logger "已完成Bark日志推送设置!" 32 else msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi fi ;; 4) if [ -n "$push_Po" ]; then comp_box "是否确认关闭Pushover日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_Po= push_Po_key= setconfig push_Po setconfig push_Po_key else continue fi else # echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" comp_box "请先通过 \033[32;4mhttps://pushover.net/\033[0m 注册账号并获取\033[36mUser Key\033[0m" \ "" \ "\033[36m请直接请输入你的User Key\033[0m" \ "或输入 0 返回上级菜单" read -r -p "请输入> " key if [ "$key" = 0 ]; then continue elif [ -n "$key" ]; then comp_box "\033[33m请检查注册邮箱,完成账户验证\033[0m" btm_box "1) 我已经验证完成" \ "0) 返回上级菜单" read -r -p "我已经验证完成(1/0)> " res if [ "$res" = 1 ]; then comp_box "请通过 \033[32;4mhttps://pushover.net/apps/build\033[0m 生成\033[36mAPI Token\033[0m" read -r -p "请输入你的API Token> " Token if [ -n "$Token" ]; then push_Po=$Token push_Po_key=$key setconfig push_Po "$Token" setconfig push_Po_key "$key" logger "已完成Passover日志推送设置!" 32 else msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi else continue fi else msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi fi ;; 5) if [ -n "$push_PP" ]; then comp_box "是否确认关闭PushPlus日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_PP= setconfig push_PP else continue fi else # echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" comp_box "请先通过 \033[32;4mhttps://www.pushplus.plus/push1.html\033[0m 注册账号并获取\033[36mtoken\033[0m" btm_box "\033[36m请直接输入你的token\033[0m" \ "或输入 0 返回上级菜单" read -r -p "请输入> " Token if [ "$Token" = 0 ]; then continue elif [ -n "$Token" ]; then push_PP=$Token setconfig push_PP "$Token" logger "已完成PushPlus日志推送设置!" 32 else msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi fi ;; 6) if [ -n "$push_SynoChat" ]; then comp_box "是否确认关闭SynoChat日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_SynoChat= setconfig push_SynoChat else continue fi else line_break read -r -p "请输入你的Synology DSM主页地址> " URL read -r -p "请输入你的Synology Chat Token> " TOKEN comp_box '请通过"你的群晖地址/webapi/entry.cgi?api=SYNO.Chat.External&method=user_list&version=2&token=你的TOKEN"获取user_id' read -r -p "请输入你的user_id> " USERID if [ -n "$URL" ]; then push_SynoChat=$USERID setconfig push_SynoChat "$USERID" setconfig push_ChatURL "$URL" setconfig push_ChatTOKEN "$TOKEN" setconfig push_ChatUSERID "$USERID" logger "已完成SynoChat日志推送设置!" 32 else setconfig push_ChatURL setconfig push_ChatTOKEN setconfig push_ChatUSERID push_SynoChat= setconfig push_SynoChat msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi fi ;; # 在menu.sh的case $num in代码块中添加 7) if [ -n "$push_Gotify" ]; then comp_box "是否确认关闭Gotify日志推送?" btm_box "1) 是" \ "0) 否,返回上级菜单" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then push_Gotify= setconfig push_Gotify else continue fi else comp_box "请先通过Gotify服务器获取推送URL" \ "格式示例: https://gotify.example.com/message?token=你的应用令牌" btm_box "\033[36m请直接你的Gotify推送URL\033[0m" \ "或输入 0 返回上级菜单" read -r -p "请输入> " url if [ "$url" = 0 ]; then continue elif [ -n "$url" ]; then push_Gotify=$url setconfig push_Gotify "$url" logger "已完成Gotify日志推送设置!" 32 else msg_alert "\033[31m输入错误,请重新输入!\033[0m" fi fi ;; a) if [ -s "$TMPDIR"/ShellCrash.log ]; then line_break echo "===========================================================" cat "$TMPDIR"/ShellCrash.log echo "===========================================================" exit else msg_alert "\033[31m未找到相关日志!\033[0m" fi ;; b) [ "$task_push" = 1 ] && task_push='' || task_push=1 setconfig task_push "$task_push" sleep 1 ;; c) comp_box "请直接输入本设备自定义推送名称" \ "或直接回车确认返回上级菜单" read -r -p "请输入> " device_name if [ -n "$device_name" ]; then setconfig device_name "$device_name" fi ;; d) rm -rf "$TMPDIR"/ShellCrash.log msg_alert "\033[33m运行日志及任务日志均已清空!\033[0m" ;; *) errornum ;; esac done } # 测试菜单 testcommand() { while true; do comp_box "\033[30;47m这里是测试命令菜单\033[0m" \ "\033[33m如遇问题尽量运行相应命令后截图提交issue或TG讨论组\033[0m" btm_box "1) Debug模式运行内核" \ "2) 查看系统DNS端口(:53)占用 " \ "3) 测试ssl加密(aes-128-gcm)跑分" \ "4) 查看ShellCrash相关路由规则" \ "5) 查看内核配置文件前40行" \ "6) 测试代理服务器连通性(google.tw)" \ "" \ "0) 返回上级目录" read -r -p "请输入对应数字> " num case "$num" in 0) break ;; 1) debug ;; 2) line_break echo "===========================================================" netstat -ntulp | grep 53 echo echo -e "可以使用\033[44m netstat -ntulp |grep xxx \033[0m来查询任意(xxx)端口" echo "===========================================================" ;; 3) line_break openssl speed -multi 4 -evp aes-128-gcm ;; 4) line_break if [ "$firewall_mod" = "nftables" ]; then nft list table inet shellcrash | sed '/set cn_ip {/,/}/d;/set cn_ip6 {/,/}/d;/^[[:space:]]*}/d' else [ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 -o "$vm_redir" = "ON" ] && { echo "----------------Redir+DNS---------------------" iptables -t nat -L PREROUTING --line-numbers iptables -t nat -L shellcrash_dns --line-numbers [ -n "$(echo $redir_mod | grep -E 'Redir|Mix')" ] && iptables -t nat -L shellcrash --line-numbers [ -n "$(echo "$redir_mod" | grep -E 'Tproxy|Mix|Tun')" ] && { echo "----------------Tun/Tproxy-------------------" iptables -t mangle -L PREROUTING --line-numbers iptables -t mangle -L shellcrash_mark --line-numbers } } [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && { echo "-------------OUTPUT-Redir+DNS----------------" iptables -t nat -L OUTPUT --line-numbers iptables -t nat -L shellcrash_dns_out --line-numbers [ -n "$(echo "$redir_mod" | grep -E 'Redir|Mix')" ] && iptables -t nat -L shellcrash_out --line-numbers [ -n "$(echo "$redir_mod" | grep -E 'Tproxy|Mix|Tun')" ] && { echo "------------OUTPUT-Tun/Tproxy---------------" iptables -t mangle -L OUTPUT --line-numbers iptables -t mangle -L shellcrash_mark_out --line-numbers } } [ "$ipv6_redir" = "ON" ] && { [ "$firewall_area" = 1 -o "$firewall_area" = 3 ] && { ip6tables -t nat -L >/dev/null 2>&1 && { echo "-------------IPV6-Redir+DNS-------------------" ip6tables -t nat -L PREROUTING --line-numbers ip6tables -t nat -L shellcrashv6_dns --line-numbers [ -n "$(echo "$redir_mod" | grep -E 'Redir|Mix')" ] && ip6tables -t nat -L shellcrashv6 --line-numbers } [ -n "$(echo "$redir_mod" | grep -E 'Tproxy|Mix|Tun')" ] && { echo "-------------IPV6-Tun/Tproxy------------------" ip6tables -t mangle -L PREROUTING --line-numbers ip6tables -t mangle -L shellcrashv6_mark --line-numbers } } } [ "$vm_redir" = "ON" ] && { echo "-------------vm-Redir-------------------" iptables -t nat -L shellcrash_vm --line-numbers iptables -t nat -L shellcrash_vm_dns --line-numbers } echo "----------------本机防火墙---------------------" iptables -L INPUT --line-numbers fi ;; 5) echo "$crashcore" | grep -q 'singbox' && config_path="$CRASHDIR"/jsons/config.json || config_path="$CRASHDIR"/yamls/config.yaml line_break sed -n '1,40p' "$config_path" ;; 6) comp_box "\033[33m注意:依赖curl(不支持wget),且测试结果不保证一定准确!\033[0m" delay=$( curl -kx ${authentication}@127.0.0.1:$mix_port -o /dev/null -s -w '%{time_starttransfer}' 'https://google.tw' & { sleep 3 kill $! >/dev/null 2>&1 & } ) >/dev/null 2>&1 delay=$(echo | awk "{print $delay*1000}") >/dev/null 2>&1 line_break separator_line "=" if [ $(echo ${#delay}) -gt 1 ]; then content_line "\033[32m连接成功!响应时间为:"$delay" ms\033[0m" else content_line "\033[31m连接超时!请重试或检查节点配置!\033[0m" fi separator_line "=" ;; *) errornum ;; esac done } debug() { echo "$crashcore" | grep -q 'singbox' && config_tmp="$TMPDIR"/jsons || config_tmp="$TMPDIR"/config.yaml comp_box "\033[36m注意:Debug运行均会停止原本的内核服务\033[0m" \ "后台运行日志地址:\033[32m$TMPDIR/debug.log\033[0m" \ "如长时间运行后台监测,日志等级推荐error!防止文件过大!" \ "你亦可通过:\033[33mcrash -s debug 'warning'\033[0m命令使用其他日志等级" content_line "1) 仅测试\033[32m$config_tmp\033[0m配置文件可用性" content_line "2) 前台运行\033[32m$config_tmp\033[0m配置文件,不配置防火墙劫持(\033[33m使用Ctrl+C手动停止\033[0m)" content_line "3) 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[31merror\033[0m" content_line "4) 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[32minfo\033[0m" content_line "5) 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[33mdebug\033[0m" content_line "6) 后台运行完整启动流程,并配置防火墙劫持,且将错误日志打印到闪存:\033[32m$CRASHDIR/debug.log\033[0m" content_line "" content_line "8) 后台运行完整启动流程,输出执行错误并查找上下文,之后关闭进程" [ -s "$TMPDIR"/jsons/inbounds.json ] && content_line "9) 将\033[32m$config_tmp\033[0m下json文件合并为$TMPDIR/debug.json" btm_box "" \ "0) 返回上级目录" read -r -p "请输入对应标号> " num case "$num" in 0) ;; 1) "$CRASHDIR"/start.sh stop "$CRASHDIR"/start.sh bfstart if echo "$crashcore" | grep -q 'singbox'; then "$TMPDIR"/CrashCore run -D "$BINDIR" -C "$TMPDIR"/jsons & { sleep 4 kill $! >/dev/null 2>&1 & } wait else "$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml fi rm -rf "$TMPDIR"/CrashCore line_break exit ;; 2) "$CRASHDIR"/start.sh stop "$CRASHDIR"/start.sh bfstart $COMMAND rm -rf "$TMPDIR"/CrashCore line_break exit ;; 3) "$CRASHDIR"/start.sh debug error main_menu ;; 4) "$CRASHDIR"/start.sh debug info main_menu ;; 5) "$CRASHDIR"/start.sh debug debug main_menu ;; 6) comp_box "频繁写入闪存会导致闪存寿命降低,如非遇到会导致设备死机或重启的bug,请勿使用此功能!" \ "是否确认启用此功能?" btm_box "1) 是" \ "0) 否" read -r -p "请输入对应标号> " res if [ "$res" = 1 ]; then "$CRASHDIR"/start.sh debug debug flash fi main_menu ;; 8) $0 -d main_menu ;; 9) . "$CRASHDIR"/libs/core_webget.sh && core_find && "$TMPDIR"/CrashCore merge "$TMPDIR"/debug.json -C "$TMPDIR"/jsons && line_break comp_box "\033[32m合并成功!\033[0m" [ "$TMPDIR" = "$BINDIR" ] && rm -rf "$TMPDIR"/CrashCore main_menu ;; *) errornum ;; esac }