diff --git a/README_CN.md b/README_CN.md index 0e9281c9..e1bc4b50 100644 --- a/README_CN.md +++ b/README_CN.md @@ -43,8 +43,8 @@ ShellCrash 旨在兼容绝大多数基于 Linux 内核的网络设备: ## :hammer_and_wrench: 安装指南 -> **提示** -> 若遇到连接失败或与SSL相关问题,请尝试切换至其他安装镜站。 +> [!TIP] +> 若遇到连接失败或SSL相关问题,请尝试切换至其他安装镜像站。 ### 前置条件 1. 确保设备已开启 **SSH** 并获得 **Root 权限**(带图形介面的 Linux 系统可直接使用终端)。 @@ -52,9 +52,11 @@ ShellCrash 旨在兼容绝大多数基于 Linux 内核的网络设备: ### :penguin: 标准 Linux 设备安装 +> [!IMPORTANT] +> 请以 root 用户进行安装。 + > 使用 wget 安装(jsDelivr CDN 源) ```sh -sudo -i # 切换至root用户,若需密码,请输入 export url='https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@master' \ && wget -q --no-check-certificate -O /tmp/install.sh $url/install.sh \ && bash /tmp/install.sh \ @@ -64,7 +66,6 @@ export url='https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@master' \ > 或使用 curl 安装(作者私人源) ```sh -sudo -i # 切换至root用户,若需密码,请输入 export url='https://gh.jwsc.eu.org/master' \ && bash -c "$(curl -kfsSl $url/install.sh)" \ && . /etc/profile &> /dev/null diff --git a/ShellCrash.tar.gz b/ShellCrash.tar.gz index 6e24154c..b9dcb111 100644 Binary files a/ShellCrash.tar.gz and b/ShellCrash.tar.gz differ diff --git a/bin/clashfm.tar.gz b/bin/clashfm.tar.gz index 6e24154c..b9dcb111 100644 Binary files a/bin/clashfm.tar.gz and b/bin/clashfm.tar.gz differ diff --git a/bin/version b/bin/version index 417d29e0..b67f4a93 100644 --- a/bin/version +++ b/bin/version @@ -1,4 +1,4 @@ meta_v=v1.19.17 singboxr_v=1.13.0-alpha.27 -versionsh=1.9.4beta1.1 +versionsh=1.9.4beta2 GeoIP_v=20251205 diff --git a/install.sh b/install.sh index ebcaff6c..74989653 100644 --- a/install.sh +++ b/install.sh @@ -1,16 +1,93 @@ #!/usr/bin/env bash # Copyright (C) Juewuy +# ================================= table format tools ================================= +# >>>>>>>>>>>>>> + +# set the total width of the menu +# (adjusting this number will automatically change the entire menu, including the separator lines) +# note: The number represents the number of columns that appear when the "||" appears on the right +TABLE_WIDTH=60 + +# define two extra-long template strings in advance +# (the length should be greater than the expected TABLE_WIDTH) +FULL_EQ="====================================================================================================" +FULL_DASH="- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " + +# function to print content lines +# (using cursor jump) +content_line() { + echo -e " ${1}\033[${TABLE_WIDTH}G||" +} + +# function to print sub content lines +# for printing accompanying instructions +sub_content_line() { + echo -e " ${1}\033[${TABLE_WIDTH}G||" + content_line +} + +# increase the spacing between the front +# and back forms to improve readability +double_line_break() { + printf "\n\n" +} + +# function to print separators +# (using string slicing) +# parameter $1: pass in "=" or "-" +separator_line() { + local separator_type="$1" + local output_line="" + local len=$((TABLE_WIDTH - 1)) + + if [ "$separator_type" == "=" ]; then + output_line="${FULL_EQ:0:$len}" + else + output_line="${FULL_DASH:0:$len}" + fi + + echo "${output_line}||" +} +# <<<<<<<<<<<<<< +# ================================= table format tools ================================= + +# =============================== display prompt message =============================== +# >>>>>>>>>>>>>> + +abort_install() { + double_line_break + separator_line "=" + content_line "安装已取消" + separator_line "=" + double_line_break + + exit 1 +} + +invalid_input_retry() { + double_line_break + separator_line "=" + content_line "\033[31m输入错误!\033[0m" + content_line "\033[31m请重新设置!\033[0m" + separator_line "=" + + sleep 1 +} + +# <<<<<<<<<<<<<< +# =============================== display prompt message =============================== + [ -z "$url" ] && url="https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@dev" type bash &>/dev/null && shtype=bash || shtype=sh -[ -n "$(echo -e | grep e)" ] && echo=echo || echo='echo -e' -echo "***********************************************" -echo "** 欢迎使用 **" -echo "** ShellCrash **" -echo "** by Juewuy **" -echo "***********************************************" -# Check available capacity +error_down() { + content_line "\033[33m请参考:\033[0m" + content_line "\033[33mgithub.com/juewuy/ShellCrash/blob/master/README_CN.md\033[0m" + content_line "\033[33m或使用其他安装源重新安装!\033[0m" +} + +# check available capacity dir_avail() { df -h >/dev/null 2>&1 && h="$2" df -P $h "${1:-.}" 2>/dev/null | awk 'NR==2 {print $4}' @@ -31,8 +108,18 @@ webget() { if curl --version >/dev/null 2>&1; then [ "$3" = "echooff" ] && progress='-s' || progress='-#' [ -z "$4" ] && redirect='-L' || redirect='' - result=$(curl -w %{http_code} --connect-timeout 5 $progress $redirect -ko $1 $2) - [ -n "$(echo $result | grep -e ^2)" ] && result="200" + result=$(curl -w %{http_code} --connect-timeout 5 "$progress" "$redirect" -ko "$1" "$2") + + # === original version === + # [ -n "$(echo $result | grep -e ^2)" ] && result="200" + + # === fixed version === + # strictly match the 200 status code to avoid 204 (empty content) + # or 202 being mistakenly interpreted as success + if [ "$result" = "200" ]; then + result="200" + fi + else if wget --version >/dev/null 2>&1; then [ "$3" = "echooff" ] && progress='-q' || progress='-q --show-progress' @@ -42,33 +129,26 @@ webget() { fi [ "$3" = "echoon" ] && progress='' [ "$3" = "echooff" ] && progress='-q' - wget $progress $redirect $certificate $timeout -O $1 $2 + wget "$progress" "$redirect" "$certificate" "$timeout" -O "$1" "$2" [ $? -eq 0 ] && result="200" fi } -error_down() { - $echo "请参考 \033[32mhttps://github.com/juewuy/ShellCrash/blob/master/README_CN.md" - $echo "\033[33m使用其他安装源重新安装!\033[0m" -} - # 安装及初始化 set_alias() { while true; do - echo "-----------------------------------------------" - $echo "\033[36m请选择一个别名,或使用自定义别名:\033[0m" - echo "-----------------------------------------------" - $echo " 1 【\033[32mcrash\033[0m】" - $echo " 2 【\033[32m sc \033[0m】" - $echo " 3 【\033[32m mm \033[0m】" - $echo " 0 退出安装" - echo "-----------------------------------------------" - read -p "请输入相应数字或自定义别名 > " res + double_line_break + separator_line "=" + content_line "\033[36m请选择一个别名\033[0m" + content_line "\033[36m或直接输入自定义别名\033[0m" + separator_line "-" + content_line "1) 【\033[32mcrash\033[0m】" + content_line "2) 【\033[32m sc \033[0m】" + content_line "3) 【\033[32m mm \033[0m】" + content_line "E) 退出安装" + separator_line "=" + read -p "请输入相应数字/自定义别名> " res case "$res" in - 0) - echo "安装已取消" - exit 1 - ;; 1) my_alias=crash ;; @@ -78,41 +158,62 @@ set_alias() { 3) my_alias=mm ;; + "E" | "e") + abort_install + ;; *) my_alias=$res ;; esac cmd=$(ckcmd "$my_alias" | grep 'menu.sh') ckcmd "$my_alias" && [ -z "$cmd" ] && { - $echo "\033[33m此别名和当前系统内置命令/别名冲突,请换一个!\033[0m" + double_line_break + separator_line "=" + content_line "该别名【\033[32m$my_alias\033[0m】和当前系统内置命令/别名\033[33m冲突\033[0m,请更换" + separator_line "=" + sleep 1 continue } - break + break 1 done } gettar() { - webget /tmp/ShellCrash.tar.gz "$url/ShellCrash.tar.gz" + webget /tmp/ShellCrash.tar.gz "$url/ShellCrash.tar.gz" >/dev/null 2>&1 if [ "$result" != "200" ]; then - $echo "\033[33m文件下载失败!\033[0m" + content_line "\033[31m下载失败!\033[0m" error_down + separator_line "=" + double_line_break exit 1 else - $CRASHDIR/start.sh stop 2>/dev/null + content_line "下载成功" + "$CRASHDIR"/start.sh stop 2>/dev/null # 解压 - echo "-----------------------------------------------" - echo "开始解压文件!" - mkdir -p $CRASHDIR >/dev/null - tar -zxf '/tmp/ShellCrash.tar.gz' -C $CRASHDIR/ || tar -zxf '/tmp/ShellCrash.tar.gz' --no-same-owner -C $CRASHDIR/ - if [ -s $CRASHDIR/init.sh ]; then + content_line "开始解压文件......" + mkdir -p "$CRASHDIR" >/dev/null + tar -zxf '/tmp/ShellCrash.tar.gz' -C "$CRASHDIR"/ || tar -zxf '/tmp/ShellCrash.tar.gz' --no-same-owner -C "$CRASHDIR"/ + if [ -s "$CRASHDIR"/init.sh ]; then + content_line "解压成功" + separator_line "=" set_alias . $CRASHDIR/init.sh >/dev/null - [ "$?" != 0 ] && $echo "\033[33m初始化失败,请尝试本地安装!\033[0m" && exit 1 + if [ $? != 0 ]; then + content_line "\033[31m初始化失败,请尝试本地安装!\033[0m" + separator_line "=" + double_line_break + + exit 1 + fi + else rm -rf /tmp/ShellCrash.tar.gz - $echo "\033[33m文件解压失败!\033[0m" + content_line "\033[31m解压失败!\033[0m" error_down + separator_line "=" + double_line_break + exit 1 fi fi @@ -120,62 +221,162 @@ gettar() { set_usb_dir() { while true; do - $echo "请选择安装目录" - du -hL /mnt | awk '{print " "NR" "$2" "$1}' - read -p "请输入相应数字 > " num - dir=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) - if [ -z "$dir" ]; then - $echo "\033[31m输入错误!请重新设置!\033[0m" - continue - fi - break 1 + double_line_break + separator_line "=" + content_line "请选择安装目录:" + separator_line "-" + + # original version + # du -hL /mnt | awk '{print " "NR" "$2" "$1}' + du -hL /mnt | + awk '{print NR") "$2" (已用空间:"$1")"}' | + while IFS= read -r line; do + content_line "$line" + done + + content_line "0) 返回上级菜单" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 0) + return 1 + ;; + *) + dir=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) + if [ -z "$dir" ]; then + invalid_input_retry + continue + fi + return 0 + ;; + esac done } set_asus_dir() { while true; do - echo -e "请选择U盘目录" - du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print " "NR" "$2" "$1}' - read -p "请输入相应数字 > " num - dir=$(du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print $2}' | sed -n "$num"p) - if [ ! -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ]; then - echo -e "\033[31m未找到下载大师自启文件:$dir/asusware.arm/etc/init.d/S50downloadmaster,请检查设置!\033[0m" - continue - fi - break 1 + double_line_break + separator_line "=" + content_line "请选择U盘目录:" + separator_line "-" + + # original version + # du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print " "NR" "$2" "$1}' + du -hL /tmp/mnt | + awk -F/ 'NF<=4 {print NR") "$2" (已用空间:"$1")"}' | + while IFS= read -r line; do + content_line "$line" + done + + content_line "0) 返回上级菜单" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 0) + return 1 + ;; + *) + dir=$(du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print $2}' | sed -n "$num"p) + if [ ! -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ]; then + double_line_break + separator_line "=" + content_line "\033[33m未找到下载大师自启文件:\033[0m" + content_line "\033[33m$dir/asusware.arm/etc/init.d/S50downloadmaster\033[0m" + content_line "\033[33m请检查设置!\033[0m" + separator_line "=" + + continue + fi + return 0 + ;; + esac done } set_cust_dir() { while true; do - echo "-----------------------------------------------" - echo '可用路径 剩余空间:' - df -h | awk '{print $6,$4}' | sed 1d - echo '路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!' - read -p "请输入自定义路径 > " dir - if [ "$(dir_avail $dir)" = 0 ] || [ -n "$(echo $dir | grep -E 'tmp|opt|sys')" ]; then - $echo "\033[31m路径错误!请重新设置!\033[0m" - continue - fi - break 1 + double_line_break + separator_line "=" + content_line "\033[33m注意:\033[0m" + content_line "\033[33m路径必须是带 / 的格式\033[0m" + content_line "\033[33m写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!\033[0m" + separator_line "-" + content_line "参考路经:" + separator_line "-" + + # original version + # df -h | awk '{print $6,$4}' | sed 1d + df -h | + awk 'NR>1 { + path=""; + for(i=6;i<=NF;i++) path=path $i " "; + sub(/ $/, "", path); + print path "|" $4 + }' | + while IFS='|' read -r mount_point path_avail; do + if [ -n "$mount_point" ]; then + i=$((i + 1)) + printf -v line_content "%-3s %s" "$i)" "$mount_point" + content_line "$line_content" + sub_content_line " (可用空间:$path_avail)" + fi + done + + content_line "0) 返回上级菜单" + separator_line "=" + read -p "请输入自定义路径> " dir + case "$dir" in + 0) + return 1 + ;; + *) + if [ "$(dir_avail "$dir")" = 0 ] || [ -n "$(echo "$dir" | grep -E 'tmp|opt|sys')" ]; then + invalid_input_retry + continue + fi + return 0 + ;; + esac done } setdir() { while true; do - echo "-----------------------------------------------" - $echo "\033[33m注意:安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m" + double_line_break + separator_line "=" + content_line "\033[33m注意:\033[0m" + content_line "\033[33m安装ShellCrash至少需要预留约 1MB 的磁盘空间\033[0m" if [ -n "$systype" ]; then [ "$systype" = "Padavan" ] && dir=/etc/storage + [ "$systype" = "mi_snapshot" ] && { - $echo "\033[33m检测到当前设备为小米官方系统,请选择安装位置\033[0m" - [ -d /data ] && $echo " 1 安装到 /data 目录,剩余空间:$(dir_avail /data -h)(支持软固化功能)" - [ -d /userdisk ] && $echo " 2 安装到 /userdisk 目录,剩余空间:$(dir_avail /userdisk -h)(支持软固化功能)" - [ -d /data/other_vol ] && $echo " 3 安装到 /data/other_vol 目录,剩余空间:$(dir_avail /data/other_vol -h)(支持软固化功能)" - $echo " 4 安装到自定义目录(不推荐,不明勿用!)" - $echo " 0 退出安装" - echo "-----------------------------------------------" - read -p "请输入相应数字 > " num + content_line "\033[33m检测到当前设备为小米官方系统\033[0m" + + separator_line "-" + content_line "请选择安装位置:" + separator_line "-" + + if [ -d /data ]; then + content_line "1) 安装到 /data 目录" + sub_content_line "剩余空间:$(dir_avail /data -h)(支持软固化功能)" + fi + + if [ -d /userdisk ]; then + content_line "2) 安装到 /userdisk 目录" + sub_content_line "剩余空间:$(dir_avail /userdisk -h)(支持软固化功能)" + fi + + if [ -d /data/other_vol ]; then + content_line "3) 安装到 /data/other_vol 目录" + sub_content_line "剩余空间:$(dir_avail /data/other_vol -h)(支持软固化功能)" + fi + + content_line "4) 安装到自定义目录" + sub_content_line "(不推荐,不明勿用!)" + + content_line "E) 退出安装" + separator_line "=" + read -p "请输入相应数字> " num case "$num" in 1) dir=/data @@ -188,51 +389,104 @@ setdir() { ;; 4) set_cust_dir + ret=$? + [ "$ret" -eq 1 ] && continue + ;; + "E" | "e") + abort_install ;; *) - exit 1 + invalid_input_retry + continue ;; esac } + [ "$systype" = "asusrouter" ] && { - $echo "\033[33m检测到当前设备为华硕固件,请选择安装方式\033[0m" - $echo " 1 基于USB设备安装(限23年9月之前固件,须插入\033[31m任意\033[0mUSB设备)" - $echo " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)" - $echo " 3 基于U盘+下载大师安装(支持所有固件,限ARM设备,须插入U盘或移动硬盘)" - $echo " 0 退出安装" - echo "-----------------------------------------------" - read -p "请输入相应数字 > " num + + content_line "\033[33m检测到当前设备为华硕固件\033[0m" + separator_line "-" + content_line "请选择安装方式:" + separator_line "-" + + content_line "1) 基于USB设备安装" + sub_content_line "(限23年9月之前固件,须插入任意USB设备)" + + content_line "2) 基于自启脚本安装" + sub_content_line "(仅支持梅林及部分非koolshare官改固件)" + + content_line "3) 基于U盘 + 下载大师安装" + sub_content_line "(支持所有固件,限ARM设备,须插入U盘或移动硬盘)" + + content_line "E) 退出安装" + separator_line "=" + + read -p "请输入相应数字> " num case "$num" in 1) - read -p "将脚本安装到USB存储/系统闪存?(1/0) > " res - [ "$res" = "1" ] && set_usb_dir || dir=/jffs + double_line_break + separator_line "=" + content_line "请选择脚本安装位置:" + separator_line "-" + content_line "1) USB存储" + content_line "2) 系统闪存" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 1) + set_usb_dir + ;; + *) + dir=/jffs + ;; + esac + usb_status=1 ;; 2) - $echo "如无法正常开机启动,请重新使用USB方式安装!" + double_line_break + separator_line "=" + content_line "如无法正常开机启动,请重新使用USB方式安装!" + separator_line "=" sleep 2 + dir=/jffs ;; 3) - echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!" + double_line_break + separator_line "=" + content_line "请先在路由器网页后台安装下载大师并启用," + content_line "之后选择外置存储所在目录!" + separator_line "=" sleep 2 + set_asus_dir + ret=$? + [ "$ret" -eq 1 ] && continue + ;; + "E" | "e") + abort_install ;; *) - exit 1 + invalid_input_retry + continue ;; esac } + [ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt else - $echo " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)" - $echo " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)" - $echo " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)" - $echo " 4 在\033[32m外置存储\033[0m中安装" - $echo " 5 手动设置安装目录" - $echo " 0 退出安装" - echo "----------------------------------------------" - read -p "请输入相应数字 > " num + separator_line "-" + content_line "请选择安装目录:" + separator_line "-" + content_line "1) \033[32m/etc目录\033[0m (适合root用户)" + content_line "2) \033[32m/usr/share目录\033[0m (适合Linux系统)" + content_line "3) \033[32m当前用户目录\033[0m (适合非root用户)" + content_line "4) \033[32m外置存储\033[0m" + content_line "5) 手动设置" + content_line "E) 退出安装" + separator_line "=" + read -p "请输入相应数字> " num # 设置目录 case "$num" in 1) @@ -247,87 +501,173 @@ setdir() { ;; 4) set_usb_dir + ret=$? + [ "$ret" -eq 1 ] && continue ;; 5) set_cust_dir + ret=$? + [ "$ret" -eq 1 ] && continue + ;; + "E" | "e") + abort_install ;; *) - echo "安装已取消" - exit 1 + invalid_input_retry + continue ;; esac fi - if [ ! -w $dir ]; then - $echo "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" - sleep 1 + if [ ! -w "$dir" ]; then + double_line_break + separator_line "=" + content_line "\033[31m没有$dir目录写入权限!\033[0m" + content_line "\033[31m请重新设置!\033[0m" + separator_line "=" + sleep 2 else - $echo "目标目录\033[32m$dir\033[0m空间剩余:$(dir_avail $dir -h)" - read -p "确认安装?(1/0) > " res - if [ "$res" = "1" ]; then - CRASHDIR=$dir/ShellCrash - break - fi + while true; do + double_line_break + separator_line "=" + content_line "目标目录:\033[32m$dir\033[0m" + content_line "可用空间:$(dir_avail $dir -h)" + separator_line "-" + content_line "1) 确认安装" + content_line "E) 退出安装" + content_line "0) 返回上级菜单" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 0) + break 1 + ;; + 1) + CRASHDIR="${dir}/ShellCrash" + break 2 + ;; + "E" | "e") + abort_install + ;; + *) + invalid_input_retry + continue + ;; + esac + done fi done } install() { - echo "-----------------------------------------------" - echo "开始从服务器获取安装文件!" - echo "-----------------------------------------------" + double_line_break + separator_line "=" + content_line "下载安装文件......" gettar - echo "-----------------------------------------------" - echo "ShellCrash 已经安装成功!" - [ "$profile" = "~/.bashrc" ] && echo "请执行【. ~/.bashrc > /dev/null】命令以更新环境变量!" - [ -n "$(ls -l /bin/sh | grep -oE 'zsh')" ] && echo "请执行【. ~/.zshrc > /dev/null】命令以更新环境变量!" - echo "-----------------------------------------------" - $echo "\033[33m输入\033[30;47m $my_alias \033[0;33m命令即可管理!!!\033[0m" - echo "-----------------------------------------------" + double_line_break + separator_line "=" + content_line "ShellCrash 已经安装成功!" + [ "$profile" = "~/.bashrc" ] && content_line "请执行【. ~/.bashrc > /dev/null】命令以更新环境变量!" + [ -n "$(ls -l /bin/sh | grep -oE 'zsh')" ] && content_line "请执行【. ~/.zshrc > /dev/null】命令以更新环境变量!" + content_line "输入\033[32m $my_alias \033[0m命令即可管理!" + separator_line "=" + double_line_break } setversion() { - echo "-----------------------------------------------" - $echo "\033[33m请选择想要安装的版本:\033[0m" - $echo " 1 \033[32m公测版(推荐)\033[0m" - $echo " 2 \033[36m稳定版\033[0m" - $echo " 3 \033[31m开发版\033[0m" - echo "-----------------------------------------------" - read -p "请输入相应数字 > " num - case "$num" in - 2) - url=$(echo $url | sed 's/master/stable/') - ;; - 3) - url=$(echo $url | sed 's/master/dev/') - ;; - *) ;; - esac + while true; do + double_line_break + separator_line "=" + content_line "请选择安装版本:" + separator_line "-" + content_line "1) \033[32m公测版(推荐)\033[0m" + content_line "2) \033[36m稳定版\033[0m" + content_line "3) \033[31m开发版\033[0m" + content_line "E) 退出安装" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 1) + break 1 + ;; + 2) + url=$(echo "$url" | sed 's/master/stable/') + break 1 + ;; + 3) + url=$(echo "$url" | sed 's/master/dev/') + break 1 + ;; + "E" | "e") + abort_install + ;; + *) + invalid_input_retry + continue + ;; + esac + done } +# =============================== the script start here ================================ + +# clean screen +printf "\033[H\033[2J" + +double_line_break +separator_line "=" +content_line " 欢迎使用" +content_line " ShellCrash" +content_line +content_line " 支持各种基于 openwrt 的路由器设备" +content_line " 支持Debian、Centos等标准 Linux 系统" +content_line " 如遇问题请加TG群反馈:t.me/ShellClash" +content_line +content_line " by Juewuy" +separator_line "=" + # 特殊固件识别及标记 [ -f "/etc/storage/started_script.sh" ] && { - systype=Padavan #老毛子固件 + systype=Padavan # 老毛子固件 initdir='/etc/storage/started_script.sh' } [ -d "/jffs" ] && { - systype=asusrouter #华硕固件 + systype=asusrouter # 华硕固件 [ -f "/jffs/.asusrouter" ] && initdir='/jffs/.asusrouter' [ -d "/jffs/scripts" ] && initdir='/jffs/scripts/nat-start' } -[ -f "/data/etc/crontabs/root" ] && systype=mi_snapshot #小米设备 -[ -w "/var/mnt/cfg/firewall" ] && systype=ng_snapshot #NETGEAR设备 +[ -f "/data/etc/crontabs/root" ] && systype=mi_snapshot # 小米设备 +[ -w "/var/mnt/cfg/firewall" ] && systype=ng_snapshot # NETGEAR设备 # 检查root权限 -if [ "$USER" != "root" -a -z "$systype" ]; then - echo "当前用户:$USER" - $echo "\033[31m请尽量使用root用户(不要直接使用sudo命令!)执行安装!\033[0m" - echo "-----------------------------------------------" - read -p "仍要安装?可能会产生未知错误!(1/0) > " res - [ "$res" != "1" ] && exit 1 +if [ "$USER" != "root" ] && [ -z "$systype" ]; then + while true; do + double_line_break + separator_line "=" + content_line "当前用户 $USER 非 root 用户" + content_line "\033[33m请尽量使用 root 用户(不要直接使用sudo命令)执行安装!\033[0m" + content_line "\033[31m继续安装,可能会产生未知错误!\033[0m" + separator_line "-" + content_line "1) 继续安装" + content_line "E) 退出安装" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 1) + break 1 + ;; + "E" | "e") + abort_install + ;; + *) + invalid_input_retry + continue + ;; + esac + done fi -if [ -n "$(echo $url | grep master)" ]; then +if [ -n "$(echo "$url" | grep master)" ]; then setversion fi @@ -337,38 +677,61 @@ webget /tmp/version "$url/version" echooff rm -rf /tmp/version # 输出 -$echo "最新版本:\033[32m$versionsh\033[0m" -echo "-----------------------------------------------" -$echo "\033[44m如遇问题请加TG群反馈:\033[42;30m t.me/ShellClash \033[0m" -$echo "\033[37m支持各种基于openwrt的路由器设备" -$echo "\033[33m支持Debian、Centos等标准Linux系统\033[0m" +double_line_break +separator_line "=" +content_line "最新版本:\033[32m$versionsh\033[0m" +separator_line "=" if [ -n "$CRASHDIR" ]; then - echo "-----------------------------------------------" - $echo "检测到旧的安装目录\033[36m$CRASHDIR\033[0m,是否覆盖安装?" - $echo "\033[32m覆盖安装时不会移除配置文件!\033[0m" - read -p "覆盖安装/卸载旧版本?(1/0) > " res - case "$res" in - 1) - install - ;; - 0) - rm -rf $CRASHDIR - echo "-----------------------------------------------" - $echo "\033[31m 旧版本文件已卸载!\033[0m" - setdir - install - ;; - 9) - echo "测试模式,变更安装位置" - setdir - install - ;; - *) - $echo "\033[31m输入错误!已取消安装!\033[0m" - exit 1 - ;; - esac + while true; do + double_line_break + separator_line "=" + content_line "检测到旧版本安装目录:\033[36m$CRASHDIR\033[0m" + content_line "\033[33m注意:覆盖安装时不会移除配置文件!\033[0m" + separator_line "-" + content_line "1) 覆盖安装" + content_line "2) 卸载旧版本" + content_line "E) 退出安装" + separator_line "=" + read -p "请输入相应数字> " num + case "$num" in + 1) + install + break 1 + ;; + 2) + rm -rf "$CRASHDIR" + + double_line_break + separator_line "=" + content_line "\033[31m旧版本文件已卸载!\033[0m" + separator_line "=" + + setdir + install + + break 1 + ;; + 9) + double_line_break + separator_line "=" + content_line "测试模式,变更安装位置" + separator_line "=" + + setdir + install + + break 1 + ;; + "E" | "e") + abort_install + ;; + *) + invalid_input_retry + continue + ;; + esac + done else setdir install diff --git a/rules/clash_providers/ShellCrash_RS_Full_BanAds.yaml b/rules/clash_providers/ShellCrash_RS_Full_BanAds.yaml index c25c2ff7..53ee08b2 100644 --- a/rules/clash_providers/ShellCrash_RS_Full_BanAds.yaml +++ b/rules/clash_providers/ShellCrash_RS_Full_BanAds.yaml @@ -1,4 +1,4 @@ -#ShellCrash-ruleset 全分组规则+去广告 For mihomo By Maozai 260109 +#ShellCrash-ruleset 全分组规则+去广告 For mihomo By Maozai 260111 #此版本为Maozai根据ACL4SSR规则修改优化而来,尽量在保持原有的基础上进行优化。 #数据源采用了DustinWin/ruleset_geodata和MetaCubeX/meta-rules-dat两个开源项目的规则,感谢原作者的辛勤付出。 @@ -46,9 +46,9 @@ proxy-groups: - {name: 🇭🇰 香港节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇭🇰|港|hk|hongkong|hong kong)"} - {name: 🇹🇼 台湾节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇹🇼|台|tw|taiwan|tai wan)", exclude-filter: "(?i)(仙台)"} - - {name: 🇺🇸 美国节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇺🇸|美|洛杉矶|圣何塞|西雅图|纽约|波特兰|旧金山|us|unitedstates|united states)", exclude-filter: "(?i)(南美|中美|拉美|亚美尼亚|美属)"} + - {name: 🇺🇸 美国节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇺🇸|美|洛杉矶|圣何塞|西雅图|纽约|波特兰|旧金山|休斯|达拉斯|硅谷|堪萨斯|迈阿密|凤凰城|芝加哥|奥勒姆|us|unitedstates|united states)", exclude-filter: "(?i)(南美|中美|拉美|亚美尼亚|美属)"} - {name: 🇯🇵 日本节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇯🇵|日|东京|大阪|埼玉|九州|仙台|jp|japan)", exclude-filter: "(?i)(尼日利亚|尼日尔|日内瓦)"} - - {name: 🇪🇺 欧洲节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇪🇺|欧|德|英|法|荷|俄罗斯|西班牙|意大利|瑞士|瑞典|土耳其|挪威|芬兰|丹麦|比利时|爱尔兰|奥地利|波兰|葡萄牙|乌克兰|希腊|捷克|匈牙利|罗马尼亚|保加利亚|冰岛|克罗地亚)"} + - {name: 🇪🇺 欧洲节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇪🇺|欧|德|英|法|荷|俄罗斯|西班牙|意大利|瑞士|瑞典|土耳其|挪威|芬兰|丹麦|比利时|爱尔兰|奥地利|波兰|葡萄牙|乌克兰|希腊|捷克|匈牙利|罗马尼亚|保加利亚|冰岛|克罗地亚|阿姆斯特丹)"} - {name: 🇰🇷 韩国节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇰🇷|韩|韓|首尔|kr|kor)"} - {name: 🇸🇬 狮城节点, type: url-test, tolerance: 50, include-all: true, filter: "(?i)(🇸🇬|新加坡|狮城|sg|singapore)"} @@ -221,8 +221,8 @@ rule-providers: #规则顺序 rules: - - DOMAIN-SUFFIX,captive.apple.com,DIRECT - - DOMAIN-SUFFIX,kamo.teracloud.jp,DIRECT + - DOMAIN-SUFFIX,captive.apple.com,🍎 苹果服务 + - DOMAIN-SUFFIX,kamo.teracloud.jp,🀄️ 国内流量 - RULE-SET,privateip,🔒 私有网络,no-resolve - RULE-SET,private,🔒 私有网络 diff --git a/rules/singbox_providers/ShellCrash_RS_Full_BanAds.json b/rules/singbox_providers/ShellCrash_RS_Full_BanAds.json index 80151ae3..2e4fc53f 100644 --- a/rules/singbox_providers/ShellCrash_RS_Full_BanAds.json +++ b/rules/singbox_providers/ShellCrash_RS_Full_BanAds.json @@ -1,4 +1,4 @@ -//ShellCrash-ruleset 全分组规则+去广告 For Sing-box By Maozai 260109 +//ShellCrash-ruleset 全分组规则+去广告 For Sing-box By Maozai 260111 { "outbounds": [ { "tag": "🚀 节点选择", "type": "selector", "outbounds": ["♻️ 自动选择", "✨ 自动选择(去高倍率)", "🛠️ 手动切换", "🎯 本地直连", "🇭🇰 香港节点", "🇹🇼 台湾节点", "🇺🇸 美国节点", "🇯🇵 日本节点", "🇪🇺 欧洲节点", "🇰🇷 韩国节点", "🇸🇬 狮城节点", "👑 高级节点", "📉 省流节点", {providers_tags}] }, @@ -37,9 +37,9 @@ { "tag": "🇭🇰 香港节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇭🇰|港|hk|hongkong|hong kong)" }, { "tag": "🇹🇼 台湾节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇹🇼|台|tw|taiwan|tai wan)", "exclude": "(?i)(仙台)" }, - { "tag": "🇺🇸 美国节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇺🇸|美|洛杉矶|圣何塞|西雅图|纽约|波特兰|旧金山|us|unitedstates|united states)", "exclude": "(?i)(南美|中美|拉美|亚美尼亚|美属)" }, + { "tag": "🇺🇸 美国节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇺🇸|美|洛杉矶|圣何塞|西雅图|纽约|波特兰|旧金山|休斯|达拉斯|硅谷|堪萨斯|迈阿密|凤凰城|芝加哥|奥勒姆|us|unitedstates|united states)", "exclude": "(?i)(南美|中美|拉美|亚美尼亚|美属)" }, { "tag": "🇯🇵 日本节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇯🇵|日|东京|大阪|埼玉|九州|jp|japan)", "exclude": "(?i)(尼日利亚|尼日尔|日内瓦)" }, - { "tag": "🇪🇺 欧洲节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇪🇺|欧|德|英|法|荷|俄罗斯|西班牙|意大利|瑞士|瑞典|土耳其|挪威|芬兰|丹麦|比利时|爱尔兰|奥地利|波兰|葡萄牙|乌克兰|希腊|捷克|匈牙利|罗马尼亚|保加利亚|冰岛|克罗地亚)" }, + { "tag": "🇪🇺 欧洲节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇪🇺|欧|德|英|法|荷|俄罗斯|西班牙|意大利|瑞士|瑞典|土耳其|挪威|芬兰|丹麦|比利时|爱尔兰|奥地利|波兰|葡萄牙|乌克兰|希腊|捷克|匈牙利|罗马尼亚|保加利亚|冰岛|克罗地亚|阿姆斯特丹)" }, { "tag": "🇰🇷 韩国节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇰🇷|韩|韓|首尔|kr|kor)" }, { "tag": "🇸🇬 狮城节点", "type": "urltest", "use_all_providers": true, "include": "(?i)(🇸🇬|新加坡|狮城|sg|singapore)" }, @@ -48,8 +48,8 @@ ], "route": { "rules": [ - { "domain_suffix": ["captive.apple.com"], "outbound": "DIRECT" }, - { "domain_suffix": ["kamo.teracloud.jp"], "outbound": "DIRECT" }, + { "domain_suffix": ["captive.apple.com"], "outbound": "🍎 苹果服务" }, + { "domain_suffix": ["kamo.teracloud.jp"], "outbound": "🀄️ 国内流量" }, { "rule_set": ["private"], "outbound": "🎯 本地直连" }, { "rule_set": ["ads"], "outbound": "🛑 广告拦截" }, diff --git a/scripts/init.sh b/scripts/init.sh index 558a9660..d5535529 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -102,7 +102,7 @@ grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || { #设置更新地址 [ -n "$url" ] && setconfig update_url $url #设置环境变量 -[ -w /opt/etc/profile ] && profile=/opt/etc/profile +[ -w /opt/etc/profile ] && [ "$systype" = "Padavan" ] && profile=/opt/etc/profile [ -w /jffs/configs/profile.add ] && profile=/jffs/configs/profile.add [ -z "$profile" ] && profile=/etc/profile if [ -n "$profile" ]; then diff --git a/scripts/lang/chs/1_start.lang b/scripts/lang/chs/1_start.lang new file mode 100644 index 00000000..275f0996 --- /dev/null +++ b/scripts/lang/chs/1_start.lang @@ -0,0 +1,11 @@ +# ===== 启动完成 ===== +START_SERVICE_OK="服务已启动!" +START_WEB_HINT="请使用" +START_WEB_HINT2="管理内置规则" +START_PAC_HINT="其他设备可使用 PAC 配置:" +START_PROXY_HINT="或使用 HTTP / SOCKS5 方式连接:" + +# ===== 启动流程 ===== +START_NO_CORE_CFG_TRY_GEN="没有找到核心配置文件,尝试生成 providers 配置文件!" +START_NO_CORE_CFG_IMPORT_FIRST="没有找到核心配置文件,请先导入配置文件!" +START_FIREWALL_DONE="已完成防火墙设置!" diff --git a/scripts/lang/en/1_start.lang b/scripts/lang/en/1_start.lang new file mode 100644 index 00000000..c45276af --- /dev/null +++ b/scripts/lang/en/1_start.lang @@ -0,0 +1,11 @@ +# ===== Startup ===== +START_SERVICE_OK="Service started successfully!" +START_WEB_HINT="Please use" +START_WEB_HINT2="manage built-in rules" +START_PAC_HINT="Other devices can connect using PAC configuration:" +START_PROXY_HINT="Or connect using HTTP / SOCKS5:" + +# ===== Startup Flow ===== +START_NO_CORE_CFG_TRY_GEN="Core configuration not found. Attempting to generate providers configuration!" +START_NO_CORE_CFG_IMPORT_FIRST="Core configuration not found. Please import a configuration first!" +START_FIREWALL_DONE="Firewall configuration completed!" diff --git a/scripts/libs/set_proxy.sh b/scripts/libs/set_proxy.sh index 3f3400cf..c5e0c8ff 100644 --- a/scripts/libs/set_proxy.sh +++ b/scripts/libs/set_proxy.sh @@ -3,6 +3,7 @@ setproxy(){ [ -n "$(pidof CrashCore)" ] && { [ -n "$authentication" ] && auth="$authentication@" || auth="" [ -z "$mix_port" ] && mix_port=7890 - export all_proxy="http://${auth}127.0.0.1:$mix_port" + export https_proxy="http://${auth}127.0.0.1:$mix_port" + export http_proxy="http://${auth}127.0.0.1:$mix_port" } } \ No newline at end of file diff --git a/scripts/libs/web_get.sh b/scripts/libs/web_get.sh index 949fd6d9..261a91ee 100644 --- a/scripts/libs/web_get.sh +++ b/scripts/libs/web_get.sh @@ -32,7 +32,8 @@ webget(){ result=$(curl $agent -w '%{http_code}' --connect-timeout 3 $progress $redirect $certificate -o "$1" "$url") fi [ "$result" = "200" ] && return 0 #成功则退出否则重试 - export all_proxy="" + export https_proxy="" + export http_proxy="" result=$(curl $agent -w '%{http_code}' --connect-timeout 5 $progress $redirect $certificate -o "$1" "$2") [ "$result" = "200" ] return $? diff --git a/scripts/libs/web_save.sh b/scripts/libs/web_save.sh index b9f75c88..23cecb35 100644 --- a/scripts/libs/web_save.sh +++ b/scripts/libs/web_save.sh @@ -20,11 +20,13 @@ web_save() { #最小化保存面板节点选择 } done <"$TMPDIR"/web_proxies rm -rf "$TMPDIR"/web_proxies - #对比文件,如果有变动且不为空则写入磁盘,否则清除缓存 - for file in web_save web_configs; do - if [ -s "$TMPDIR"/${file} ]; then - . "$CRASHDIR"/libs/compare.sh && compare "$TMPDIR"/${file} "$CRASHDIR"/configs/${file} - [ "$?" = 0 ] && rm -rf "$TMPDIR"/${file} || mv -f "$TMPDIR"/${file} "$CRASHDIR"/configs/${file} + #对比文件,如果有变动则写入磁盘,否则清除缓存 + for file in web_save; do + if [ -s "$TMPDIR/$file" ]; then + . "$CRASHDIR"/libs/compare.sh && compare "$TMPDIR/$file" "$CRASHDIR/configs/$file" + [ "$?" = 0 ] && rm -f "$TMPDIR/$file" || mv -f "$TMPDIR/$file" "$CRASHDIR/configs/$file" + else + rm -f "$CRASHDIR/configs/$file" #空文件时移除旧文件 fi done } diff --git a/scripts/menu.sh b/scripts/menu.sh index d1be37fd..138da872 100644 --- a/scripts/menu.sh +++ b/scripts/menu.sh @@ -159,88 +159,82 @@ ckstatus() { #脚本启动前检查 } main_menu() { - ckstatus + while true; do + ckstatus - echo -e " 1 \033[32m$MENU_MAIN_1\033[0m" - echo -e " 2 \033[36m$MENU_MAIN_2\033[0m" - echo -e " 3 \033[31m$MENU_MAIN_3\033[0m" - echo -e " 4 \033[33m$MENU_MAIN_4\033[0m" - echo -e " 5 \033[32m$MENU_MAIN_5\033[0m" - echo -e " 6 \033[36m$MENU_MAIN_6\033[0m" - echo -e " 7 \033[33m$MENU_MAIN_7\033[0m" - echo -e " 8 $MENU_MAIN_8" - echo -e " 9 \033[32m$MENU_MAIN_9\033[0m" - echo "-----------------------------------------------" - echo -e " 0 $MENU_MAIN_0" - - read -p "$MENU_MAIN_PROMPT" num - - case "$num" in - 0) - exit - ;; - 1) - start_service - exit - ;; - 2) - checkcfg=$(cat "$CFG_PATH") - . "$CRASHDIR"/menus/2_settings.sh && settings - if [ -n "$PID" ]; then - checkcfg_new=$(cat "$CFG_PATH") - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - main_menu - ;; - 3) - [ "$bot_tg_service" = ON ] && . "$CRASHDIR"/menus/bot_tg_service.sh && bot_tg_stop - "$CRASHDIR"/start.sh stop - sleep 1 + echo -e " 1 \033[32m$MENU_MAIN_1\033[0m" + echo -e " 2 \033[36m$MENU_MAIN_2\033[0m" + echo -e " 3 \033[31m$MENU_MAIN_3\033[0m" + echo -e " 4 \033[33m$MENU_MAIN_4\033[0m" + echo -e " 5 \033[32m$MENU_MAIN_5\033[0m" + echo -e " 6 \033[36m$MENU_MAIN_6\033[0m" + echo -e " 7 \033[33m$MENU_MAIN_7\033[0m" + echo -e " 8 $MENU_MAIN_8" + echo -e " 9 \033[32m$MENU_MAIN_9\033[0m" echo "-----------------------------------------------" - echo -e "\033[31m$corename$MENU_SERVICE_STOPPED\033[0m" - main_menu - ;; - 4) - . "$CRASHDIR"/menus/4_setboot.sh && setboot - main_menu - ;; - 5) - . "$CRASHDIR"/menus/5_task.sh && task_menu - main_menu - ;; - 6) - . "$CRASHDIR"/menus/6_core_config.sh && set_core_config - main_menu - ;; - 7) - GT_CFG_PATH="$CRASHDIR"/configs/gateway.cfg - touch "$GT_CFG_PATH" - checkcfg=$(cat "$CFG_PATH" "$GT_CFG_PATH") - . "$CRASHDIR"/menus/7_gateway.sh && gateway - if [ -n "$PID" ]; then - checkcfg_new=$(cat "$CFG_PATH" "$GT_CFG_PATH") - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - main_menu - ;; - 8) - . "$CRASHDIR"/menus/8_tools.sh && tools - main_menu - ;; - 9) - checkcfg=$(cat "$CFG_PATH") - . "$CRASHDIR"/menus/9_upgrade.sh && upgrade - if [ -n "$PID" ]; then - checkcfg_new=$(cat "$CFG_PATH") - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - main_menu - ;; - *) - errornum - exit - ;; - esac + echo -e " 0 $MENU_MAIN_0" + + read -p "$MENU_MAIN_PROMPT" num + + case "$num" in + "" | 0) + exit + ;; + 1) + start_service + exit + ;; + 2) + checkcfg=$(cat "$CFG_PATH") + . "$CRASHDIR"/menus/2_settings.sh && settings + if [ -n "$PID" ]; then + checkcfg_new=$(cat "$CFG_PATH") + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + ;; + 3) + [ "$bot_tg_service" = ON ] && . "$CRASHDIR"/menus/bot_tg_service.sh && bot_tg_stop + "$CRASHDIR"/start.sh stop + sleep 1 + echo "-----------------------------------------------" + echo -e "\033[31m$corename$MENU_SERVICE_STOPPED\033[0m" + ;; + 4) + . "$CRASHDIR"/menus/4_setboot.sh && setboot + ;; + 5) + . "$CRASHDIR"/menus/5_task.sh && task_menu + ;; + 6) + . "$CRASHDIR"/menus/6_core_config.sh && set_core_config + ;; + 7) + GT_CFG_PATH="$CRASHDIR"/configs/gateway.cfg + touch "$GT_CFG_PATH" + checkcfg=$(cat "$CFG_PATH" "$GT_CFG_PATH") + . "$CRASHDIR"/menus/7_gateway.sh && gateway + if [ -n "$PID" ]; then + checkcfg_new=$(cat "$CFG_PATH" "$GT_CFG_PATH") + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + ;; + 8) + . "$CRASHDIR"/menus/8_tools.sh && tools + ;; + 9) + checkcfg=$(cat "$CFG_PATH") + . "$CRASHDIR"/menus/9_upgrade.sh && upgrade + if [ -n "$PID" ]; then + checkcfg_new=$(cat "$CFG_PATH") + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + ;; + *) + errornum + sleep 1 + ;; + esac + done } case "$1" in diff --git a/scripts/menus/1_start.sh b/scripts/menus/1_start.sh index c3c39249..6f0cc258 100644 --- a/scripts/menus/1_start.sh +++ b/scripts/menus/1_start.sh @@ -3,49 +3,65 @@ [ -n "$__IS_MODULE_1_START_LOADED" ] && return __IS_MODULE_1_START_LOADED=1 +load_lang 1_start -#启动相关 +# ===== 启动完成提示 ===== startover() { echo -ne " \r" - echo -e "\033[32m服务已启动!\033[0m" - echo -e "请使用 \033[4;36mhttp://$host$hostdir\033[0m 管理内置规则" + echo -e "\033[32m$START_SERVICE_OK\033[0m" + echo -e "$START_WEB_HINT \033[4;36mhttp://$host$hostdir\033[0m $START_WEB_HINT2" + if [ "$redir_mod" = "纯净模式" ]; then echo "-----------------------------------------------" - echo -e "其他设备可以使用PAC配置连接:\033[4;32mhttp://$host:$db_port/ui/pac\033[0m" - echo -e "或者使用HTTP/SOCK5方式连接:IP{\033[36m$host\033[0m}Port{\033[36m$mix_port\033[0m}" + echo -e "$START_PAC_HINT \033[4;32mhttp://$host:$db_port/ui/pac\033[0m" + echo -e "$START_PROXY_HINT IP{\033[36m$host\033[0m} Port{\033[36m$mix_port\033[0m}" fi return 0 } + +# ===== 启动核心 ===== start_core() { if echo "$crashcore" | grep -q 'singbox'; then - core_config="$CRASHDIR"/jsons/config.json + core_config="$CRASHDIR/jsons/config.json" else - core_config="$CRASHDIR"/yamls/config.yaml + core_config="$CRASHDIR/yamls/config.yaml" fi + echo "-----------------------------------------------" - if [ ! -s $core_config -a -s "$CRASHDIR"/configs/providers.cfg ]; then - echo -e "\033[33m没有找到${crashcore}配置文件,尝试生成providers配置文件!\033[0m" + + if [ ! -s "$core_config" ] && [ -s "$CRASHDIR/configs/providers.cfg" ]; then + echo -e "\033[33m$START_NO_CORE_CFG_TRY_GEN\033[0m" + [ "$crashcore" = singboxr ] && coretype=singbox [ "$crashcore" = meta -o "$crashcore" = clashpre ] && coretype=clash - . "$CRASHDIR"/menus/6_core_config.sh && gen_${coretype}_providers - elif [ -s $core_config -o -n "$Url" -o -n "$Https" ]; then - "$CRASHDIR"/start.sh start - #设置循环检测以判定服务启动是否成功 - . "$CRASHDIR"/libs/start_wait.sh - [ -n "$test" -o -n "$(pidof CrashCore)" ] && { - #启动TG机器人 - [ "$bot_tg_service" = ON ] && . "$CRASHDIR"/menus/bot_tg_service.sh && bot_tg_start - startover - } + + . "$CRASHDIR/menus/6_core_config.sh" && gen_${coretype}_providers + + elif [ -s "$core_config" ] || [ -n "$Url" ] || [ -n "$Https" ]; then + "$CRASHDIR/start.sh" start + + # 循环检测服务启动状态 + . "$CRASHDIR/libs/start_wait.sh" + + [ -n "$test" ] || pidof CrashCore >/dev/null && { + # 启动 TG 机器人 + if [ "$bot_tg_service" = ON ]; then + . "$CRASHDIR/menus/bot_tg_service.sh" && bot_tg_start + fi + startover + } + else - echo -e "\033[31m没有找到${crashcore}配置文件,请先导入配置文件!\033[0m" - . "$CRASHDIR"/menus/6_core_config.sh && set_core_config + echo -e "\033[31m$START_NO_CORE_CFG_IMPORT_FIRST\033[0m" + . "$CRASHDIR/menus/6_core_config.sh" && set_core_config fi } + +# ===== 启动服务入口 ===== start_service() { if [ "$firewall_area" = 5 ]; then - "$CRASHDIR"/start.sh start - echo -e "\033[32m已完成防火墙设置!\033[0m" + "$CRASHDIR/start.sh" start + echo -e "\033[32m$START_FIREWALL_DONE\033[0m" else start_core fi diff --git a/scripts/menus/6_core_config.sh b/scripts/menus/6_core_config.sh index 4594a909..8cf80fa2 100644 --- a/scripts/menus/6_core_config.sh +++ b/scripts/menus/6_core_config.sh @@ -372,13 +372,13 @@ EOF } } if [ -z "$(grep "provider_temp_${coretype}" "$CRASHDIR"/configs/ShellCrash.cfg)" ];then - provider_temp_file="$TMPDIR/$(sed -n "1 p" "$CRASHDIR"/configs/${coretype}_providers.list | awk '{print $2}')" + provider_temp_file="$(sed -n "1 p" "$CRASHDIR"/configs/${coretype}_providers.list | awk '{print $2}')" else provider_temp_file=$(grep "provider_temp_${coretype}" "$CRASHDIR"/configs/ShellCrash.cfg | awk -F '=' '{print $2}') fi echo "-----------------------------------------------" - if [ -s "$provider_temp_file" ];then - ln -sf "$provider_temp_file" "$TMPDIR"/provider_temp_file + if [ -s "$TMPDIR/$provider_temp_file" ];then + ln -sf "$TMPDIR/$provider_temp_file" "$TMPDIR"/provider_temp_file else echo -e "\033[33m正在获取在线模版!\033[0m" get_bin "$TMPDIR"/provider_temp_file "rules/${coretype}_providers/$provider_temp_file" @@ -416,7 +416,7 @@ EOF cut -c 1- "$TMPDIR"/providers/providers.yaml "$TMPDIR"/providers/proxy-groups.yaml "$TMPDIR"/providers/rules.yaml > "$TMPDIR"/config.yaml rm -rf "$TMPDIR"/providers #调用内核测试 - . "$CRASHDIR"/libs/core_tools.sh && core_find && "$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml + . "$CRASHDIR"/starts/check_core.sh && check_core && "$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml if [ "$?" = 0 ];then echo -e "\033[32m配置文件生成成功!\033[0m" mkdir -p "$CRASHDIR"/yamls @@ -518,7 +518,7 @@ EOF cat "$TMPDIR"/provider_temp_file | sed "s/{providers_tags}/$providers_tags/g" > "$TMPDIR"/providers/outbounds.json rm -rf "$TMPDIR"/provider_temp_file #调用内核测试 - . "$CRASHDIR"/libs/core_tools.sh && core_find && "$TMPDIR"/CrashCore merge "$TMPDIR"/config.json -C "$TMPDIR"/providers + . "$CRASHDIR"/starts/check_core.sh && check_core && "$TMPDIR"/CrashCore merge "$TMPDIR"/config.json -C "$TMPDIR"/providers if [ "$?" = 0 ];then echo -e "\033[32m配置文件生成成功!如果启动超时建议更新里手动安装Singbox-srs数据库常用包!\033[0m" mkdir -p "$CRASHDIR"/jsons @@ -988,205 +988,206 @@ gen_core_config_link(){ #在线生成工具 fi done } -set_core_config_link(){ #直接导入配置 - echo "-----------------------------------------------" - echo -e "\033[32m仅限导入完整的配置文件链接!!!\033[0m" - echo "-----------------------------------------------" - echo -e "注意:\033[31m此功能不兼容“跳过证书验证”功能,部分老旧\n设备可能出现x509报错导致节点不通\033[0m" - echo -e "你也可以搭配在线订阅转换网站或者自建SubStore使用" - echo "$crashcore" | grep -q 'singbox' &&echo -e "singbox内核建议使用\033[32;4mhttps://subv.jwsc.eu.org/\033[0m转换" - echo "-----------------------------------------------" - echo -e "\033[33m0 返回上级菜单\033[0m" - echo "-----------------------------------------------" - read -p "请输入完整链接 > " link - test=$(echo $link | grep -iE "tp.*://" ) - link=`echo ${link/\ \(*\)/''}` #删除恶心的超链接内容 - link=`echo ${link//\&/\\\&}` #处理分隔符 - if [ -n "$link" -a -n "$test" ];then - echo "-----------------------------------------------" - echo -e 请检查输入的链接是否正确: - echo -e "\033[4;32m$link\033[0m" - read -p "确认导入配置文件?原配置文件将被备份![1/0] > " res - if [ "$res" = '1' ]; then - #将用户链接写入配置 - Url='' - Https="$link" - setconfig Https "'$Https'" - setconfig Url - #获取在线yaml文件 - jump_core_config - else - set_core_config_link - fi - elif [ "$link" = 0 ];then - i= - else - echo "-----------------------------------------------" - echo -e "\033[31m请输入正确的配置文件链接地址!!!\033[0m" - echo -e "\033[33m仅支持http、https、ftp以及ftps链接!\033[0m" - sleep 1 - set_core_config_link - fi + +# 直接导入配置 +set_core_config_link() { + while true; do + echo "-----------------------------------------------" + echo -e "\033[32m仅限导入完整的配置文件链接!!!\033[0m" + echo "-----------------------------------------------" + echo -e "注意:\033[31m此功能不兼容“跳过证书验证”功能,部分老旧\n设备可能出现x509报错导致节点不通\033[0m" + echo -e "你也可以搭配在线订阅转换网站或者自建SubStore使用" + echo "$crashcore" | grep -q 'singbox' && echo -e "singbox内核建议使用\033[32;4mhttps://subv.jwsc.eu.org/\033[0m转换" + echo "-----------------------------------------------" + echo -e "\033[33m0 返回上级菜单\033[0m" + echo "-----------------------------------------------" + read -p "请输入完整链接 > " link + test=$(echo $link | grep -iE "tp.*://") + link=$(echo ${link/\ \(*\)/''}) # 删除恶心的超链接内容 + link=$(echo ${link//\&/\\&}) # 处理分隔符 + if [ -n "$link" -a -n "$test" ]; then + echo "-----------------------------------------------" + echo -e "请检查输入的链接是否正确:" + echo -e "\033[4;32m$link\033[0m" + read -p "确认导入配置文件?原配置文件将被备份![1/0] > " res + if [ "$res" = '1' ]; then + # 将用户链接写入配置 + Url='' + Https="$link" + setconfig Https "'$Https'" + setconfig Url + # 获取在线yaml文件 + jump_core_config + break + fi + elif [ "$link" = 0 ]; then + i= + break + else + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的配置文件链接地址!!!\033[0m" + echo -e "\033[33m仅支持http、https、ftp以及ftps链接!\033[0m" + sleep 1 + fi + done } -#配置文件主界面 -set_core_config(){ - [ -z "$rule_link" ] && rule_link=1 - [ -z "$server_link" ] && server_link=1 - echo "$crashcore" | grep -q 'singbox' && config_path="$JSONSDIR"/config.json || config_path="$YAMLSDIR"/config.yaml - echo "-----------------------------------------------" - echo -e "\033[30;47m ShellCrash配置文件管理\033[0m" - echo "-----------------------------------------------" - echo -e " 1 在线\033[32m生成配置文件\033[0m(基于Subconverter订阅转换)" - if [ -f "$CRASHDIR"/v2b_api.sh ];then - echo -e " 2 登录\033[33m获取订阅(推荐!)\033[0m" - else - echo -e " 2 在线\033[33m获取配置文件\033[0m(基于订阅提供者)" - fi - echo -e " 3 本地\033[32m生成配置文件\033[0m(基于内核providers,推荐!)" - echo -e " 4 本地\033[33m上传完整配置文件\033[0m" - echo -e " 5 设置\033[36m自动更新\033[0m" - echo -e " 6 \033[32m自定义\033[0m配置文件" - echo -e " 7 \033[33m更新\033[0m配置文件" - echo -e " 8 \033[36m还原\033[0m配置文件" - echo -e " 9 自定义浏览器UA \033[32m$user_agent\033[0m" - echo "-----------------------------------------------" - [ "$inuserguide" = 1 ] || echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - if [ -n "$Url" ];then - echo "-----------------------------------------------" - echo -e "\033[33m检测到已记录的链接内容:\033[0m" - echo -e "\033[4;32m$Url\033[0m" - echo "-----------------------------------------------" - read -p "清空链接/追加导入?[1/0] > " res - if [ "$res" = '1' ]; then - Url_link="" - echo "-----------------------------------------------" - echo -e "\033[31m链接已清空!\033[0m" - else - Url_link=$Url - fi - fi - gen_core_config_link - set_core_config - ;; - 2) - if [ -f "$CRASHDIR"/v2b_api.sh ];then - . "$CRASHDIR"/v2b_api.sh - set_core_config - else - set_core_config_link - fi - set_core_config - ;; - 3) - if [ "$crashcore" = meta -o "$crashcore" = clashpre ];then - coretype=clash - setproviders - elif [ "$crashcore" = singboxr ];then - coretype=singbox - setproviders - else - echo -e "\033[33msingbox官方内核及Clash基础内核不支持此功能,请先更换内核!\033[0m" - sleep 1 - checkupdate && setcore - fi - set_core_config - ;; - 4) - echo "-----------------------------------------------" - echo -e "\033[33m请将本地配置文件上传到/tmp目录并重命名为config.yaml或者config.json\033[0m" - echo -e "\033[32m之后重新运行本脚本即可自动弹出导入提示!\033[0m" - exit - ;; - 5) - . "$CRASHDIR"/menus/5_task.sh && task_menu - set_core_config - ;; - 6) - checkcfg=$(cat $CFG_PATH) - override - if [ -n "$PID" ];then - checkcfg_new=$(cat $CFG_PATH) - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - set_core_config - ;; - 7) - if [ -z "$Url" -a -z "$Https" ];then - echo "-----------------------------------------------" - echo -e "\033[31m没有找到你的配置文件/订阅链接!请先输入链接!\033[0m" - sleep 1 - set_core_config - else - echo "-----------------------------------------------" - echo -e "\033[33m当前系统记录的链接为:\033[0m" - echo -e "\033[4;32m$Url$Https\033[0m" - echo "-----------------------------------------------" - read -p "确认更新配置文件?[1/0] > " res - if [ "$res" = '1' ]; then - jump_core_config - else - set_core_config - fi - fi - ;; - 8) - if [ ! -f ${config_path}.bak ];then - echo "-----------------------------------------------" - echo -e "\033[31m没有找到配置文件的备份!\033[0m" - set_core_config - else - echo "-----------------------------------------------" - echo -e 备份文件共有"\033[32m`wc -l < ${config_path}.bak`\033[0m"行内容,当前文件共有"\033[32m`wc -l < ${config_path}`\033[0m"行内容 - read -p "确认还原配置文件?此操作不可逆![1/0] > " res - if [ "$res" = '1' ]; then - mv ${config_path}.bak ${config_path} - echo "----------------------------------------------" - echo -e "\033[32m配置文件已还原!请手动重启服务!\033[0m" - sleep 1 - else - echo "-----------------------------------------------" - echo -e "\033[31m操作已取消!返回上级菜单!\033[0m" - set_core_config - fi - fi - ;; - 9) - echo "-----------------------------------------------" - echo -e "\033[36m如果6-1或者6-2无法正确获取配置文件时可以尝试使用\033[0m" - echo -e " 1 使用自动UA" - echo -e " 2 不使用UA" - echo -e " 3 使用自定义UA:\033[32m$user_agent\033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) - user_agent='' - ;; - 1) - user_agent='auto' - ;; - 2) - user_agent='none' - ;; - 3) - read -p "请输入自定义UA(不要包含空格和特殊符号!) > " text - [ -n "$text" ] && user_agent="$text" - ;; - *) - errornum - ;; - esac - [ "$num" -le 3 ] && setconfig user_agent "$user_agent" - set_core_config - ;; - *) - errornum - ;; - esac +# 配置文件主界面 +set_core_config() { + while true; do + [ -z "$rule_link" ] && rule_link=1 + [ -z "$server_link" ] && server_link=1 + echo "$crashcore" | grep -q 'singbox' && config_path="$JSONSDIR"/config.json || config_path="$YAMLSDIR"/config.yaml + echo "-----------------------------------------------" + echo -e "\033[30;47m ShellCrash配置文件管理\033[0m" + echo "-----------------------------------------------" + echo -e " 1 在线\033[32m生成配置文件\033[0m(基于Subconverter订阅转换)" + if [ -f "$CRASHDIR"/v2b_api.sh ]; then + echo -e " 2 登录\033[33m获取订阅(推荐!)\033[0m" + else + echo -e " 2 在线\033[33m获取配置文件\033[0m(基于订阅提供者)" + fi + echo -e " 3 本地\033[32m生成配置文件\033[0m(基于内核providers,推荐!)" + echo -e " 4 本地\033[33m上传完整配置文件\033[0m" + echo -e " 5 设置\033[36m自动更新\033[0m" + echo -e " 6 \033[32m自定义\033[0m配置文件" + echo -e " 7 \033[33m更新\033[0m配置文件" + echo -e " 8 \033[36m还原\033[0m配置文件" + echo -e " 9 自定义浏览器UA \033[32m$user_agent\033[0m" + echo "-----------------------------------------------" + [ "$inuserguide" = 1 ] || echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + "" | 0) + break + ;; + 1) + if [ -n "$Url" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m检测到已记录的链接内容:\033[0m" + echo -e "\033[4;32m$Url\033[0m" + echo "-----------------------------------------------" + read -p "清空链接/追加导入?[1/0] > " res + if [ "$res" = '1' ]; then + Url_link="" + echo "-----------------------------------------------" + echo -e "\033[31m链接已清空!\033[0m" + else + Url_link=$Url + fi + fi + gen_core_config_link + ;; + 2) + if [ -f "$CRASHDIR"/v2b_api.sh ]; then + . "$CRASHDIR"/v2b_api.sh + else + set_core_config_link + fi + ;; + 3) + if [ "$crashcore" = meta -o "$crashcore" = clashpre ]; then + coretype=clash + setproviders + elif [ "$crashcore" = singboxr ]; then + coretype=singbox + setproviders + else + echo -e "\033[33msingbox官方内核及Clash基础内核不支持此功能,请先更换内核!\033[0m" + sleep 1 + checkupdate && setcore + fi + ;; + 4) + echo "-----------------------------------------------" + echo -e "\033[33m请将本地配置文件上传到/tmp目录并重命名为config.yaml或者config.json\033[0m" + echo -e "\033[32m之后重新运行本脚本即可自动弹出导入提示!\033[0m" + sleep 2 + exit + ;; + 5) + . "$CRASHDIR"/menus/5_task.sh && task_menu + break + ;; + 6) + checkcfg=$(cat $CFG_PATH) + override + if [ -n "$PID" ]; then + checkcfg_new=$(cat $CFG_PATH) + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + ;; + 7) + if [ -z "$Url" -a -z "$Https" ]; then + echo "-----------------------------------------------" + echo -e "\033[31m没有找到你的配置文件/订阅链接!请先输入链接!\033[0m" + sleep 1 + else + echo "-----------------------------------------------" + echo -e "\033[33m当前系统记录的链接为:\033[0m" + echo -e "\033[4;32m$Url$Https\033[0m" + echo "-----------------------------------------------" + read -p "确认更新配置文件?[1/0] > " res + if [ "$res" = '1' ]; then + jump_core_config + break + fi + fi + ;; + 8) + if [ ! -f ${config_path}.bak ]; then + echo "-----------------------------------------------" + echo -e "\033[31m没有找到配置文件的备份!\033[0m" + else + echo "-----------------------------------------------" + echo -e 备份文件共有"\033[32m$(wc -l <${config_path}.bak)\033[0m"行内容,当前文件共有"\033[32m$(wc -l <${config_path})\033[0m"行内容 + read -p "确认还原配置文件?此操作不可逆![1/0] > " res + if [ "$res" = '1' ]; then + mv ${config_path}.bak ${config_path} + echo "----------------------------------------------" + echo -e "\033[32m配置文件已还原!请手动重启服务!\033[0m" + sleep 1 + break + else + echo "-----------------------------------------------" + echo -e "\033[31m操作已取消!返回上级菜单!\033[0m" + sleep 1 + fi + fi + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[36m如果6-1或者6-2无法正确获取配置文件时可以尝试使用\033[0m" + echo -e " 1 使用自动UA" + echo -e " 2 不使用UA" + echo -e " 3 使用自定义UA:\033[32m$user_agent\033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + user_agent='' + ;; + 1) + user_agent='auto' + ;; + 2) + user_agent='none' + ;; + 3) + read -p "请输入自定义UA(不要包含空格和特殊符号!) > " text + [ -n "$text" ] && user_agent="$text" + ;; + *) + errornum + ;; + esac + [ "$num" -le 3 ] && setconfig user_agent "$user_agent" + ;; + *) + errornum + sleep 1 + break + ;; + esac + done } diff --git a/scripts/menus/9_upgrade.sh b/scripts/menus/9_upgrade.sh index 387dbe21..042a96f9 100644 --- a/scripts/menus/9_upgrade.sh +++ b/scripts/menus/9_upgrade.sh @@ -8,10 +8,10 @@ __IS_MODULE_9_UPGRADE_LOADED=1 . "$CRASHDIR"/libs/check_cpucore.sh . "$CRASHDIR"/libs/web_get_bin.sh -error_down(){ - echo -e "\033[33m请尝试切换至其他安装源后重新下载!\033[0m" - echo -e "或者参考 \033[32;4mhttps://juewuy.github.io/bdaz\033[0m 进行本地安装!" - sleep 1 +error_down() { + echo -e "\033[33m请尝试切换至其他安装源后重新下载!\033[0m" + echo -e "或者参考 \033[32;4mhttps://juewuy.github.io/bdaz\033[0m 进行本地安装!" + sleep 1 } # 更新/卸载功能菜单 @@ -46,7 +46,7 @@ upgrade() { echo "-----------------------------------------------" read -p "请输入对应数字 > " num case "$num" in - ""|0) + "" | 0) break ;; 1) @@ -97,136 +97,136 @@ upgrade() { ;; *) errornum - sleep 1 - break + sleep 1 + break ;; esac done } #检查更新 -checkupdate(){ - echo -ne "\033[32m正在检查更新!\033[0m\r" - get_bin "$TMPDIR"/version_new version echooff - [ "$?" = "0" ] && { - version_new=$(cat "$TMPDIR"/version_new) - get_bin "$TMPDIR"/version_new bin/version echooff - } - if [ "$?" = "0" ];then - . "$TMPDIR"/version_new 2>/dev/null - else - echo -e "\033[31m检查更新失败!请尝试切换其他安装源!\033[0m" - setserver - [ "$checkupdate" = false ] || checkupdate - fi - rm -rf "$TMPDIR"/version_new +checkupdate() { + echo -ne "\033[32m正在检查更新!\033[0m\r" + get_bin "$TMPDIR"/version_new version echooff + [ "$?" = "0" ] && { + version_new=$(cat "$TMPDIR"/version_new) + get_bin "$TMPDIR"/version_new bin/version echooff + } + if [ "$?" = "0" ]; then + . "$TMPDIR"/version_new 2>/dev/null + else + echo -e "\033[31m检查更新失败!请尝试切换其他安装源!\033[0m" + setserver + [ "$checkupdate" = false ] || checkupdate + fi + rm -rf "$TMPDIR"/version_new } #更新脚本 -getscripts(){ - get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz - if [ "$?" != "0" ];then - echo -e "\033[33m文件下载失败!\033[0m" - error_down - else - "$CRASHDIR"/start.sh stop 2>/dev/null - #解压 - echo "-----------------------------------------------" - echo "开始解压文件!" - mkdir -p "$CRASHDIR" > /dev/null - tar -zxf "$TMPDIR/ShellCrash.tar.gz" ${tar_para} -C "$CRASHDIR"/ - if [ $? -ne 0 ];then - echo -e "\033[33m文件解压失败!\033[0m" - error_down - else - . "$CRASHDIR"/init.sh >/dev/null - echo -e "\033[32m脚本更新成功!\033[0m" - fi - fi - rm -rf "$TMPDIR"/ShellCrash.tar.gz - exit +getscripts() { + get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz + if [ "$?" != "0" ]; then + echo -e "\033[33m文件下载失败!\033[0m" + error_down + else + "$CRASHDIR"/start.sh stop 2>/dev/null + #解压 + echo "-----------------------------------------------" + echo "开始解压文件!" + mkdir -p "$CRASHDIR" >/dev/null + tar -zxf "$TMPDIR/ShellCrash.tar.gz" ${tar_para} -C "$CRASHDIR"/ + if [ $? -ne 0 ]; then + echo -e "\033[33m文件解压失败!\033[0m" + error_down + else + . "$CRASHDIR"/init.sh >/dev/null + echo -e "\033[32m脚本更新成功!\033[0m" + fi + fi + rm -rf "$TMPDIR"/ShellCrash.tar.gz + exit } -setscripts(){ - echo "-----------------------------------------------" - echo -e "当前脚本版本为:\033[33m $versionsh_l \033[0m" - echo -e "最新脚本版本为:\033[32m $version_new \033[0m" - echo -e "注意更新时会停止服务!" - echo "-----------------------------------------------" - read -p "是否更新脚本?[1/0] > " res - if [ "$res" = '1' ]; then - #下载更新 - getscripts - #提示 - echo "-----------------------------------------------" - echo -e "\033[32m管理脚本更新成功!\033[0m" - echo "-----------------------------------------------" - exit; - fi +setscripts() { + echo "-----------------------------------------------" + echo -e "当前脚本版本为:\033[33m $versionsh_l \033[0m" + echo -e "最新脚本版本为:\033[32m $version_new \033[0m" + echo -e "注意更新时会停止服务!" + echo "-----------------------------------------------" + read -p "是否更新脚本?[1/0] > " res + if [ "$res" = '1' ]; then + #下载更新 + getscripts + #提示 + echo "-----------------------------------------------" + echo -e "\033[32m管理脚本更新成功!\033[0m" + echo "-----------------------------------------------" + exit + fi } #更新内核 -setcpucore(){ #手动设置内核架构 - cpucore_list="armv5 armv7 arm64 386 amd64 mipsle-softfloat mipsle-hardfloat mips-softfloat" - echo "-----------------------------------------------" - echo -e "\033[31m仅适合脚本无法正确识别核心或核心无法正常运行时使用!\033[0m" - echo -e "当前可供在线下载的处理器架构为:" - echo $cpucore_list | awk -F " " '{for(i=1;i<=NF;i++) {print i" "$i }}' - echo -e "不知道如何获取核心版本?请参考:\033[36;4mhttps://juewuy.github.io/bdaz\033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - [ -n "$num" ] && setcpucore=$(echo $cpucore_list | awk '{print $"'"$num"'"}' ) - if [ -z "$setcpucore" ];then - echo -e "\033[31m请输入正确的处理器架构!\033[0m" - sleep 1 - cpucore="" - else - cpucore=$setcpucore - setconfig cpucore $cpucore - fi +setcpucore() { #手动设置内核架构 + cpucore_list="armv5 armv7 arm64 386 amd64 mipsle-softfloat mipsle-hardfloat mips-softfloat" + echo "-----------------------------------------------" + echo -e "\033[31m仅适合脚本无法正确识别核心或核心无法正常运行时使用!\033[0m" + echo -e "当前可供在线下载的处理器架构为:" + echo "$cpucore_list" | awk -F " " '{for(i=1;i<=NF;i++) {print i" "$i }}' + echo -e "不知道如何获取核心版本?请参考:\033[36;4mhttps://juewuy.github.io/bdaz\033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + [ -n "$num" ] && setcpucore=$(echo "$cpucore_list" | awk '{print $"'"$num"'"}') + if [ -z "$setcpucore" ]; then + echo -e "\033[31m请输入正确的处理器架构!\033[0m" + sleep 1 + cpucore="" + else + cpucore=$setcpucore + setconfig cpucore "$cpucore" + fi } -setcoretype(){ #手动指定内核类型 - echo "$crashcore" | grep -q 'singbox' && core_old=singbox || core_old=clash - echo -e "\033[33m请确认该自定义内核的类型:\033[0m" - echo -e " 1 Clash基础内核" - echo -e " 2 Clash-Premium内核" - echo -e " 3 Mihomo(Meta)内核" - echo -e " 4 Sing-Box内核" - echo -e " 5 Sing-Box-reF1nd内核" - read -p "请输入对应数字 > " num - case "$num" in - 2) crashcore=clashpre ;; - 3) crashcore=meta ;; - 4) crashcore=singbox ;; - 5) crashcore=singboxr ;; - *) crashcore=clash ;; - esac - echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash +setcoretype() { #手动指定内核类型 + echo "$crashcore" | grep -q 'singbox' && core_old=singbox || core_old=clash + echo -e "\033[33m请确认该自定义内核的类型:\033[0m" + echo -e " 1 Clash基础内核" + echo -e " 2 Clash-Premium内核" + echo -e " 3 Mihomo(Meta)内核" + echo -e " 4 Sing-Box内核" + echo -e " 5 Sing-Box-reF1nd内核" + read -p "请输入对应数字 > " num + case "$num" in + 2) crashcore=clashpre ;; + 3) crashcore=meta ;; + 4) crashcore=singbox ;; + 5) crashcore=singboxr ;; + *) crashcore=clash ;; + esac + echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash } -switch_core(){ #clash与singbox内核切换 - #singbox和clash内核切换时提示是否保留文件 - [ "$core_new" != "$core_old" ] && { - [ "$dns_mod" = "redir_host" ] && [ "$core_old" = "clash" ] && setconfig dns_mod mix #singbox自动切换dns - [ "$dns_mod" = "mix" ] && [ "$crashcore" = 'clash' -o "$crashcore" = 'clashpre' ] && setconfig dns_mod redir_host #singbox自动切换dns - echo -e "\033[33m已从$core_old内核切换至$core_new内核\033[0m" - echo -e "\033[33m二者Geo数据库及yaml/json配置文件不通用\033[0m" - read -p "是否保留相关数据库文件?(1/0) > " res - [ "$res" = '0' ] && { - [ "$core_old" = "clash" ] && { - geodate='Country.mmdb GeoSite.dat ruleset/*.mrs ruleset/*.yaml ruleset/*.yml' - geodate_v='Country_v cn_mini_v geosite_v mrs_geosite_cn_v' - } - [ "$core_old" = "singbox" ] && { - geodate='geoip.db geosite.db ruleset/*.srs ruleset/*.json' - geodate_v='geoip_cn_v geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v' - } - for text in ${geodate} ;do - rm -rf "$CRASHDIR"/${text} - done - for text in ${geodate_v} ;do - setconfig "$text" - done - } - } +switch_core() { #clash与singbox内核切换 + #singbox和clash内核切换时提示是否保留文件 + [ "$core_new" != "$core_old" ] && { + [ "$dns_mod" = "redir_host" ] && [ "$core_old" = "clash" ] && setconfig dns_mod mix #singbox自动切换dns + [ "$dns_mod" = "mix" ] && [ "$crashcore" = 'clash' -o "$crashcore" = 'clashpre' ] && setconfig dns_mod redir_host #singbox自动切换dns + echo -e "\033[33m已从$core_old内核切换至$core_new内核\033[0m" + echo -e "\033[33m二者Geo数据库及yaml/json配置文件不通用\033[0m" + read -p "是否保留相关数据库文件?(1/0) > " res + [ "$res" = '0' ] && { + [ "$core_old" = "clash" ] && { + geodate='Country.mmdb GeoSite.dat ruleset/*.mrs ruleset/*.yaml ruleset/*.yml' + geodate_v='Country_v cn_mini_v geosite_v mrs_geosite_cn_v' + } + [ "$core_old" = "singbox" ] && { + geodate='geoip.db geosite.db ruleset/*.srs ruleset/*.json' + geodate_v='geoip_cn_v geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v' + } + for text in ${geodate}; do + rm -rf "$CRASHDIR"/${text} + done + for text in ${geodate_v}; do + setconfig "$text" + done + } + } } # 下载内核文件 @@ -254,8 +254,8 @@ getcore() { ;; *) echo -e "\033[31m核心文件下载成功但校验失败!请尝试手动指定CPU版本\033[0m" - rm -rf ${TMPDIR}/core_new - rm -rf ${TMPDIR}/core_new.tar.gz + rm -rf "${TMPDIR}"/core_new + rm -rf "${TMPDIR}"/core_new.tar.gz setcpucore ;; esac @@ -265,12 +265,12 @@ checkcustcore() { [ "$api_tag" = "latest" ] && api_url=latest || api_url="tags/$api_tag" # 通过githubapi获取内核信息 echo -e "\033[32m正在获取内核文件链接!\033[0m" - webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url} + webget "$TMPDIR"/github_api https://api.github.com/repos/"${project}"/releases/"${api_url}" if [ "$?" = 0 ]; then release_tag=$(cat "$TMPDIR"/github_api | grep '"tag_name":' | awk -F '"' '{print $4}') release_date=$(cat "$TMPDIR"/github_api | grep '"published_at":' | awk -F '"' '{print $4}') update_date=$(cat "$TMPDIR"/github_api | grep '"updated_at":' | head -n 1 | awk -F '"' '{print $4}') - [ -n "$(echo $cpucore | grep mips)" ] && cpu_type=mips || cpu_type=$cpucore + [ -n "$(echo "$cpucore" | grep mips)" ] && cpu_type=mips || cpu_type=$cpucore cat "$TMPDIR"/github_api | grep "browser_download_url" | grep -oE "https://github.com/${project}/releases/download.*linux.*${cpu_type}.*\.gz\"$" | sed 's/"//' >"$TMPDIR"/core.list rm -rf "$TMPDIR"/github_api @@ -380,32 +380,32 @@ setcustcore() { done } -setziptype(){ - echo "-----------------------------------------------" - echo -e "请选择内核内核分支及压缩方式:\033[0m" - echo "-----------------------------------------------" - echo -e " 1 \033[36m最简编译release版本,upx压缩\033[0m-不支持Gvisor,Tailscale,Wireguard,NaiveProxy" - echo -e " 2 \033[32m标准编译release版本,tar.gz压缩\033[0m-完整支持脚本全部内置功能" - echo -e " 3 \033[33m完整编译alpha版本,gz压缩\033[0m-占用可能略高,稳定性自测" - echo "-----------------------------------------------" - echo " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - zip_type='upx' - ;; - 2) - zip_type='tar.gz' - ;; - 3) - zip_type='gz' - ;; - *) - errornum - ;; - esac - setconfig zip_type "$zip_type" +setziptype() { + echo "-----------------------------------------------" + echo -e "请选择内核内核分支及压缩方式:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[36m最简编译release版本,upx压缩\033[0m-不支持Gvisor,Tailscale,Wireguard,NaiveProxy" + echo -e " 2 \033[32m标准编译release版本,tar.gz压缩\033[0m-完整支持脚本全部内置功能" + echo -e " 3 \033[33m完整编译alpha版本,gz压缩\033[0m-占用可能略高,稳定性自测" + echo "-----------------------------------------------" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + zip_type='upx' + ;; + 2) + zip_type='tar.gz' + ;; + 3) + zip_type='gz' + ;; + *) + errornum + ;; + esac + setconfig zip_type "$zip_type" } # 内核选择菜单 @@ -415,7 +415,7 @@ setcore() { [ -z "$crashcore" ] && crashcore="unknow" [ -z "$zip_type" ] && zip_type="tar.gz" echo "$crashcore" | grep -q 'singbox' && core_old=singbox || core_old=clash - [ -n "$custcorelink" ] && custcore="$(echo $custcorelink | sed 's#.*github.com##; s#/releases/download/#@#; s#-linux.*$##')" + [ -n "$custcorelink" ] && custcore="$(echo "$custcorelink" | sed 's#.*github.com##; s#/releases/download/#@#; s#-linux.*$##')" ### echo "-----------------------------------------------" [ -z "$cpucore" ] && check_cpucore @@ -505,53 +505,53 @@ setcore() { } #数据库 -getgeo(){ #下载Geo文件 - #生成链接 - echo "-----------------------------------------------" - echo "正在从服务器获取数据库文件…………" - get_bin "$TMPDIR"/${geoname} bin/geodata/$geotype - if [ "$?" = "1" ];then - echo "-----------------------------------------------" - echo -e "\033[31m文件下载失败!\033[0m" - error_down - else - echo "$geoname" | grep -Eq '.mrs|.srs|.tar.gz' && { - geofile='ruleset/' - [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset - } - if echo "$geoname" | grep -Eq '.tar.gz';then - tar -zxf "$TMPDIR"/${geoname} ${tar_para} -C "$BINDIR"/${geofile} > /dev/null - [ $? -ne 0 ] && echo "文件解压失败!" && rm -rf "$TMPDIR"/${geoname} && exit 1 - rm -rf "$TMPDIR"/${geoname} - else - mv -f "$TMPDIR"/${geoname} "$BINDIR"/${geofile}${geoname} - fi - echo "-----------------------------------------------" - echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" - geo_v="$(echo $geotype | awk -F "." '{print $1}')_v" - setconfig $geo_v $GeoIP_v - fi - sleep 1 +getgeo() { #下载Geo文件 + #生成链接 + echo "-----------------------------------------------" + echo "正在从服务器获取数据库文件......" + get_bin "$TMPDIR"/"${geoname}" bin/geodata/"$geotype" + if [ "$?" = "1" ]; then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + error_down + else + echo "$geoname" | grep -Eq '.mrs|.srs|.tar.gz' && { + geofile='ruleset/' + [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset + } + if echo "$geoname" | grep -Eq '.tar.gz'; then + tar -zxf "$TMPDIR"/"${geoname}" "${tar_para}" -C "$BINDIR"/"${geofile}" >/dev/null + [ $? -ne 0 ] && echo "文件解压失败!" && rm -rf "$TMPDIR"/${geoname} && exit 1 + rm -rf "$TMPDIR"/${geoname} + else + mv -f "$TMPDIR"/"${geoname}" "$BINDIR"/"${geofile}""${geoname}" + fi + echo "-----------------------------------------------" + echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" + geo_v="$(echo "$geotype" | awk -F "." '{print $1}')_v" + setconfig "$geo_v" "$GeoIP_v" + fi + sleep 1 } -getcustgeo(){ - echo "-----------------------------------------------" - echo "正在获取数据库文件…………" - webget "$TMPDIR"/$geoname $custgeolink - if [ "$?" = "1" ];then - echo "-----------------------------------------------" - echo -e "\033[31m文件下载失败!\033[0m" - error_down - else - echo "$geoname" | grep -Eq '.mrs|.srs' && { - geofile='ruleset/' - [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset - } - mv -f "$TMPDIR"/${geoname} "$BINDIR"/${geofile}${geoname} - echo "-----------------------------------------------" - echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" - fi - sleep 1 +getcustgeo() { + echo "-----------------------------------------------" + echo "正在获取数据库文件......" + webget "$TMPDIR"/"$geoname" "$custgeolink" + if [ "$?" = "1" ]; then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + error_down + else + echo "$geoname" | grep -Eq '.mrs|.srs' && { + geofile='ruleset/' + [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset + } + mv -f "$TMPDIR"/"${geoname}" "$BINDIR"/"${geofile}""${geoname}" + echo "-----------------------------------------------" + echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" + fi + sleep 1 } checkcustgeo() { @@ -578,9 +578,9 @@ checkcustgeo() { [1-99]) if [ "$num" -le "$(wc -l <"$TMPDIR"/geo.list)" ]; then geotype=$(sed -n "$num"p "$TMPDIR"/geo.list) - [ -n "$(echo $geotype | grep -oiE 'GeoSite.*dat')" ] && geoname=GeoSite.dat - [ -n "$(echo $geotype | grep -oiE 'Country.*mmdb')" ] && geoname=Country.mmdb - [ -n "$(echo $geotype | grep -oiE '.*(.srs|.mrs)')" ] && geoname=$geotype + [ -n "$(echo "$geotype" | grep -oiE 'GeoSite.*dat')" ] && geoname=GeoSite.dat + [ -n "$(echo "$geotype" | grep -oiE 'Country.*mmdb')" ] && geoname=Country.mmdb + [ -n "$(echo "$geotype" | grep -oiE '.*(.srs|.mrs)')" ] && geoname=$geotype custgeolink=https://github.com/${project}/releases/download/${release_tag}/${geotype} getcustgeo else @@ -604,151 +604,151 @@ checkcustgeo() { # 下载自定义数据库文件 setcustgeo() { - while true; do - rm -rf "$TMPDIR"/geo.list - echo "-----------------------------------------------" - echo -e "\033[36m此处数据库均源自互联网采集,此处致谢各位开发者!\033[0m" - echo -e "\033[32m请点击或复制链接前往项目页面查看具体说明!\033[0m" - echo -e "\033[31m自定义数据库不支持定时任务及小闪存模式!\033[0m" - echo -e "\033[33m如遇到网络错误请先启动ShellCrash服务!\033[0m" - echo -e "\033[0m请选择需要更新的数据库项目来源:\033[0m" - echo "-----------------------------------------------" - echo -e " 1 \033[36;4mhttps://github.com/MetaCubeX/meta-rules-dat\033[0m (仅限Clash/Mihomo)" - echo -e " 2 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Clash/Mihomo)" - echo -e " 3 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限SingBox-srs)" - echo -e " 4 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Mihomo-mrs)" - echo -e " 5 \033[36;4mhttps://github.com/Loyalsoldier/geoip\033[0m (仅限Clash-GeoIP)" - echo "-----------------------------------------------" - echo -e " 9 \033[33m自定义数据库链接 \033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - ""|0) - break - ;; - 1) - project=MetaCubeX/meta-rules-dat - api_tag=latest - checkcustgeo - ;; - 2) - project=DustinWin/ruleset_geodata - api_tag=mihomo-geodata - checkcustgeo - ;; - 3) - project=DustinWin/ruleset_geodata - api_tag=sing-box-ruleset - checkcustgeo - ;; - 4) - project=DustinWin/ruleset_geodata - api_tag=mihomo-ruleset - checkcustgeo - ;; - 5) - project=Loyalsoldier/geoip - api_tag=latest - checkcustgeo - ;; - 9) - read -p "请输入自定义数据库的链接地址 > " link - [ -n "$link" ] && custgeolink="$link" - getgeo - ;; - *) - errornum - sleep 1 - break - ;; - esac - done + while true; do + rm -rf "$TMPDIR"/geo.list + echo "-----------------------------------------------" + echo -e "\033[36m此处数据库均源自互联网采集,此处致谢各位开发者!\033[0m" + echo -e "\033[32m请点击或复制链接前往项目页面查看具体说明!\033[0m" + echo -e "\033[31m自定义数据库不支持定时任务及小闪存模式!\033[0m" + echo -e "\033[33m如遇到网络错误请先启动ShellCrash服务!\033[0m" + echo -e "\033[0m请选择需要更新的数据库项目来源:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[36;4mhttps://github.com/MetaCubeX/meta-rules-dat\033[0m (仅限Clash/Mihomo)" + echo -e " 2 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Clash/Mihomo)" + echo -e " 3 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限SingBox-srs)" + echo -e " 4 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Mihomo-mrs)" + echo -e " 5 \033[36;4mhttps://github.com/Loyalsoldier/geoip\033[0m (仅限Clash-GeoIP)" + echo "-----------------------------------------------" + echo -e " 9 \033[33m自定义数据库链接 \033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + "" | 0) + break + ;; + 1) + project=MetaCubeX/meta-rules-dat + api_tag=latest + checkcustgeo + ;; + 2) + project=DustinWin/ruleset_geodata + api_tag=mihomo-geodata + checkcustgeo + ;; + 3) + project=DustinWin/ruleset_geodata + api_tag=sing-box-ruleset + checkcustgeo + ;; + 4) + project=DustinWin/ruleset_geodata + api_tag=mihomo-ruleset + checkcustgeo + ;; + 5) + project=Loyalsoldier/geoip + api_tag=latest + checkcustgeo + ;; + 9) + read -p "请输入自定义数据库的链接地址 > " link + [ -n "$link" ] && custgeolink="$link" + getgeo + ;; + *) + errornum + sleep 1 + break + ;; + esac + done } setgeo() { - while true; do - . $CFG_PATH > /dev/null - [ -n "$cn_mini_v" ] && geo_type_des=精简版 || geo_type_des=全球版 - echo "-----------------------------------------------" - echo -e "\033[36m请选择需要更新的Geo数据库文件:\033[0m" - echo -e "\033[36mMihomo内核和SingBox内核的数据库文件不通用\033[0m" - echo -e "在线数据库最新版本(每日同步上游):\033[32m$GeoIP_v\033[0m" - echo "-----------------------------------------------" - echo -e " 1 CN-IP绕过文件(约0.1mb) \033[33m$china_ip_list_v\033[0m" - echo -e " 2 CN-IPV6绕过文件(约30kb) \033[33m$china_ipv6_list_v\033[0m" - echo "-----------------------------------------------" - echo -e " 3 Mihomo精简版GeoIP_cn数据库(约0.1mb) \033[33m$cn_mini_v\033[0m" - echo -e " 4 Mihomo完整版GeoSite数据库(约5mb) \033[33m$geosite_v\033[0m" - echo "-----------------------------------------------" - echo -e " 5 Mihomo-mrs数据库常用包(约1mb,非必要勿用)" - echo -e " 6 Singbox-srs数据库常用包(约0.8mb,非必要勿用)" - echo "-----------------------------------------------" - echo -e " 8 \033[32m自定义数据库文件\033[0m" - echo -e " 9 \033[31m清理数据库文件\033[0m" - echo " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - ""|0) - break - ;; - 1) - geotype=china_ip_list.txt - geoname=cn_ip.txt - getgeo - ;; - 2) - geotype=china_ipv6_list.txt - geoname=cn_ipv6.txt - getgeo - ;; - 3) - geotype=cn_mini.mmdb - geoname=Country.mmdb - getgeo - ;; - 4) - geotype=geosite.dat - geoname=GeoSite.dat - getgeo - ;; - 5) - geotype=mrs.tar.gz - geoname=mrs.tar.gz - getgeo - ;; - 6) - geotype=srs.tar.gz - geoname=srs.tar.gz - getgeo - ;; - 8) - setcustgeo - ;; - 9) - echo "-----------------------------------------------" - echo -e "\033[33m这将清理$CRASHDIR目录及/ruleset目录下所有数据库文件!\033[0m" - echo -e "\033[36m清理后启动服务即可自动下载所需文件~\033[0m" - echo "-----------------------------------------------" - read -p "确认清理?[1/0] > " res - [ "$res" = '1' ] && { - for file in cn_ip.txt cn_ipv6.txt Country.mmdb GeoSite.dat geoip.db geosite.db;do - rm -rf $CRASHDIR/$file - done - for var in Country_v cn_mini_v china_ip_list_v china_ipv6_list_v geosite_v geoip_cn_v geosite_cn_v mrs_geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v mrs_v srs_v;do - setconfig $var - done - rm -rf $CRASHDIR/ruleset/* - echo -e "\033[33m所有数据库文件均已清理!\033[0m" - sleep 1 - } - ;; - *) - errornum - sleep 1 - break - ;; - esac -done + while true; do + . $CFG_PATH >/dev/null + [ -n "$cn_mini_v" ] && geo_type_des=精简版 || geo_type_des=全球版 + echo "-----------------------------------------------" + echo -e "\033[36m请选择需要更新的Geo数据库文件:\033[0m" + echo -e "\033[36mMihomo内核和SingBox内核的数据库文件不通用\033[0m" + echo -e "在线数据库最新版本(每日同步上游):\033[32m$GeoIP_v\033[0m" + echo "-----------------------------------------------" + echo -e " 1 CN-IP绕过文件(约0.1mb) \033[33m$china_ip_list_v\033[0m" + echo -e " 2 CN-IPV6绕过文件(约30kb) \033[33m$china_ipv6_list_v\033[0m" + echo "-----------------------------------------------" + echo -e " 3 Mihomo精简版GeoIP_cn数据库(约0.1mb) \033[33m$cn_mini_v\033[0m" + echo -e " 4 Mihomo完整版GeoSite数据库(约5mb) \033[33m$geosite_v\033[0m" + echo "-----------------------------------------------" + echo -e " 5 Mihomo-mrs数据库常用包(约1mb,非必要勿用)" + echo -e " 6 Singbox-srs数据库常用包(约0.8mb,非必要勿用)" + echo "-----------------------------------------------" + echo -e " 8 \033[32m自定义数据库文件\033[0m" + echo -e " 9 \033[31m清理数据库文件\033[0m" + echo " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + "" | 0) + break + ;; + 1) + geotype=china_ip_list.txt + geoname=cn_ip.txt + getgeo + ;; + 2) + geotype=china_ipv6_list.txt + geoname=cn_ipv6.txt + getgeo + ;; + 3) + geotype=cn_mini.mmdb + geoname=Country.mmdb + getgeo + ;; + 4) + geotype=geosite.dat + geoname=GeoSite.dat + getgeo + ;; + 5) + geotype=mrs.tar.gz + geoname=mrs.tar.gz + getgeo + ;; + 6) + geotype=srs.tar.gz + geoname=srs.tar.gz + getgeo + ;; + 8) + setcustgeo + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[33m这将清理$CRASHDIR目录及/ruleset目录下所有数据库文件!\033[0m" + echo -e "\033[36m清理后启动服务即可自动下载所需文件~\033[0m" + echo "-----------------------------------------------" + read -p "确认清理?[1/0] > " res + [ "$res" = '1' ] && { + for file in cn_ip.txt cn_ipv6.txt Country.mmdb GeoSite.dat geoip.db geosite.db; do + rm -rf $CRASHDIR/$file + done + for var in Country_v cn_mini_v china_ip_list_v china_ipv6_list_v geosite_v geoip_cn_v geosite_cn_v mrs_geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v mrs_v srs_v; do + setconfig $var + done + rm -rf "$CRASHDIR"/ruleset/* + echo -e "\033[33m所有数据库文件均已清理!\033[0m" + sleep 1 + } + ;; + *) + errornum + sleep 1 + break + ;; + esac + done } #Dashboard @@ -765,17 +765,17 @@ getdb() { return 1 else echo -e "\033[33m下载成功,正在解压文件!\033[0m" - mkdir -p $dbdir >/dev/null - tar -zxf "$TMPDIR/clashdb.tar.gz" ${tar_para} -C $dbdir >/dev/null + mkdir -p "$dbdir" >/dev/null + tar -zxf "$TMPDIR/clashdb.tar.gz" "${tar_para}" -C "$dbdir" >/dev/null [ $? -ne 0 ] && echo "文件解压失败!" && rm -rf "$TMPDIR"/clashfm.tar.gz && exit 1 #修改默认host和端口 if [ "$db_type" = "clashdb" -o "$db_type" = "meta_db" -o "$db_type" = "zashboard" ]; then - sed -i "s/127.0.0.1/${host}/g" $dbdir/assets/*.js - sed -i "s/9090/${db_port}/g" $dbdir/assets/*.js + sed -i "s/127.0.0.1/${host}/g" "$dbdir"/assets/*.js + sed -i "s/9090/${db_port}/g" "$dbdir"/assets/*.js elif [ "$db_type" = "meta_xd" ]; then - sed -i "s/127.0.0.1:9090/${host}:${db_port}/g" $dbdir/_nuxt/*.js + sed -i "s/127.0.0.1:9090/${host}:${db_port}/g" "$dbdir"/_nuxt/*.js else - sed -i "s/127.0.0.1:9090/${host}:${db_port}/g" $dbdir/*.html + sed -i "s/127.0.0.1:9090/${host}:${db_port}/g" "$dbdir"/*.html fi #写入配置文件 setconfig hostdir "'$hostdir'" @@ -907,194 +907,194 @@ setdb() { } #根证书 -getcrt(){ - echo "-----------------------------------------------" - echo "正在连接服务器获取安装文件…………" - get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt - if [ "$?" = "1" ];then - echo "-----------------------------------------------" - echo -e "\033[31m文件下载失败!\033[0m" - error_down - else - echo "-----------------------------------------------" - [ "$systype" = 'mi_snapshot' ] && cp -f "$TMPDIR"/ca-certificates.crt $CRASHDIR/tools #镜像化设备特殊处理 - [ -f $openssldir/certs ] && rm -rf $openssldir/certs #如果certs不是目录而是文件则删除并创建目录 - mkdir -p $openssldir/certs - mv -f "$TMPDIR"/ca-certificates.crt $crtdir - webget /dev/null https://baidu.com echooff rediron skipceroff - if [ "$?" = "1" ];then - export CURL_CA_BUNDLE=$crtdir - echo "export CURL_CA_BUNDLE=$crtdir" >> /etc/profile - fi - echo -e "\033[32m证书安装成功!\033[0m" - sleep 1 - fi +getcrt() { + echo "-----------------------------------------------" + echo "正在连接服务器获取安装文件......" + get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt + if [ "$?" = "1" ]; then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + error_down + else + echo "-----------------------------------------------" + [ "$systype" = 'mi_snapshot' ] && cp -f "$TMPDIR"/ca-certificates.crt "$CRASHDIR"/tools #镜像化设备特殊处理 + [ -f "$openssldir"/certs ] && rm -rf "$openssldir"/certs #如果certs不是目录而是文件则删除并创建目录 + mkdir -p "$openssldir"/certs + mv -f "$TMPDIR"/ca-certificates.crt "$crtdir" + webget /dev/null https://baidu.com echooff rediron skipceroff + if [ "$?" = "1" ]; then + export CURL_CA_BUNDLE="$crtdir" + echo "export CURL_CA_BUNDLE=$crtdir" >>/etc/profile + fi + echo -e "\033[32m证书安装成功!\033[0m" + sleep 1 + fi } -setcrt(){ - openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" - if [ -d "$openssldir/certs/" ];then - crtdir="$openssldir/certs/ca-certificates.crt" - else - crtdir="/etc/ssl/certs/ca-certificates.crt" - fi - if [ -n "$openssldir" ];then - echo "-----------------------------------------------" - echo -e "\033[36m安装/更新本地根证书文件(ca-certificates.crt)\033[0m" - echo -e "\033[33m用于解决证书校验错误,x509报错等问题\033[0m" - echo -e "\033[31m无上述问题的设备请勿使用!\033[0m" - echo "-----------------------------------------------" - [ -f "$crtdir" ] && echo -e "\033[33m检测到系统已经存在根证书文件($crtdir)了!\033[0m\n-----------------------------------------------" - read -p "是否覆盖更新?(1/0) > " res +setcrt() { + openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" + if [ -d "$openssldir/certs/" ]; then + crtdir="$openssldir/certs/ca-certificates.crt" + else + crtdir="/etc/ssl/certs/ca-certificates.crt" + fi + if [ -n "$openssldir" ]; then + echo "-----------------------------------------------" + echo -e "\033[36m安装/更新本地根证书文件(ca-certificates.crt)\033[0m" + echo -e "\033[33m用于解决证书校验错误,x509报错等问题\033[0m" + echo -e "\033[31m无上述问题的设备请勿使用!\033[0m" + echo "-----------------------------------------------" + [ -f "$crtdir" ] && echo -e "\033[33m检测到系统已经存在根证书文件($crtdir)了!\033[0m\n-----------------------------------------------" + read -p "是否覆盖更新?(1/0) > " res - if [ -z "$res" ];then - errornum - elif [ "$res" = '0' ]; then - i= - elif [ "$res" = '1' ]; then - getcrt - else - errornum - fi - else - echo "-----------------------------------------------" - echo -e "\033[33m设备可能尚未安装openssl,无法安装证书文件!\033[0m" - sleep 1 - fi + if [ -z "$res" ]; then + errornum + elif [ "$res" = '0' ]; then + i= + elif [ "$res" = '1' ]; then + getcrt + else + errornum + fi + else + echo "-----------------------------------------------" + echo -e "\033[33m设备可能尚未安装openssl,无法安装证书文件!\033[0m" + sleep 1 + fi } # 写入配置文件 saveserver() { - setconfig update_url "'$update_url'" - setconfig url_id $url_id - setconfig release_type $release_type - version_new='' - echo "-----------------------------------------------" - echo -e "\033[32m源地址切换成功!\033[0m" + setconfig update_url "'$update_url'" + setconfig url_id "$url_id" + setconfig release_type "$release_type" + version_new='' + echo "-----------------------------------------------" + echo -e "\033[32m源地址切换成功!\033[0m" } # 安装源 setserver() { - while true; do - [ -z "$release_type" ] && release_name=未指定 - [ -n "$release_type" ] && release_name="$release_type(回退)" - [ "$release_type" = stable ] && release_name=稳定版 - [ "$release_type" = master ] && release_name=公测版 - [ "$release_type" = dev ] && release_name=开发版 - [ -n "$url_id" ] && url_name=$(grep "$url_id" "$CRASHDIR"/configs/servers.list 2>/dev/null | awk '{print $2}') || url_name="$update_url" - - echo "-----------------------------------------------" - echo -e "\033[30;47m切换ShellCrash版本及更新源地址\033[0m" - echo -e "当前版本:\033[4;33m$release_name\033[0m 当前源:\033[4;32m$url_name\033[0m" - echo "-----------------------------------------------" - grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | awk '{print " "NR" "$2}' - echo "-----------------------------------------------" - echo -e " a 切换至\033[32m稳定版-stable\033[0m" - echo -e " b 切换至\033[36m公测版-master\033[0m" - echo -e " c 切换至\033[33m开发版-dev\033[0m" - echo "-----------------------------------------------" - echo -e " d 自定义源地址(用于本地源或自建源)" - echo -e " e \033[31m版本回退\033[0m" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应字母或数字 > " num - case "$num" in - ""|0) - checkupdate=false - break - ;; - [1-99]) - url_id_new=$(grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | sed -n "$num"p | awk '{print $1}') - if [ -z "$url_id_new" ];then - errornum - sleep 1 - continue - elif [ "$url_id_new" -ge 200 ];then - update_url=$(grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | sed -n "$num"p | awk '{print $3}') - url_id='' - saveserver - break - else - url_id=$url_id_new - update_url='' - saveserver - break - fi - unset url_id_new - ;; - a) - release_type=stable - [ -z "$url_id" ] && url_id=101 - saveserver - ;; - b) - release_type=master - [ -z "$url_id" ] && url_id=101 - saveserver - ;; - c) - echo "-----------------------------------------------" - echo -e "\033[33m开发版未经过妥善测试,可能依然存在大量bug!!!\033[0m" - echo -e "\033[36m如果你没有足够的耐心或者测试经验,切勿使用此版本!\033[0m" - echo -e "请务必加入我们的讨论组:\033[32;4mhttps://t.me/ShellClash\033[0m" - read -p "是否依然切换到开发版?(1/0) > " res - if [ "$res" = 1 ];then - release_type=dev - [ -z "$url_id" ] && url_id=101 - saveserver - fi - ;; - d) - echo "-----------------------------------------------" - read -p "请输入个人源路径 > " update_url - if [ -z "$update_url" ];then - echo "-----------------------------------------------" - echo -e "\033[31m取消输入,返回上级菜单\033[0m" - else - url_id='' - release_type='' - saveserver - fi - ;; - e) - echo "-----------------------------------------------" - if [ -n "$url_id" ] && [ "$url_id" -lt 200 ];then - echo -ne "\033[32m正在获取版本信息!\033[0m\r" - get_bin "$TMPDIR"/release_version bin/release_version - if [ "$?" = "0" ];then - echo -e "\033[31m请选择想要回退至的稳定版版本:\033[0m" - cat "$TMPDIR"/release_version | awk '{print " "NR" "$1}' - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - if [ -z "$num" -o "$num" = 0 ]; then - continue - elif [ $num -le $(cat "$TMPDIR"/release_version 2>/dev/null | awk 'END{print NR}') ]; then - release_type=$(cat "$TMPDIR"/release_version | awk '{print $1}' | sed -n "$num"p) - update_url='' - saveserver - else - echo "-----------------------------------------------" - errornum - sleep 1 - continue - fi - else - echo "-----------------------------------------------" - echo -e "\033[31m版本回退信息获取失败,请尝试更换其他安装源!\033[0m" - sleep 1 - continue - fi - rm -rf "$TMPDIR"/release_version - else - echo -e "\033[31m当前源不支持版本回退,请尝试更换其他安装源!\033[0m" - sleep 1 - continue - fi - ;; - *) - errornum - sleep 1 - break - ;; - esac - done + while true; do + [ -z "$release_type" ] && release_name=未指定 + [ -n "$release_type" ] && release_name="$release_type(回退)" + [ "$release_type" = stable ] && release_name=稳定版 + [ "$release_type" = master ] && release_name=公测版 + [ "$release_type" = dev ] && release_name=开发版 + [ -n "$url_id" ] && url_name=$(grep "$url_id" "$CRASHDIR"/configs/servers.list 2>/dev/null | awk '{print $2}') || url_name="$update_url" + + echo "-----------------------------------------------" + echo -e "\033[30;47m切换ShellCrash版本及更新源地址\033[0m" + echo -e "当前版本:\033[4;33m$release_name\033[0m 当前源:\033[4;32m$url_name\033[0m" + echo "-----------------------------------------------" + grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | awk '{print " "NR" "$2}' + echo "-----------------------------------------------" + echo -e " a 切换至\033[32m稳定版-stable\033[0m" + echo -e " b 切换至\033[36m公测版-master\033[0m" + echo -e " c 切换至\033[33m开发版-dev\033[0m" + echo "-----------------------------------------------" + echo -e " d 自定义源地址(用于本地源或自建源)" + echo -e " e \033[31m版本回退\033[0m" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应字母或数字 > " num + case "$num" in + "" | 0) + checkupdate=false + break + ;; + [1-99]) + url_id_new=$(grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | sed -n "$num"p | awk '{print $1}') + if [ -z "$url_id_new" ]; then + errornum + sleep 1 + continue + elif [ "$url_id_new" -ge 200 ]; then + update_url=$(grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | sed -n "$num"p | awk '{print $3}') + url_id='' + saveserver + break + else + url_id=$url_id_new + update_url='' + saveserver + break + fi + unset url_id_new + ;; + a) + release_type=stable + [ -z "$url_id" ] && url_id=101 + saveserver + ;; + b) + release_type=master + [ -z "$url_id" ] && url_id=101 + saveserver + ;; + c) + echo "-----------------------------------------------" + echo -e "\033[33m开发版未经过妥善测试,可能依然存在大量bug!!!\033[0m" + echo -e "\033[36m如果你没有足够的耐心或者测试经验,切勿使用此版本!\033[0m" + echo -e "请务必加入我们的讨论组:\033[32;4mhttps://t.me/ShellClash\033[0m" + read -p "是否依然切换到开发版?(1/0) > " res + if [ "$res" = 1 ]; then + release_type=dev + [ -z "$url_id" ] && url_id=101 + saveserver + fi + ;; + d) + echo "-----------------------------------------------" + read -p "请输入个人源路径 > " update_url + if [ -z "$update_url" ]; then + echo "-----------------------------------------------" + echo -e "\033[31m取消输入,返回上级菜单\033[0m" + else + url_id='' + release_type='' + saveserver + fi + ;; + e) + echo "-----------------------------------------------" + if [ -n "$url_id" ] && [ "$url_id" -lt 200 ]; then + echo -ne "\033[32m正在获取版本信息!\033[0m\r" + get_bin "$TMPDIR"/release_version bin/release_version + if [ "$?" = "0" ]; then + echo -e "\033[31m请选择想要回退至的稳定版版本:\033[0m" + cat "$TMPDIR"/release_version | awk '{print " "NR" "$1}' + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + if [ -z "$num" -o "$num" = 0 ]; then + continue + elif [ "$num" -le $(cat "$TMPDIR"/release_version 2>/dev/null | awk 'END{print NR}') ]; then + release_type=$(cat "$TMPDIR"/release_version | awk '{print $1}' | sed -n "$num"p) + update_url='' + saveserver + else + echo "-----------------------------------------------" + errornum + sleep 1 + continue + fi + else + echo "-----------------------------------------------" + echo -e "\033[31m版本回退信息获取失败,请尝试更换其他安装源!\033[0m" + sleep 1 + continue + fi + rm -rf "$TMPDIR"/release_version + else + echo -e "\033[31m当前源不支持版本回退,请尝试更换其他安装源!\033[0m" + sleep 1 + continue + fi + ;; + *) + errornum + sleep 1 + break + ;; + esac + done } diff --git a/scripts/menus/fw_filter.sh b/scripts/menus/fw_filter.sh index 89e6324b..af719952 100644 --- a/scripts/menus/fw_filter.sh +++ b/scripts/menus/fw_filter.sh @@ -181,8 +181,9 @@ set_common_ports() { } set_cust_host_ipv4() { #自定义ipv4透明路由网段 [ -z "$replace_default_host_ipv4" ] && replace_default_host_ipv4="OFF" + . "$CRASHDIR"/starts/fw_getlanip.sh && getlanip echo "-----------------------------------------------" - echo -e "当前默认透明路由的网段为: \033[32m$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'br' | grep -v 'iot' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ' && echo) \033[0m" + echo -e "当前默认透明路由的网段为: \033[32m$host_ipv4 \033[0m" echo -e "当前已添加的自定义网段为:\033[36m$cust_host_ipv4\033[0m" echo "-----------------------------------------------" echo -e " 1 移除所有自定义网段" diff --git a/scripts/start.sh b/scripts/start.sh index 3e7142fb..22895a9e 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -37,6 +37,7 @@ 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 diff --git a/scripts/starts/bfstart.sh b/scripts/starts/bfstart.sh index 294e1418..3882f88a 100644 --- a/scripts/starts/bfstart.sh +++ b/scripts/starts/bfstart.sh @@ -6,6 +6,9 @@ . "$CRASHDIR"/libs/get_config.sh [ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1 [ ! -f "$TMPDIR" ] && mkdir -p "$TMPDIR" + +#当上次启动失败时终止自启动 +[ -f "CRASHDIR"/.start_error ] && exit 1 #加载工具 . "$CRASHDIR"/libs/check_cmd.sh . "$CRASHDIR"/libs/check_target.sh @@ -18,6 +21,7 @@ [ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式' [ -z "$dns_mod" ] && dns_mod='redir_host' [ -z "$redir_mod" ] && firewall_area='4' +routing_mark=$((fwmark + 2)) makehtml() { #生成面板跳转文件 cat >"$BINDIR"/ui/index.html <&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -Ev 'utun|iot|peer|docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/[[:space:]]br.*$//g' | sed 's/metric.*$//g') #ipv4局域网网段 - [ "$ipv6_redir" = "ON" ] && host_ipv6=$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g') #ipv6公网地址段 + host_ipv4=$(ip route show scope link | grep -Ev 'wan|utun|iot|peer|docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | grep -E ' 1(92|0|72)\.' | awk '{print $1}') #ipv4局域网网段 + [ "$ipv6_redir" = "ON" ] && host_ipv6=$(ip -6 route show | grep 'default' | awk '{print $3}') #ipv6公网地址段 [ -f "$TMPDIR"/ShellCrash.log ] && break [ -n "$host_ipv4" -a "$ipv6_redir" != "ON" ] && break [ -n "$host_ipv4" -a -n "$host_ipv6" ] && break diff --git a/scripts/starts/fw_iptables.sh b/scripts/starts/fw_iptables.sh index 5e0b4681..8105bb7a 100644 --- a/scripts/starts/fw_iptables.sh +++ b/scripts/starts/fw_iptables.sh @@ -1,6 +1,9 @@ #!/bin/sh # Copyright (C) Juewuy +ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables +ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables + start_ipt_route() { #iptables-route通用工具 #$1:iptables/ip6tables $2:所在的表(nat/mangle) $3:所在的链(OUTPUT/PREROUTING) $4:新创建的shellcrash链表 $5:tcp/udp/all #区分ipv4/ipv6 @@ -28,7 +31,10 @@ start_ipt_route() { #iptables-route通用工具 "$1" $w -t "$2" -A "$4" -m owner --gid-owner $gid -j RETURN done [ "$firewall_area" = 5 ] && "$1" $w -t "$2" -A "$4" -s $bypass_host -j RETURN - [ -z "$ports" ] && "$1" $w -t "$2" -A "$4" -p tcp -m multiport --dports "$mix_port,$redir_port,$tproxy_port" -j RETURN + [ -z "$ports" ] && { + "$1" $w -t "$2" -A "$4" -p tcp -m multiport --dports "$mix_port,$redir_port,$tproxy_port" -j RETURN + "$1" $w -t "$2" -A "$4" -p udp -m multiport --dports "$mix_port,$redir_port,$tproxy_port" -j RETURN + } #跳过目标保留地址及目标本机网段 for ip in $HOST_IP $RESERVED_IP; do "$1" $w -t "$2" -A "$4" -d $ip -j RETURN @@ -130,8 +136,6 @@ start_ipt_dns() { #iptables-dns通用工具 "$1" $w -t nat -I "$2" -p udp --dport 53 -j "$3" } start_ipt_wan() { #iptables公网防火墙 - ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables - ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables ipt_wan_accept(){ $iptable -I INPUT -p "$1" -m multiport --dports "$accept_ports" -j ACCEPT ckcmd ip6tables && $ip6table -I INPUT -p "$1" -m multiport --dports "$accept_ports" -j ACCEPT @@ -141,7 +145,7 @@ start_ipt_wan() { #iptables公网防火墙 ckcmd ip6tables && $ip6table -I INPUT -p "$1" -m multiport --dports "$reject_ports" -j REJECT } #端口拦截 - reject_ports="$mix_port,$db_port,$dns_port" + reject_ports="$mix_port,$db_port" ipt_wan_reject tcp ipt_wan_reject udp #端口放行 diff --git a/scripts/starts/fw_nftables.sh b/scripts/starts/fw_nftables.sh index 53a9bf53..a7d0b52e 100644 --- a/scripts/starts/fw_nftables.sh +++ b/scripts/starts/fw_nftables.sh @@ -146,7 +146,7 @@ start_nft_wan() { #nftables公网防火墙 nft add rule inet shellcrash input udp dport $fw_wan_nfports meta mark set 0x67890 accept } #端口拦截 - reject_ports="{ $mix_port, $db_port, $dns_port }" + reject_ports="{ $mix_port, $db_port }" nft add rule inet shellcrash input ip saddr {$HOST_IP} accept nft add rule inet shellcrash input ip6 saddr {$HOST_IP6} accept nft add rule inet shellcrash input tcp dport $reject_ports reject diff --git a/scripts/starts/fw_stop.sh b/scripts/starts/fw_stop.sh index 154e40fa..9a6d398d 100644 --- a/scripts/starts/fw_stop.sh +++ b/scripts/starts/fw_stop.sh @@ -55,8 +55,8 @@ ckcmd iptables && { done $iptable -D INPUT -p tcp -m multiport --dports "$accept_ports" -j ACCEPT 2>/dev/null $iptable -D INPUT -p udp -m multiport --dports "$accept_ports" -j ACCEPT 2>/dev/null - $iptable -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null - $iptable -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null + $iptable -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port" -j REJECT 2>/dev/null + $iptable -D INPUT -p udp -m multiport --dports "$mix_port,$db_port" -j REJECT 2>/dev/null #清理shellcrash自建表 for text in shellcrash_dns shellcrash shellcrash_out shellcrash_dns_out shellcrash_vm shellcrash_vm_dns; do $iptable -t nat -F "$text" 2>/dev/null @@ -105,8 +105,8 @@ ckcmd ip6tables && { done $ip6table -D INPUT -p tcp -m multiport --dports "$accept_ports" -j ACCEPT 2>/dev/null $ip6table -D INPUT -p udp -m multiport --dports "$accept_ports" -j ACCEPT 2>/dev/null - $ip6table -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null - $ip6table -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null + $ip6table -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port" -j REJECT 2>/dev/null + $ip6table -D INPUT -p udp -m multiport --dports "$mix_port,$db_port" -j REJECT 2>/dev/null #清理shellcrash自建表 for text in shellcrashv6_dns shellcrashv6 shellcrashv6_out; do $ip6table -t nat -F "$text" 2>/dev/null diff --git a/scripts/starts/singbox_modify.sh b/scripts/starts/singbox_modify.sh index e1c02052..a91edb4a 100644 --- a/scripts/starts/singbox_modify.sh +++ b/scripts/starts/singbox_modify.sh @@ -200,20 +200,21 @@ EOF EOF #生成add_route.json #域名嗅探配置 - [ "$sniffer" = ON ] && sniffer_set='{ "action": "sniff", "timeout": "500ms" },' - [ "$ts_service" = ON ] && tailscale_set='{ "inbound": [ "ts-ep" ], "port": 53, "action": "hijack-dns" },' + [ "$sniffer" = ON ] && ! grep -Eq '"action" *:[[:space:]]*"sniff"' "$CRASHDIR"/jsons/*.json && sniffer_set='{ "action": "sniff", "timeout": "500ms" },' + [ "$ts_service" = ON ] && tailscale_set='{ "inbound": [ "ts-ep" ], "port": 53, "action": "hijack-dns" },' + sed -i '/"clash_mode".*"outbound"/d' "$CRASHDIR"/jsons/*.json cat >"$TMPDIR"/jsons/add_route.json </dev/null 2>&1 fi -error=$(cat $TMPDIR/core_test.log | grep -iEo 'error.*=.*|.*ERROR.*|.*FATAL.*') +touch "CRASHDIR"/.start_error #标记启动失败,防止自启 +error=$(cat "$TMPDIR"/core_test.log | grep -iEo 'error.*=.*|.*ERROR.*|.*FATAL.*') logger "服务启动失败!请查看报错信息!详细信息请查看$TMPDIR/core_test.log" 33 logger "$error" 31 diff --git a/scripts/starts/start_legacy.sh b/scripts/starts/start_legacy.sh index f05df7f9..bcbd4dc1 100644 --- a/scripts/starts/start_legacy.sh +++ b/scripts/starts/start_legacy.sh @@ -2,16 +2,14 @@ . "$CRASHDIR"/libs/check_cmd.sh start_legacy(){ + ckcmd nohup && _nohup=nohup if ckcmd su && grep -q 'shellcrash:x:0:7890' /etc/passwd;then - su shellcrash -c "$1 >/dev/null 2>&1 & echo \$! > /tmp/ShellCrash/$2.pid" + su shellcrash -c "$_nohup $1 >/dev/null 2>&1 & echo \$! > /tmp/ShellCrash/$2.pid" elif ckcmd setsid; then - setsid $1 >/dev/null 2>&1 & + $_nohup setsid $1 >/dev/null 2>&1 & echo $! > "/tmp/ShellCrash/$2.pid" - elif ckcmd nohup; then - nohup $1 >/dev/null 2>&1 & - echo $! > "/tmp/ShellCrash/$2.pid" else - $1 >/dev/null 2>&1 & + $_nohup $1 >/dev/null 2>&1 & echo $! > "/tmp/ShellCrash/$2.pid" fi } diff --git a/version b/version index 9c798a82..99c3e34e 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.9.4beta1.1 +1.9.4beta2