├── README.md ├── dependencies ├── BestTrace.tar.gz ├── LemonBench.sh ├── Network-Reinstall-System-Modify.sh ├── bashrc ├── bashrc.sh ├── besttrace4linux.zip ├── config-v2ray.json ├── config-xray.json ├── fast_com.py ├── fast_com_example_usage.py ├── ijcnf.sh ├── jcnf.sh ├── jg.sh ├── shbox.png ├── speedtest.tgz ├── status.sh ├── superbench.sh ├── tcping ├── tcping.sh ├── tools.py └── xd.sh ├── shbox.sh └── shbox.sh.old /README.md: -------------------------------------------------------------------------------- 1 | shbox 2 | --------------- 3 | **概述** 4 | 5 | 此脚本本人常用脚本的集合,个人使用了一段时间,感觉还不错,但是大部分脚本和文件从自己的服务器拉取的,便修改了一下,去除了从个人服务器拉取的脚本和文件,目前几乎所有脚本和文件依赖都拉取自github。 6 | 仅限Debian系系统,本人能力有限,其他系统请自行修改。 7 | 8 | **使用** 9 | 10 | #下载使用脚本 11 | wget https://ghproxy.com/https://raw.githubusercontent.com/jamespan2012/shbox/main/shbox.sh -O shbox.sh && bash shbox.sh 12 | 13 | #后续运行脚本(再次检查也仅需运行下面代码) 14 | bash shbox.sh 15 | 16 | **更新** 17 | 18 | - 0.0.3 19 | 20 | 添加aapanel和升级Debian系统 21 | 22 | - 0.0.2 23 | 24 | 1.添加魔法上网二级菜单 25 | 26 | 2.替换LemonBench脚本地址 27 | 28 | 3.添加建站环境安装二级菜单(宝塔、lnmp、oneinstack,screen运行,若ssh断开重连后 screen -r 即可继续安装) 29 | 30 | 4.添加docker版v2ray/xray安装(docker中的目录挂载在宿主机/root/v2ray和/root/xray目录,需自行修改其中的配置文件) 31 | 32 | 5.添加ICMP回程测试 33 | 34 | - 0.0.1 35 | 36 | **功能说明** 37 | 38 | 所有脚本都来源于公开项目 39 | 40 | - 1.首次运行会安装常用命令,安装tcping、speedtest,拉取doubi、Port-forwarding、Multi-EasyGost、EasyRealM以便于使用gost、realm。 41 | - 2.要使用docker版x-ui,请先安装docker,docker版x-ui将容器目录/etc/x-ui/挂载到本地/root/x-ui/db/,将容器目录/root/cert/挂载到本地/root/x-ui/cert/。 42 | - 3.DD脚本,如果系统重启后失联,请进vnc编辑/etc/network/interfaces文件注释掉allow-hotplug ensX,添加一行auto ensX。 43 | 44 | 输入数字选择需要进行的测试。 45 | 46 | https://github.com/jamespan2012/shbox 47 | 48 | ![image](https://github.com/jamespan2012/shbox/blob/main/dependencies/shbox.png) 49 | 50 | ---------- 51 | 52 | 53 | 所有脚本都来源于以下项目,本人未作任何修改 54 | 55 | shbox https://github.com/jamespan2012/shbox 56 | 57 | multi-v2ray https://github.com/Jrohy/multi-v2ray 58 | 59 | x-ui https://github.com/vaxilu/x-ui 60 | 61 | Linux-NetSpeed https://github.com/ylx2016/Linux-NetSpeed 62 | 63 | AutoReinstall.sh https://github.com/hiCasper/Shell 64 | 65 | RegionRestrictionCheck https://github.com/lmc999/RegionRestrictionCheck 66 | 67 | yabs https://github.com/masonr/yet-another-bench-script 68 | 69 | LemonBench https://blog.ilemonrain.com/linux/LemonBench.html 70 | 71 | superbench https://github.com/jamespan2012/shbox/blob/main/dependencies/superbench.sh 72 | 73 | ServerStatus-Hotaru https://github.com/cokemine/ServerStatus-Hotaru 74 | 75 | Aurora-Admin-Panel https://github.com/Aurora-Admin-Panel/deploy 76 | 77 | xd-panel https://sh.xdmb.xyz/xiandan/xd.sh 78 | 79 | linux-toolkit https://github.com/wikihost-opensource/linux-toolkit -------------------------------------------------------------------------------- /dependencies/BestTrace.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamespan2012/shbox/787cf0fc98d83c7d824a7cc47b4ad9846c23ee48/dependencies/BestTrace.tar.gz -------------------------------------------------------------------------------- /dependencies/Network-Reinstall-System-Modify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## License: GPL 4 | ## This is the magically modified version of the one-click reload script. 5 | ## It can reinstall CentOS, Debian, Ubuntu and other Linux systems (continuously added) over the network in one click. 6 | ## It can reinstall Windwos 2003, 7, 2008R2, 2012R2, 2016, 2019 and other Windows systems (continuously added) via the network in one click. 7 | ## Support GRUB or GRUB2 for installing a clean minimal system. 8 | ## Technical support is provided by the CXT (CXTHHHHH.com). (based on the original version of Vicer) 9 | 10 | ## Magic Modify version author: 11 | ## Default root password: cxthhhhh.com 12 | ## WebSite: https://www.cxthhhhh.com 13 | ## Written By CXT (CXTHHHHH.com) 14 | 15 | ## Original version author: 16 | ## Blog: https://moeclub.org 17 | ## Written By Vicer (MoeClub.org) 18 | 19 | 20 | echo -e "\n\n\n" 21 | clear 22 | echo -e "\n" 23 | echo "---------------------------------------------------------------------------------------------------------------------" 24 | echo -e "\033[33m 一键网络重装系统 - 魔改版 版本:V4.1.0 更新:2021年04月16日 \033[0m" 25 | echo -e "\033[33m Network-Reinstall-System-Modify Tools V4.1.0 2021/04/16 \033[0m" 26 | echo "---------------------------------------------------------------------------------------------------------------------" 27 | echo -e "\033[33m 一键网络重装系统 - 魔改版(适用于Linux / Windows) \033[0m" 28 | echo -e "\033[33m 系统需求: 任何带有GRUB或GRUB2的Linux操作系统即可运行, 当前推荐安装的系统为: CentOS8/Debian10/Ubuntu20 \033[0m" 29 | echo -e "\n" 30 | echo -e "\033[33m [Magic Modify] Reinstall the system (any Windows / Linux) requires only network and one click \033[0m" 31 | echo -e "\033[33m System requirements: Any Linux system with GRUB or GRUB2, recommended CentOS8/Debian10/Ubuntu20 \033[0m" 32 | echo -e "\n" 33 | echo -e "\033[33m 官方更新地址(Official update address):CXT - Enjoy Life | 生活、技术、交友、分享 \033[0m" 34 | echo -e "\033[33m https://www.cxthhhhh.com/Network-Reinstall-System-Modify \033[0m" 35 | echo "---------------------------------------------------------------------------------------------------------------------" 36 | echo " 默认密码: cxthhhhh.com" 37 | echo " Default password: cxthhhhh.com" 38 | echo "---------------------------------------------------------------------------------------------------------------------" 39 | echo -e "\n" 40 | sleep 6s 41 | 42 | echo "---------------------------------------------------------------------------------------------------------------------" 43 | echo " 对当前系统环境进行处理. . ." 44 | echo " Pre-environment preparation. . ." 45 | echo "---------------------------------------------------------------------------------------------------------------------" 46 | echo -e "\n" 47 | sleep 2s 48 | 49 | if [ -f "/usr/bin/apt-get" ];then 50 | isDebian=`cat /etc/issue|grep Debian` 51 | if [ "$isDebian" != "" ];then 52 | echo '当前系统 是 Debian' 53 | echo 'Current system is Debian' 54 | apt-get install -y xz-utils openssl gawk file wget curl 55 | apt install -y xz-utils openssl gawk file wget curl 56 | sleep 3s 57 | else 58 | echo '当前系统 是 Ubuntu' 59 | echo 'Current system is Ubuntu' 60 | apt-get install -y xz-utils openssl gawk file wget curl 61 | apt install -y xz-utils openssl gawk file wget curl 62 | sleep 3s 63 | fi 64 | else 65 | echo '当前系统 是 CentOS' 66 | echo 'Current system is CentOS' 67 | yum install -y xz openssl gawk file wget curl 68 | sleep 3s 69 | fi 70 | 71 | echo "---------------------------------------------------------------------------------------------------------------------" 72 | echo " 对当前系统环境进行处理. . . 【OK】" 73 | echo " Pre-environment preparation. . . 【OK】" 74 | echo -e "\n" 75 | echo " 启动系统安装. . . " 76 | echo " Start system installation. . . " 77 | echo "---------------------------------------------------------------------------------------------------------------------" 78 | echo -e "\n" 79 | sleep 2s 80 | 81 | 82 | echo "---------------------------------------------------------------------------------------------------------------------" 83 | echo -e "\033[35m 启动 安装 \033[0m" 84 | echo -e "\033[32m Start Installation \033[0m" 85 | echo "---------------------------------------------------------------------------------------------------------------------" 86 | echo -e "\n" 87 | 88 | 89 | if [ $1 = '-UI_Options' ] 90 | then 91 | echo -e "\033[33m 你选择启动到 【图形化安装界面】 正在进入图形化安装选择器. . . \033[0m" 92 | echo -e "\033[33m You have chosen to Start the Graphical Interface Options, Wait a moment. . . \033[0m" 93 | echo -e "\n" 94 | sleep 1s 95 | wget --no-check-certificate -qO UI_Options.sh 'https://github.com/ylx2016/reinstall/raw/master/UI_Options.sh' && bash UI_Options.sh 96 | fi 97 | 98 | if [ $1 = '-CXT_Bare-metal_System_Deployment_Platform' ] 99 | then 100 | echo -e "\033[33m 你选择安装 最新的 【CXT裸机系统部署平台】,支持玩家VNC自定义安装。(建议极客使用,小白勿扰) \033[0m" 101 | echo -e "\033[33m You have chosen to install the latest CXT_Bare-metal_System_Deployment_Platform \033[0m" 102 | echo -e "\n" 103 | sleep 5s 104 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Bare-metal_System_Deployment_Platform/CXT_Bare-metal_System_Deployment_Platform_v3.6.vhd.gz' 105 | fi 106 | 107 | if [ $1 = '-OpenWRT' ] 108 | then 109 | echo -e "\033[33m 你选择安装 最新的 【CXT-OpenWRT】 \033[0m" 110 | echo -e "\033[33m You have chosen to install the latest OpenWRT \033[0m" 111 | echo -e "\n" 112 | sleep 5s 113 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/OpenWRT-Virtualization-Servers/Stable/openwrt-x86-64-generic-squashfs-combined.img.gz' 114 | fi 115 | 116 | if [ $1 = '-OpenWRT_UEFI' ] 117 | then 118 | echo -e "\033[33m 你选择安装 最新的 【CXT-OpenWRT】 支持UEFI启动模式 \033[0m" 119 | echo -e "\033[33m You have chosen to install the latest OpenWRT_UEFI \033[0m" 120 | echo -e "\n" 121 | sleep 5s 122 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/OpenWRT-Virtualization-Servers/Stable/openwrt-x86-64-generic-squashfs-combined-efi.img.gz' 123 | fi 124 | 125 | if [ $1 = '-CentOS_8' ] 126 | then 127 | echo -e "\033[33m 你选择安装 最新的 【CentOS 8】 \033[0m" 128 | echo -e "\033[33m You have chosen to install the latest CentOS_8 \033[0m" 129 | echo -e "\n" 130 | sleep 5s 131 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/CentOS/CentOS_8.X_NetInstallation_Stable_v3.6.vhd.gz' 132 | fi 133 | 134 | if [ $1 = '-CentOS_7' ] 135 | then 136 | echo -e "\033[33m 你选择安装 最新的 【CentOS 7】 \033[0m" 137 | echo -e "\033[33m You have chosen to install the latest CentOS_7 \033[0m" 138 | echo -e "\n" 139 | sleep 5s 140 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/CentOS/CentOS_7.X_NetInstallation_Final_v9.2.vhd.gz' 141 | fi 142 | 143 | if [ $1 = '-CentOS_79' ] 144 | then 145 | echo -e "\033[33m You have chosen to install the latest CentOS_79 \033[0m" 146 | echo -e "\n" 147 | sleep 5s 148 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://chinagz2018-my.sharepoint.com/:u:/g/personal/ylx_chinagz2018_onmicrosoft_com/EWMERf0QmWdJlkVbNjXUBsgBkUxWHJLRwuRB6zcCaA1qvA?download=1' 149 | fi 150 | 151 | if [ $1 = '-CentOS_76' ] 152 | then 153 | echo -e "\033[33m You have chosen to install the latest CentOS_76 \033[0m" 154 | echo -e "\n" 155 | sleep 5s 156 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://chinagz2018-my.sharepoint.com/:u:/g/personal/ylx_chinagz2018_onmicrosoft_com/EXWsa4xMdExGrYYfQ6P_NRgBSu8_gjMakPaenWU3tRDcaA?download=1' 157 | fi 158 | 159 | if [ $1 = '-Debian_10' ] 160 | then 161 | echo -e "\033[33m 你选择安装 最新的 【Debian 10】 \033[0m" 162 | echo -e "\033[33m You have chosen to install the latest Debian_10 \033[0m" 163 | echo -e "\n" 164 | sleep 5s 165 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -d 10 -v 64 -a 166 | fi 167 | 168 | if [ $1 = '-Debian_9' ] 169 | then 170 | echo -e "\033[33m 你选择安装 最新的 【Debian 9】 \033[0m" 171 | echo -e "\033[33m You have chosen to install the latest Debian_9 \033[0m" 172 | echo -e "\n" 173 | sleep 5s 174 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -d 9 -v 64 -a 175 | fi 176 | 177 | if [ $1 = '-Ubuntu_20.04' ] 178 | then 179 | echo -e "\033[33m 你选择安装 最新的 【Ubuntu 20.04】 \033[0m" 180 | echo -e "\033[33m You have chosen to install the latest Ubuntu_20.04 \033[0m" 181 | echo -e "\n" 182 | sleep 5s 183 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -u 20.04 -v 64 -a 184 | fi 185 | 186 | if [ $1 = '-Ubuntu_18.04' ] 187 | then 188 | echo -e "\033[33m 你选择安装 最新的 【Ubuntu 18.04】 \033[0m" 189 | echo -e "\033[33m You have chosen to install the latest Ubuntu_18.04 \033[0m" 190 | echo -e "\n" 191 | sleep 5s 192 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -u 18.04 -v 64 -a 193 | fi 194 | 195 | if [ $1 = '-Windows_Server_2019' ] 196 | then 197 | echo -e "\033[33m 你选择安装 最新的 【Windows Server 2019】 \033[0m" 198 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2019 \033[0m" 199 | echo -e "\n" 200 | sleep 5s 201 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2019_DataCenter_CN_v5.1.vhd.gz' 202 | fi 203 | 204 | if [ $1 = '-Windows_Server_2019_UEFI' ] 205 | then 206 | echo -e "\033[33m 你选择安装 最新的 【Windows Server 2019】 支持UEFI启动模式 \033[0m" 207 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2019_UEFI \033[0m" 208 | echo -e "\n" 209 | sleep 5s 210 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2019_DataCenter_CN_v5.1_UEFI.vhd.gz' 211 | fi 212 | 213 | if [ $1 = '-Windows_Server_2016' ] 214 | then 215 | echo -e "\033[33m 你选择安装 最新的 【Windows Server 2016】 \033[0m" 216 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2016 \033[0m" 217 | echo -e "\n" 218 | sleep 5s 219 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2016_DataCenter_CN_v4.12.vhd.gz' 220 | fi 221 | 222 | if [ $1 = '-Windows_Server_2012R2' ] 223 | then 224 | echo -e "\033[33m 你选择安装 最新的 【Windows Server 2012 R2】 \033[0m" 225 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2012R2 \033[0m" 226 | echo -e "\n" 227 | sleep 5s 228 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2012R2_DataCenter_CN_v4.29.vhd.gz' 229 | fi 230 | 231 | if [ $1 = '-Windows_Server_2012R2_UEFI' ] 232 | then 233 | echo -e "\033[33m 你选择安装 最新的 【Windows Server 2012 R2】 支持UEFI启动模式 \033[0m" 234 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2012R2_UEFI \033[0m" 235 | echo -e "\n" 236 | sleep 5s 237 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2012R2_DataCenter_CN_v4.29_UEFI.vhd.gz' 238 | fi 239 | 240 | if [ $1 = '-DD' ] 241 | then 242 | echo -e "\033[33m 你选择安装 【由你指定的自定义镜像】 更多支持信息,你需要向镜像制作者寻求。 \033[0m" 243 | echo -e "\033[33m You have chosen to install the DD package provided by you \033[0m" 244 | echo -e "\n" 245 | sleep 5s 246 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd $2 247 | fi 248 | 249 | 250 | 251 | 252 | 253 | if [ $1 = '-CentOS_6' ] 254 | then 255 | echo -e "\033[33m 你选择安装 最新的 【CentOS 6】(生命周期已结束,无任何支持) \033[0m" 256 | echo -e "\033[33m You have chosen to install the latest CentOS_6 (EOL, No supported) \033[0m" 257 | echo -e "\n" 258 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 259 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 260 | echo -e "\n" 261 | sleep 10s 262 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -c 6.10 -v 64 -a 263 | fi 264 | 265 | if [ $1 = '-Debian_8' ] 266 | then 267 | echo -e "\033[33m 你选择安装 最新的 【Debian 8】(生命周期已结束,无任何支持) \033[0m" 268 | echo -e "\033[33m You have chosen to install the latest Debian_8 (EOL, No supported) \033[0m" 269 | echo -e "\n" 270 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 271 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 272 | echo -e "\n" 273 | sleep 10s 274 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -d 8 -v 64 -a 275 | fi 276 | 277 | if [ $1 = '-Debian_7' ] 278 | then 279 | echo -e "\033[33m 你选择安装 最新的 【Debian 7】(生命周期已结束,无任何支持) \033[0m" 280 | echo -e "\033[33m You have chosen to install the latest Debian_7 (EOL, No supported) \033[0m" 281 | echo -e "\n" 282 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 283 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 284 | echo -e "\n" 285 | sleep 10s 286 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -d 7 -v 64 -a 287 | fi 288 | 289 | if [ $1 = '-Ubuntu_16.04' ] 290 | then 291 | echo -e "\033[33m 你选择安装 最新的 【Ubuntu 16.04】(生命周期已结束,无任何支持) \033[0m" 292 | echo -e "\033[33m You have chosen to install the latest Ubuntu_16.04 (EOL, No supported) \033[0m" 293 | echo -e "\n" 294 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 295 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 296 | echo -e "\n" 297 | sleep 10s 298 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -u 16.04 -v 64 -a 299 | fi 300 | 301 | if [ $1 = '-Ubuntu_14.04' ] 302 | then 303 | echo -e "\033[33m 你选择安装 最新的 【Ubuntu 14.04】(生命周期已结束,无任何支持) \033[0m" 304 | echo -e "\033[33m You have chosen to install the latest Ubuntu_14.04 (EOL, No supported) \033[0m" 305 | echo -e "\n" 306 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 307 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 308 | echo -e "\n" 309 | sleep 10s 310 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -u 14.04 -v 64 -a 311 | fi 312 | 313 | if [ $1 = '-Windows_10_Lite' ] 314 | then 315 | echo -e "\033[33m 你选择安装 最新的 【Windows 10 Lite 精简版】(生命周期已结束,无任何支持) \033[0m" 316 | echo -e "\033[33m You have chosen to install the latest Windows_10_Lite (EOL, No supported) \033[0m" 317 | echo -e "\n" 318 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 319 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 320 | echo -e "\n" 321 | sleep 10s 322 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Historical_File_Windows_DD_Disk/Disk_Windows_10_x64_Lite_by_CXT_v1.0.vhd.gz' 323 | fi 324 | 325 | if [ $1 = '-Windows_Server_2008R2' ] 326 | then 327 | echo -e "\033[33m 你选择安装 最新的 【Windows Server 2008R2】(生命周期已结束,无任何支持) \033[0m" 328 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2008R2 (EOL, No supported) \033[0m" 329 | echo -e "\n" 330 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 331 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 332 | echo -e "\n" 333 | sleep 10s 334 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2008R2_DataCenter_CN_v3.27.vhd.gz' 335 | fi 336 | 337 | if [ $1 = '-Windows_Server_2003R2' ] 338 | then 339 | echo -e "\033[33m 你选择安装 最新的 【Windows_Server_2003R2】(生命周期已结束,无任何支持) \033[0m" 340 | echo -e "\033[33m You have chosen to install the latest Windows_Server_2003R2 (EOL, No supported) \033[0m" 341 | echo -e "\n" 342 | echo -e "\033[41;30m !!!警告:安装生命周期结束的旧系统会导致安全隐患!!! \033[0m" 343 | echo -e "\033[41;30m !!! Warn:Installing the old system will lead to security risks !!! \033[0m" 344 | echo -e "\n" 345 | sleep 10s 346 | wget --no-check-certificate -qO Core_Install.sh 'https://github.com/ylx2016/reinstall/raw/master/Core_Install_v3.1.sh' && bash Core_Install.sh -dd 'https://odc.cxthhhhh.com/SyStem/Windows_DD_Disks/Disk_Windows_Server_2003_DataCenter_CN_v7.1.vhd.gz' 347 | fi 348 | 349 | 350 | 351 | 352 | 353 | echo "---------------------------------------------------------------------------------------------------------------------" 354 | echo -e "\033[35m 启动 安装 \033[0m" 355 | echo -e "\033[32m Start Installation \033[0m" 356 | echo "---------------------------------------------------------------------------------------------------------------------" 357 | echo -e "\n" 358 | exit -------------------------------------------------------------------------------- /dependencies/bashrc: -------------------------------------------------------------------------------- 1 | # ~/.bashrc: executed by bash(1) for non-login shells. 2 | 3 | # Note: PS1 and umask are already set in /etc/profile. You should not 4 | # need this unless you want different defaults for root. 5 | # PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ ' 6 | # umask 022 7 | 8 | # You may uncomment the following lines if you want `ls' to be colorized: 9 | export LS_OPTIONS='--color=auto' 10 | eval "`dircolors`" 11 | alias ls='ls $LS_OPTIONS' 12 | alias ll='ls $LS_OPTIONS -l' 13 | alias l='ls $LS_OPTIONS -lA' 14 | # 15 | # Some more alias to avoid making mistakes: 16 | # alias rm='rm -i' 17 | # alias cp='cp -i' 18 | # alias mv='mv -i' 19 | 20 | HISTCONTROL=ignoreboth 21 | HISTFILESIZE=999999999 22 | HISTSIZE=999999999 23 | PS1='${debian_chroot:+($debian_chroot)}\[\e[1;31m\]\u\[\e[1;33m\]@\[\e[1;36m\]\h \[\e[1;33m\]\w \[\e[1;35m\]\$ \[\e[0m\]' 24 | -------------------------------------------------------------------------------- /dependencies/bashrc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | wget -O /root/.bashrc https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/bashrc && source ~/.bashrc -------------------------------------------------------------------------------- /dependencies/besttrace4linux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamespan2012/shbox/787cf0fc98d83c7d824a7cc47b4ad9846c23ee48/dependencies/besttrace4linux.zip -------------------------------------------------------------------------------- /dependencies/config-v2ray.json: -------------------------------------------------------------------------------- 1 | #配置文件格式请参考:https://github.com/v2fly/v2ray-examples 2 | { 3 | "inbounds": [{ 4 | "port": 9000, 5 | "protocol": "vmess", 6 | "settings": { 7 | "clients": [ 8 | { 9 | "id": "11c2a696-0366-4524-b8f0-9a9c21512b02", 10 | "level": 1, 11 | "alterId": 64 12 | } 13 | ] 14 | } 15 | }], 16 | "outbounds": [{ 17 | "protocol": "freedom", 18 | "settings": {} 19 | }] 20 | } -------------------------------------------------------------------------------- /dependencies/config-xray.json: -------------------------------------------------------------------------------- 1 | #配置文件格式请参考:https://github.com/XTLS/Xray-examples 2 | { 3 | "inbounds": [{ 4 | "port": 9000, 5 | "protocol": "vmess", 6 | "settings": { 7 | "clients": [ 8 | { 9 | "id": "1eb6e917-774b-4a84-aff6-b058577c60a5" 10 | } 11 | ] 12 | } 13 | }], 14 | "outbounds": [{ 15 | "protocol": "freedom", 16 | "settings": {} 17 | }] 18 | } 19 | -------------------------------------------------------------------------------- /dependencies/fast_com.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | Python CLI-tool (without need for a GUI) to measure Internet speed with fast.com 5 | 6 | ''' 7 | 8 | 9 | import os 10 | import json 11 | import urllib 12 | import urllib2 13 | import sys 14 | #import jsbeautifier 15 | import time 16 | #import threading 17 | from threading import Thread 18 | 19 | 20 | def gethtmlresult(url,result,index): 21 | ''' 22 | get the stuff from url in chuncks of size CHUNK, and keep writing the number of bytes retrieved into result[index] 23 | ''' 24 | #print url, index, result[index] 25 | req = urllib2.urlopen(url) 26 | CHUNK = 100 * 1024 27 | i=1 28 | while True: 29 | chunk = req.read(CHUNK) 30 | if not chunk: break 31 | result[index] = i*CHUNK 32 | i=i+1 33 | 34 | def application_bytes_to_networkbits(bytes): 35 | # convert bytes (at application layer) to bits (at network layer) 36 | return bytes * 8 * 1.0415 37 | # 8 for bits versus bytes 38 | # 1.0416 for application versus network layers 39 | 40 | 41 | def findipv4(fqdn): 42 | ''' 43 | find IPv4 address of fqdn 44 | ''' 45 | import socket 46 | ipv4 = socket.getaddrinfo(fqdn, 80, socket.AF_INET)[0][4][0] 47 | return ipv4 48 | 49 | def findipv6(fqdn): 50 | ''' 51 | find IPv6 address of fqdn 52 | ''' 53 | import socket 54 | ipv6 = socket.getaddrinfo(fqdn, 80, socket.AF_INET6)[0][4][0] 55 | return ipv6 56 | 57 | 58 | def fast_com(verbose=False, maxtime=15, forceipv4=False, forceipv6=False): 59 | ''' 60 | verbose: print debug output 61 | maxtime: max time in seconds to monitor speedtest 62 | forceipv4: force speed test over IPv4 63 | forceipv6: force speed test over IPv6 64 | ''' 65 | # go to fast.com to get the javascript file 66 | url = 'https://fast.com/' 67 | try: 68 | urlresult = urllib.urlopen(url) 69 | except: 70 | # no connection at all? 71 | return 0 72 | response = urlresult.read() 73 | for line in response.split('\n'): 74 | # We're looking for a line like 75 | # 76 | if line.find('script src') >= 0: 77 | #print line 78 | jsname = line.split('"')[1] # At time of writing: '/app-40647a.js' 79 | 80 | 81 | # From that javascript file, get the token: 82 | url = 'https://fast.com' + jsname 83 | if verbose: print "javascript url is", url 84 | urlresult = urllib.urlopen(url) 85 | allJSstuff = urlresult.read() # this is a obfuscated Javascript file 86 | ''' 87 | # OLD STUFF ... beautiful, but needs the js-beautifier module, which was a non-stardard requirement 88 | res = jsbeautifier.beautify(allJSstuff) # ... so un-obfuscate it 89 | for line in res.split('\n'): 90 | if line.find('token:') >= 0: 91 | token = line.split('"')[1] 92 | if verbose: print "token is", token 93 | ''' 94 | 95 | ''' 96 | We're searching for the "token:" in this string: 97 | .dummy,DEFAULT_PARAMS={https:!0,token:"YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm",urlCount:3,e 98 | ''' 99 | for line in allJSstuff.split(','): 100 | if line.find('token:') >= 0: 101 | if verbose: print "line is", line 102 | token = line.split('"')[1] 103 | if verbose: print "token is", token 104 | if token: 105 | break 106 | 107 | # https://api.fast.com/netflix/speedtest?https=true&token=YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm&urlCount=3 108 | # https://api.fast.com/netflix/speedtest?https=true&token=YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm&urlCount=3 109 | # lynx --dump 'https://api.fast.com/netflix/speedtest?https=true&token=YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm&urlCount=3' | python -mjson.tool 110 | #url = 'https://api.fast.com/netflix/speedtest?https=true&token=YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm&urlCount=3' 111 | 112 | 113 | # With the token, get the (3) speed-test-URLS from api.fast.com (which will be in JSON format): 114 | baseurl = 'https://api.fast.com/' 115 | if forceipv4: 116 | # force IPv4 by connecting to an IPv4 address of api.fast.com (over ... HTTP) 117 | ipv4 = findipv4('api.fast.com') 118 | baseurl = 'http://' + ipv4 + '/' # HTTPS does not work IPv4 addresses, thus use HTTP 119 | elif forceipv6: 120 | # force IPv6 121 | ipv6 = findipv6('api.fast.com') 122 | baseurl = 'http://[' + ipv6 + ']/' 123 | 124 | url = baseurl + 'netflix/speedtest?https=true&token=' + token + '&urlCount=3' # Not more than 3 possible 125 | if verbose: print "API url is", url 126 | try: 127 | urlresult = urllib2.urlopen(url, None, 2) # 2 second time-out 128 | except: 129 | # not good 130 | if verbose: print "No connection possible" # probably IPv6, or just no network 131 | return 0 # no connection, thus no speed 132 | 133 | jsonresult = urlresult.read() 134 | parsedjson = json.loads(jsonresult) 135 | 136 | # Prepare for getting those URLs in a threaded way: 137 | amount = len(parsedjson) 138 | if verbose: print "Number of URLs:", amount 139 | threads = [None] * amount 140 | results = [0] * amount 141 | urls = [None] * amount 142 | i = 0 143 | for jsonelement in parsedjson: 144 | urls[i] = jsonelement['url'] # fill out speed test url from the json format 145 | if verbose: print jsonelement['url'] 146 | i = i+1 147 | 148 | # Let's check whether it's IPv6: 149 | for url in urls: 150 | fqdn = url.split('/')[2] 151 | try: 152 | socket.getaddrinfo(fqdn, None, socket.AF_INET6) 153 | if verbose: print "IPv6" 154 | except: 155 | pass 156 | 157 | 158 | # Now start the threads 159 | for i in range(len(threads)): 160 | #print "Thread: i is", i 161 | threads[i] = Thread(target=gethtmlresult, args=(urls[i], results, i)) 162 | threads[i].daemon=True 163 | threads[i].start() 164 | 165 | # Monitor the amount of bytes (and speed) of the threads 166 | time.sleep(1) 167 | sleepseconds = 3 # 3 seconds sleep 168 | lasttotal = 0 169 | highestspeedkBps = 0 170 | maxdownload = 60 #MB 171 | nrloops = maxtime / sleepseconds 172 | for loop in range(nrloops): 173 | total = 0 174 | for i in range(len(threads)): 175 | #print i, results[i] 176 | total += results[i] 177 | delta = total-lasttotal 178 | speedkBps = (delta/sleepseconds)/(1024) 179 | if verbose: 180 | print "Loop", loop, "Total MB", total/(1024*1024), "Delta MB", delta/(1024*1024), "Speed kB/s:", speedkBps, "aka Mbps %.1f" % (application_bytes_to_networkbits(speedkBps)/1024) 181 | ''' 182 | if total/(1024*1024) > maxdownload: 183 | break 184 | ''' 185 | lasttotal = total 186 | if speedkBps > highestspeedkBps: 187 | highestspeedkBps = speedkBps 188 | time.sleep(sleepseconds) 189 | ''' 190 | print "Now wait for threads to end:" 191 | for i in range(len(threads)): 192 | threads[i].join() 193 | ''' 194 | 195 | Mbps = (application_bytes_to_networkbits(highestspeedkBps)/1024) 196 | Mbps = float("%.1f" % Mbps) 197 | if verbose: print "Highest Speed (kB/s):", highestspeedkBps, "aka Mbps ", Mbps 198 | 199 | #print "Debug: total in bytes", total 200 | 201 | return Mbps 202 | 203 | 204 | ######## MAIN ################# 205 | 206 | 207 | if __name__ == "__main__": 208 | print "let's speed test:" 209 | print "\nSpeed test, without logging:" 210 | print fast_com() 211 | print "\nSpeed test, with logging:" 212 | print fast_com(verbose=True) 213 | print "\nSpeed test, IPv4, with verbose logging:" 214 | print fast_com(verbose=True, maxtime=18, forceipv4=True) 215 | print "\nSpeed test, IPv6:" 216 | print fast_com(maxtime=12, forceipv6=True) 217 | print "\n30 second speed test:" 218 | fast_com(verbose=True, maxtime=30) 219 | 220 | print "\ndone" 221 | 222 | 223 | -------------------------------------------------------------------------------- /dependencies/fast_com_example_usage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import fast_com 4 | 5 | print "Start speedtest against fast.com ..." 6 | print "Result:", fast_com.fast_com(), "Mbps" 7 | print "... Done" 8 | 9 | -------------------------------------------------------------------------------- /dependencies/ijcnf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 3 | export PATH 4 | Green_font="\033[32m" && Red_font="\033[31m" && Font_suffix="\033[0m" 5 | Info="${Green_font}[Info]${Font_suffix}" 6 | Error="${Red_font}[Error]${Font_suffix}" 7 | echo -e "${Green_font} 8 | #====================================== 9 | # Project: besttrace(ICMP) 10 | # Version: 0.0.2 11 | # Blog: https://vpsxb.net 12 | #====================================== 13 | ${Font_suffix}" 14 | 15 | check_system(){ 16 | if [[ ! -z "`cat /etc/issue | grep -iE "debian"`" ]]; then 17 | apt-get install traceroute mtr -y 18 | elif [[ ! -z "`cat /etc/issue | grep -iE "ubuntu"`" ]]; then 19 | apt-get install traceroute mtr -y 20 | elif [[ ! -z "`cat /etc/redhat-release | grep -iE "CentOS"`" ]]; then 21 | yum install traceroute mtr -y 22 | else 23 | echo -e "${Error} system not support!" && exit 1 24 | fi 25 | } 26 | check_root(){ 27 | [[ "`id -u`" != "0" ]] && echo -e "${Error} must be root user !" && exit 1 28 | } 29 | directory(){ 30 | [[ ! -d /home/tstrace ]] && mkdir -p /home/tstrace 31 | cd /home/tstrace 32 | } 33 | install(){ 34 | [[ ! -d /home/tstrace/besttrace ]] && wget -O BestTrace.tar.gz https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/BestTrace.tar.gz && tar -zxf BestTrace.tar.gz && rm BestTrace.tar.gz 35 | [[ ! -d /home/tstrace/besttrace ]] && echo -e "${Error} download failed, please check!" && exit 1 36 | chmod -R +x /home/tstrace 37 | } 38 | 39 | 40 | 41 | test_single(){ 42 | echo -e "${Info} 请输入你要测试的目标 ip :" 43 | read -p "输入 ip 地址:" ip 44 | 45 | while [[ -z "${ip}" ]] 46 | do 47 | echo -e "${Error} 无效输入" 48 | echo -e "${Info} 请重新输入" && read -p "输入 ip 地址:" ip 49 | done 50 | 51 | ./besttrace -q1 -g cn ${ip} | tee -a -i /home/tstrace/tstrace.log 2>/dev/null 52 | 53 | repeat_test_single 54 | } 55 | repeat_test_single(){ 56 | echo -e "${Info} 是否继续测试其他目标 ip ?" 57 | echo -e "1.是\n2.否" 58 | read -p "请选择:" whether_repeat_single 59 | while [[ ! "${whether_repeat_single}" =~ ^[1-2]$ ]] 60 | do 61 | echo -e "${Error} 无效输入" 62 | echo -e "${Info} 请重新输入" && read -p "请选择:" whether_repeat_single 63 | done 64 | [[ "${whether_repeat_single}" == "1" ]] && test_single 65 | [[ "${whether_repeat_single}" == "2" ]] && echo -e "${Info} 退出脚本 ..." && exit 0 66 | } 67 | 68 | 69 | 70 | test_alternative(){ 71 | select_alternative 72 | set_alternative 73 | result_alternative 74 | } 75 | select_alternative(){ 76 | echo -e "${Info} 选择需要测速的目标网络: \n1.中国电信\n2.中国联通\n3.中国移动\n4.教育网" 77 | read -p "输入数字以选择:" ISP 78 | 79 | while [[ ! "${ISP}" =~ ^[1-4]$ ]] 80 | do 81 | echo -e "${Error} 无效输入" 82 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" ISP 83 | done 84 | } 85 | set_alternative(){ 86 | [[ "${ISP}" == "1" ]] && node_1 87 | [[ "${ISP}" == "2" ]] && node_2 88 | [[ "${ISP}" == "3" ]] && node_3 89 | [[ "${ISP}" == "4" ]] && node_4 90 | } 91 | node_1(){ 92 | echo -e "1.上海电信\n2.上海CN2\n3.厦门CN2\n4.杭州电信\n5.嘉兴电信\n6.广州电信(天翼云)\n7.云南昆明电信" && read -p "输入数字以选择:" node 93 | 94 | while [[ ! "${node}" =~ ^[1-7]$ ]] 95 | do 96 | echo -e "${Error} 无效输入" 97 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node 98 | done 99 | 100 | [[ "${node}" == "1" ]] && ISP_name="上海电信" && ip=101.95.206.10 101 | [[ "${node}" == "2" ]] && ISP_name="上海CN2" && ip=58.32.0.1 102 | [[ "${node}" == "3" ]] && ISP_name="厦门CN2" && ip=117.28.254.129 103 | [[ "${node}" == "4" ]] && ISP_name="杭州电信" && ip=220.191.200.25 104 | [[ "${node}" == "5" ]] && ISP_name="嘉兴电信" && ip=183.134.62.129 105 | [[ "${node}" == "6" ]] && ISP_name="广州电信(天翼云)" && ip=14.215.116.1 106 | [[ "${node}" == "7" ]] && ISP_name="云南昆明电信" && ip=116.55.247.129 107 | } 108 | node_2(){ 109 | echo -e "1.深圳联通\n2.北京联通\n3.杭州联通\n4.安徽合肥联通\n5.嘉兴联通\n6.上海联通\n7.上海联通9929" && read -p "输入数字以选择:" node 110 | 111 | while [[ ! "${node}" =~ ^[1-7]$ ]] 112 | do 113 | echo -e "${Error} 无效输入" 114 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node 115 | done 116 | 117 | [[ "${node}" == "1" ]] && ISP_name="深圳联通" && ip=210.21.196.6 118 | [[ "${node}" == "2" ]] && ISP_name="北京联通" && ip=202.106.50.1 119 | [[ "${node}" == "3" ]] && ISP_name="杭州联通" && ip=219.158.105.153 120 | [[ "${node}" == "4" ]] && ISP_name="安徽合肥联通" && ip=112.122.10.26 121 | [[ "${node}" == "5" ]] && ISP_name="嘉兴联通" && ip=60.12.95.255 122 | [[ "${node}" == "6" ]] && ISP_name="上海联通" && ip=139.226.227.38 123 | [[ "${node}" == "7" ]] && ISP_name="上海联通9929" && ip=210.13.66.238 124 | } 125 | node_3(){ 126 | echo -e "1.上海移动\n2.深圳移动\n3.北京移动\n4.嘉兴移动\n5.杭州移动" && read -p "输入数字以选择:" node 127 | 128 | while [[ ! "${node}" =~ ^[1-5]$ ]] 129 | do 130 | echo -e "${Error} 无效输入" 131 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node 132 | done 133 | 134 | [[ "${node}" == "1" ]] && ISP_name="上海移动" && ip=211.136.112.200 135 | [[ "${node}" == "2" ]] && ISP_name="深圳移动" && ip=120.196.165.24 136 | [[ "${node}" == "3" ]] && ISP_name="北京移动" && ip=221.179.155.161 137 | [[ "${node}" == "4" ]] && ISP_name="嘉兴移动" && ip=223.95.245.102 138 | [[ "${node}" == "5" ]] && ISP_name="杭州移动" && ip=221.183.94.137 139 | } 140 | node_4(){ 141 | ISP_name="北京教育网" && ip=101.4.117.213 142 | } 143 | result_alternative(){ 144 | echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..." 145 | ./besttrace 146 | -q1 -g cn ${ip} | tee -a -i /home/tstrace/tstrace.log 2>/dev/null 147 | echo -e "${Info} 测试路由 到 ${ISP_name} 完成 !" 148 | 149 | repeat_test_alternative 150 | } 151 | repeat_test_alternative(){ 152 | echo -e "${Info} 是否继续测试其他节点?" 153 | echo -e "1.是\n2.否" 154 | read -p "请选择:" whether_repeat_alternative 155 | while [[ ! "${whether_repeat_alternative}" =~ ^[1-2]$ ]] 156 | do 157 | echo -e "${Error} 无效输入" 158 | echo -e "${Info} 请重新输入" && read -p "请选择:" whether_repeat_alternative 159 | done 160 | [[ "${whether_repeat_alternative}" == "1" ]] && test_alternative 161 | [[ "${whether_repeat_alternative}" == "2" ]] && echo -e "${Info} 退出脚本 ..." && exit 0 162 | } 163 | 164 | 165 | 166 | test_all(){ 167 | result_all '101.95.206.10' '上海电信' 168 | result_all '58.32.0.1' '上海CN2' 169 | 170 | result_all '139.226.227.38' '上海联通' 171 | result_all '210.13.66.238' '上海联通9929' 172 | result_all '211.136.112.200' '上海移动' 173 | 174 | result_all '101.4.117.213' '北京教育网' 175 | 176 | echo -e "${Info} 四网路由快速测试 已完成 !" 177 | } 178 | result_all(){ 179 | ISP_name=$2 180 | echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..." 181 | ./besttrace -q1 -g cn $1 182 | echo -e "${Info} 测试路由 到 ${ISP_name} 完成 !" 183 | } 184 | 185 | test_all(){ 186 | result_all '101.95.206.10' '上海电信' 187 | result_all '58.32.0.1' '上海CN2' 188 | 189 | result_all '139.226.227.38' '上海联通' 190 | result_all '210.13.66.238' '上海联通9929' 191 | result_all '211.136.112.200' '上海移动' 192 | 193 | result_all '101.4.117.213' '北京教育网' 194 | 195 | echo -e "${Info} 四网路由快速测试 已完成 !" 196 | } 197 | 198 | check_system 199 | check_root 200 | directory 201 | install 202 | cd besttrace 203 | 204 | echo -e "${Info} 选择你要使用的功能: " 205 | echo -e "1.选择一个运营商进行测试\n2.四网路由快速测试\n3.手动输入 ip 进行测试" 206 | read -p "输入数字以选择:" function 207 | 208 | while [[ ! "${function}" =~ ^[1-3]$ ]] 209 | do 210 | echo -e "${Error} 缺少或无效输入" 211 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" function 212 | done 213 | 214 | if [[ "${function}" == "1" ]]; then 215 | test_alternative 216 | elif [[ "${function}" == "2" ]]; then 217 | test_all | tee -a -i /home/tstrace/tstrace.log 2>/dev/null 218 | else 219 | test_single 220 | fi 221 | -------------------------------------------------------------------------------- /dependencies/jcnf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 3 | export PATH 4 | Green_font="\033[32m" && Red_font="\033[31m" && Font_suffix="\033[0m" 5 | Info="${Green_font}[Info]${Font_suffix}" 6 | Error="${Red_font}[Error]${Font_suffix}" 7 | echo -e "${Green_font} 8 | #====================================== 9 | # Project: besttrace(TCP) 10 | # Version: 0.0.2 11 | # Blog: https://vpsxb.net 12 | #====================================== 13 | ${Font_suffix}" 14 | 15 | check_system(){ 16 | if [[ ! -z "`cat /etc/issue | grep -iE "debian"`" ]]; then 17 | apt-get install traceroute mtr -y 18 | elif [[ ! -z "`cat /etc/issue | grep -iE "ubuntu"`" ]]; then 19 | apt-get install traceroute mtr -y 20 | elif [[ ! -z "`cat /etc/redhat-release | grep -iE "CentOS"`" ]]; then 21 | yum install traceroute mtr -y 22 | else 23 | echo -e "${Error} system not support!" && exit 1 24 | fi 25 | } 26 | check_root(){ 27 | [[ "`id -u`" != "0" ]] && echo -e "${Error} must be root user !" && exit 1 28 | } 29 | directory(){ 30 | [[ ! -d /home/tstrace ]] && mkdir -p /home/tstrace 31 | cd /home/tstrace 32 | } 33 | install(){ 34 | [[ ! -d /home/tstrace/besttrace ]] && wget -O BestTrace.tar.gz https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/BestTrace.tar.gz && tar -zxf BestTrace.tar.gz && rm BestTrace.tar.gz 35 | [[ ! -d /home/tstrace/besttrace ]] && echo -e "${Error} download failed, please check!" && exit 1 36 | chmod -R +x /home/tstrace 37 | } 38 | 39 | 40 | 41 | test_single(){ 42 | echo -e "${Info} 请输入你要测试的目标 ip :" 43 | read -p "输入 ip 地址:" ip 44 | 45 | while [[ -z "${ip}" ]] 46 | do 47 | echo -e "${Error} 无效输入" 48 | echo -e "${Info} 请重新输入" && read -p "输入 ip 地址:" ip 49 | done 50 | 51 | ./besttrace -T -q1 -g cn ${ip} | tee -a -i /home/tstrace/tstrace.log 2>/dev/null 52 | 53 | repeat_test_single 54 | } 55 | repeat_test_single(){ 56 | echo -e "${Info} 是否继续测试其他目标 ip ?" 57 | echo -e "1.是\n2.否" 58 | read -p "请选择:" whether_repeat_single 59 | while [[ ! "${whether_repeat_single}" =~ ^[1-2]$ ]] 60 | do 61 | echo -e "${Error} 无效输入" 62 | echo -e "${Info} 请重新输入" && read -p "请选择:" whether_repeat_single 63 | done 64 | [[ "${whether_repeat_single}" == "1" ]] && test_single 65 | [[ "${whether_repeat_single}" == "2" ]] && echo -e "${Info} 退出脚本 ..." && exit 0 66 | } 67 | 68 | 69 | 70 | test_alternative(){ 71 | select_alternative 72 | set_alternative 73 | result_alternative 74 | } 75 | select_alternative(){ 76 | echo -e "${Info} 选择需要测速的目标网络: \n1.中国电信\n2.中国联通\n3.中国移动\n4.教育网" 77 | read -p "输入数字以选择:" ISP 78 | 79 | while [[ ! "${ISP}" =~ ^[1-4]$ ]] 80 | do 81 | echo -e "${Error} 无效输入" 82 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" ISP 83 | done 84 | } 85 | set_alternative(){ 86 | [[ "${ISP}" == "1" ]] && node_1 87 | [[ "${ISP}" == "2" ]] && node_2 88 | [[ "${ISP}" == "3" ]] && node_3 89 | [[ "${ISP}" == "4" ]] && node_4 90 | } 91 | node_1(){ 92 | echo -e "1.上海电信\n2.上海CN2\n3.厦门CN2\n4.杭州电信\n5.嘉兴电信\n6.广州电信(天翼云)\n7.云南昆明电信" && read -p "输入数字以选择:" node 93 | 94 | while [[ ! "${node}" =~ ^[1-7]$ ]] 95 | do 96 | echo -e "${Error} 无效输入" 97 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node 98 | done 99 | 100 | [[ "${node}" == "1" ]] && ISP_name="上海电信" && ip=101.95.206.10 101 | [[ "${node}" == "2" ]] && ISP_name="上海CN2" && ip=58.32.0.1 102 | [[ "${node}" == "3" ]] && ISP_name="厦门CN2" && ip=117.28.254.129 103 | [[ "${node}" == "4" ]] && ISP_name="杭州电信" && ip=220.191.200.25 104 | [[ "${node}" == "5" ]] && ISP_name="嘉兴电信" && ip=183.134.62.129 105 | [[ "${node}" == "6" ]] && ISP_name="广州电信(天翼云)" && ip=14.215.116.1 106 | [[ "${node}" == "7" ]] && ISP_name="云南昆明电信" && ip=116.55.247.129 107 | } 108 | node_2(){ 109 | echo -e "1.深圳联通\n2.北京联通\n3.杭州联通\n4.安徽合肥联通\n5.嘉兴联通\n6.上海联通\n7.上海联通9929" && read -p "输入数字以选择:" node 110 | 111 | while [[ ! "${node}" =~ ^[1-7]$ ]] 112 | do 113 | echo -e "${Error} 无效输入" 114 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node 115 | done 116 | 117 | [[ "${node}" == "1" ]] && ISP_name="深圳联通" && ip=210.21.196.6 118 | [[ "${node}" == "2" ]] && ISP_name="北京联通" && ip=202.106.50.1 119 | [[ "${node}" == "3" ]] && ISP_name="杭州联通" && ip=219.158.105.153 120 | [[ "${node}" == "4" ]] && ISP_name="安徽合肥联通" && ip=112.122.10.26 121 | [[ "${node}" == "5" ]] && ISP_name="嘉兴联通" && ip=60.12.95.255 122 | [[ "${node}" == "6" ]] && ISP_name="上海联通" && ip=139.226.227.38 123 | [[ "${node}" == "7" ]] && ISP_name="上海联通9929" && ip=210.13.66.238 124 | } 125 | node_3(){ 126 | echo -e "1.上海移动\n2.深圳移动\n3.北京移动\n4.嘉兴移动\n5.杭州移动" && read -p "输入数字以选择:" node 127 | 128 | while [[ ! "${node}" =~ ^[1-5]$ ]] 129 | do 130 | echo -e "${Error} 无效输入" 131 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node 132 | done 133 | 134 | [[ "${node}" == "1" ]] && ISP_name="上海移动" && ip=211.136.112.200 135 | [[ "${node}" == "2" ]] && ISP_name="深圳移动" && ip=120.196.165.24 136 | [[ "${node}" == "3" ]] && ISP_name="北京移动" && ip=221.179.155.161 137 | [[ "${node}" == "4" ]] && ISP_name="嘉兴移动" && ip=223.95.245.102 138 | [[ "${node}" == "5" ]] && ISP_name="杭州移动" && ip=221.183.94.137 139 | } 140 | node_4(){ 141 | ISP_name="北京教育网" && ip=101.4.117.213 142 | } 143 | result_alternative(){ 144 | echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..." 145 | ./besttrace -T -q1 -g cn ${ip} | tee -a -i /home/tstrace/tstrace.log 2>/dev/null 146 | echo -e "${Info} 测试路由 到 ${ISP_name} 完成 !" 147 | 148 | repeat_test_alternative 149 | } 150 | repeat_test_alternative(){ 151 | echo -e "${Info} 是否继续测试其他节点?" 152 | echo -e "1.是\n2.否" 153 | read -p "请选择:" whether_repeat_alternative 154 | while [[ ! "${whether_repeat_alternative}" =~ ^[1-2]$ ]] 155 | do 156 | echo -e "${Error} 无效输入" 157 | echo -e "${Info} 请重新输入" && read -p "请选择:" whether_repeat_alternative 158 | done 159 | [[ "${whether_repeat_alternative}" == "1" ]] && test_alternative 160 | [[ "${whether_repeat_alternative}" == "2" ]] && echo -e "${Info} 退出脚本 ..." && exit 0 161 | } 162 | 163 | 164 | 165 | test_all(){ 166 | result_all '101.95.206.10' '上海电信' 167 | result_all '58.32.0.1' '上海CN2' 168 | 169 | result_all '139.226.227.38' '上海联通' 170 | result_all '210.13.66.238' '上海联通9929' 171 | result_all '211.136.112.200' '上海移动' 172 | 173 | result_all '101.4.117.213' '北京教育网' 174 | 175 | echo -e "${Info} 四网路由快速测试 已完成 !" 176 | } 177 | result_all(){ 178 | ISP_name=$2 179 | echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..." 180 | ./besttrace -T -q1 -g cn $1 181 | echo -e "${Info} 测试路由 到 ${ISP_name} 完成 !" 182 | } 183 | 184 | test_all(){ 185 | result_all '101.95.206.10' '上海电信' 186 | result_all '58.32.0.1' '上海CN2' 187 | 188 | result_all '139.226.227.38' '上海联通' 189 | result_all '210.13.66.238' '上海联通9929' 190 | result_all '211.136.112.200' '上海移动' 191 | 192 | result_all '101.4.117.213' '北京教育网' 193 | 194 | echo -e "${Info} 四网路由快速测试 已完成 !" 195 | } 196 | 197 | check_system 198 | check_root 199 | directory 200 | install 201 | cd besttrace 202 | 203 | echo -e "${Info} 选择你要使用的功能: " 204 | echo -e "1.选择一个运营商进行测试\n2.四网路由快速测试\n3.手动输入 ip 进行测试" 205 | read -p "输入数字以选择:" function 206 | 207 | while [[ ! "${function}" =~ ^[1-3]$ ]] 208 | do 209 | echo -e "${Error} 缺少或无效输入" 210 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" function 211 | done 212 | 213 | if [[ "${function}" == "1" ]]; then 214 | test_alternative 215 | elif [[ "${function}" == "2" ]]; then 216 | test_all | tee -a -i /home/tstrace/tstrace.log 2>/dev/null 217 | else 218 | test_single 219 | fi 220 | -------------------------------------------------------------------------------- /dependencies/jg.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" 4 | Info="${Green_font_prefix}[信息]${Font_color_suffix}" 5 | Error="${Red_font_prefix}[错误]${Font_color_suffix}" 6 | Tip="${Green_font_prefix}[注意]${Font_color_suffix}" 7 | 8 | while [[ $# -ge 1 ]]; do 9 | case $1 in 10 | --mirror) 11 | FASTGIT="镜像加速" 12 | shift 13 | ;; 14 | --dev) 15 | AURORA_VERSION="DEV" 16 | shift 17 | ;; 18 | *) 19 | echo -e "${Error} 请检查脚本输入的参数是否正确!" 20 | exit 1 21 | esac 22 | done 23 | 24 | if [[ $(curl -m 10 -s https://api.ip.sb/geoip | grep 'China') != "" ]]; then 25 | echo -e "${Tip} 根据 ip.sb 提供的信息,当前 IP 可能在中国" 26 | read -e -r -p "是否选用镜像完成安装? [Y/n] " input 27 | case $input in 28 | [yY][eE][sS] | [yY]) 29 | echo -e "${Tip} 使用中国镜像" 30 | FASTGIT="镜像加速" 31 | ;; 32 | [nN][oO] | [nN]) 33 | echo -e "${Tip} 不使用中国镜像" 34 | ;; 35 | *) 36 | echo "使用中国镜像" 37 | FASTGIT="镜像加速" 38 | ;; 39 | esac 40 | fi 41 | 42 | [[ $EUID != 0 ]] && echo -e "${Error} 请使用 root 账号运行该脚本!" && exit 1 43 | 44 | AURORA_HOME="$HOME/aurora" 45 | AURORA_HOME_BACKUP="$HOME/aurora_backup" 46 | AURORA_DOCKER_YML=${AURORA_HOME}/docker-compose.yml 47 | AURORA_DOCKER_YML_TEMP=${AURORA_HOME}/docker-compose.yml.tmp 48 | [[ -z $FASTGIT ]] && GITHUB_RAW_URL="raw.githubusercontent.com" || GITHUB_RAW_URL="raw.fastgit.org" 49 | AURORA_GITHUB="Aurora-Admin-Panel" 50 | AURORA_YML_URL="https://${GITHUB_RAW_URL}/${AURORA_GITHUB}/deploy/main/docker-compose.yml" 51 | AURORA_DEV_YML_URL="https://${GITHUB_RAW_URL}/${AURORA_GITHUB}/deploy/main/docker-compose-dev.yml" 52 | DOCKER_INSTALL_URL="https://get.docker.com" 53 | [[ -z $FASTGIT ]] && GITHUB_URL="github.com" || GITHUB_URL="download.fastgit.org" 54 | DOCKER_COMPOSE_URL="https://${GITHUB_URL}/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" 55 | 56 | AURORA_DEF_IP="" 57 | AURORA_DEF_PORT=8000 58 | AURORA_DEF_TRAFF_MIN=10 59 | AURORA_DEF_DDNS_MIN=2 60 | 61 | function check_system() { 62 | source '/etc/os-release' 63 | ARCH=$(uname -m) 64 | [[ $ARCH == "x86_64" || $ARCH == "aarch64" ]] || \ 65 | (echo -e "${Error} 极光面板仅支持安装在 X64 或 ARM64 架构的机器上!" && exit 1) 66 | if [[ $ID = "centos" ]]; then 67 | OS_FAMILY="centos" 68 | UPDATE="yum makecache -q -y" 69 | INSTALL="yum install -q -y" 70 | elif [[ $ID = "debian" || $ID = "ubuntu" ]]; then 71 | OS_FAMILY="debian" 72 | UPDATE="apt update -qq -y" 73 | INSTALL="apt install -qq -y" 74 | elif [[ $ID = "alpine" ]]; then 75 | OS_FAMILY="alpine" 76 | UPDATE="apk update" 77 | INSTALL="apk add" 78 | else 79 | echo -e "${Error} 系统 $ID $VERSION_ID 暂不支持一键脚本,请尝试手动安装!" && exit 1 80 | fi 81 | } 82 | 83 | function install_software() { 84 | [[ -z $1 ]] || \ 85 | (type $1 > /dev/null 2>&1 || (echo -e "开始安装依赖 $1 ..." && $INSTALL $1) || ($UPDATE && $INSTALL $1)) 86 | } 87 | 88 | function install_docker() { 89 | if ! docker --version > /dev/null 2>&1; then 90 | if [[ $OS_FAMILY = "centos" || $OS_FAMILY = "debian" ]]; then 91 | curl -fsSL ${DOCKER_INSTALL_URL} | bash -s docker --mirror Aliyun 92 | systemctl enable --now docker && \ 93 | while ! systemctl is-active --quiet docker; do sleep 3; done 94 | elif [[ $OS_FAMILY = "alpine" ]]; then 95 | ($INSTALL docker || ($UPDATE && $INSTALL docker)) && \ 96 | rc-update add docker boot && \ 97 | service docker start && \ 98 | while [[ -z $(service docker status | grep started) ]]; do sleep 3; done 99 | fi 100 | fi 101 | } 102 | 103 | function install_docker_compose() { 104 | if ! docker-compose --version > /dev/null 2>&1; then 105 | curl -fsSL ${DOCKER_COMPOSE_URL} -o /usr/local/bin/docker-compose && \ 106 | chmod +x /usr/local/bin/docker-compose && \ 107 | ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose 108 | fi 109 | } 110 | 111 | function install_all() { 112 | install_software wget 113 | install_software curl 114 | install_docker 115 | install_docker_compose 116 | } 117 | 118 | function get_config() { 119 | echo -e "${Info} 正在下载最新配置文件 ..." 120 | [[ $AURORA_VERSION == "DEV" ]] && YML_URL=${AURORA_DEV_YML_URL} || YML_URL=${AURORA_YML_URL} 121 | wget -q $YML_URL -O ${AURORA_DOCKER_YML_TEMP} 122 | [[ -z $(grep aurora ${AURORA_DOCKER_YML_TEMP}) ]] && echo -e "${Error} 配置文件下载失败,请检查网络连接是否正常!" && exit 1 123 | mv -f ${AURORA_DOCKER_YML_TEMP} ${AURORA_DOCKER_YML} 124 | } 125 | 126 | function check_install() { 127 | [ -f ${AURORA_DOCKER_YML} ] || (echo -e "${Tip} 未检测到已经安装极光面板,请先安装!" && exit 1) 128 | } 129 | 130 | function match_config() { 131 | [[ -z $1 ]] || TEMP=$(cat ${AURORA_DOCKER_YML} | awk -v name="$1" '{ if ( $0 ~ name ){ print $2; } }' | head -n 1) 132 | [[ -z $TEMP ]] && [[ -n $2 ]] && echo $2 || echo $TEMP 133 | } 134 | 135 | function read_config() { 136 | ENABLE_SENTRY=$(match_config ENABLE_SENTRY \'no\') 137 | TRAFFIC_INTERVAL_SECONDS=$(match_config TRAFFIC_INTERVAL_SECONDS 600) 138 | DDNS_INTERVAL_SECONDS=$(match_config DDNS_INTERVAL_SECONDS 120) 139 | } 140 | 141 | function set_config() { 142 | [[ -z $ENABLE_SENTRY ]] || sed -i "s/ENABLE_SENTRY:.*$/ENABLE_SENTRY: $ENABLE_SENTRY/" ${AURORA_DOCKER_YML} 143 | [[ -z $TRAFFIC_INTERVAL_SECONDS ]] || sed -i "s/TRAFFIC_INTERVAL_SECONDS:.*$/TRAFFIC_INTERVAL_SECONDS: $TRAFFIC_INTERVAL_SECONDS/" ${AURORA_DOCKER_YML} 144 | [[ -z $DDNS_INTERVAL_SECONDS ]] || sed -i "s/DDNS_INTERVAL_SECONDS:.*$/DDNS_INTERVAL_SECONDS: $DDNS_INTERVAL_SECONDS/" ${AURORA_DOCKER_YML} 145 | } 146 | 147 | function read_port() { 148 | IP=$(grep -A 1 port ${AURORA_DOCKER_YML} | grep -Eo "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)") 149 | [[ -z $IP ]] && PORT=$(grep -A 1 port ${AURORA_DOCKER_YML} | grep -Eo "[[:digit:]]+:" | grep -Eo "[[:digit:]]+") || \ 150 | PORT=$(grep -A 1 port ${AURORA_DOCKER_YML} | grep -Eo ":[[:digit:]]+:" | grep -Eo "[[:digit:]]+") 151 | [[ -z $PORT ]] && echo -e "${Error} 未检测到旧端口号,请检查配置文件是否正确!" && exit 1 152 | } 153 | 154 | function set_port() { 155 | [[ -z $1 ]] && PORT=${AURORA_DEF_PORT} || PORT=$1 156 | NEW_PORT=$(echo $2 | grep -Eo "[[:digit:]]+") 157 | [[ -z $NEW_PORT ]] && echo -e "${Error} 未检测到新端口号!" && exit 1 158 | [[ -z $IP ]] && sed -i "s/- $PORT:80/- $NEW_PORT:80/" ${AURORA_DOCKER_YML} || \ 159 | (sed -i "s/- $PORT:80/- $IP:$NEW_PORT:80/" ${AURORA_DOCKER_YML} && \ 160 | sed -i "s/- $IP:$PORT:80/- $IP:$NEW_PORT:80/" ${AURORA_DOCKER_YML}) 161 | } 162 | 163 | function check_run() { 164 | LEVEL=$1 && [[ -z $LEVEL || $LEVEL != ${Info} || $LEVEL != ${Tip} || $LEVEL != ${Error} ]] && LEVEL=${Tip} 165 | TIPS=$2 && [[ -z $TIPS ]] && TIPS="极光面板未在运行!" 166 | [[ -z $(docker ps | grep aurora) ]] && echo -e "${LEVEL} $TIPS" 167 | } 168 | 169 | 170 | function change_port() { 171 | check_install || exit 1 172 | check_run && exit 1 173 | read_port 174 | echo -e "${Info} 旧端口号: $PORT" 175 | read -r -e -p "请输入新端口: " NEW_PORT 176 | set_port $PORT $NEW_PORT 177 | read_port 178 | [[ $PORT = $NEW_PORT ]] && cd ${AURORA_HOME} && docker-compose up -d && \ 179 | echo -e "${Info} 端口修改成功!" || echo -e "${Error} 端口修改失败!" 180 | } 181 | 182 | function sec_to_min() { 183 | [[ -z $1 ]] || sec=$(echo $1 | grep -v "\." | grep -Eo "[[:digit:]]+") 184 | [[ -z $sec ]] || ((min=$sec/60)) 185 | echo $min 186 | } 187 | 188 | function min_to_sec() { 189 | [[ -z $1 ]] || min=$(echo $1 | grep -v "\." | grep -Eo "[[:digit:]]+") 190 | [[ -z $min ]] || ((sec=$min*60)) 191 | echo $sec 192 | } 193 | 194 | function echo_config() { 195 | [[ -z $IP ]] || echo -e "${Info} 面板监听地址: $IP" 196 | [[ -z $PORT ]] || echo -e "${Info} 面板监听端口: $PORT" 197 | [[ -z $ENABLE_SENTRY ]] || echo -e "${Info} 开启错误跟踪: $ENABLE_SENTRY" 198 | [[ -z $TRAFFIC_INTERVAL_SECONDS ]] || echo -e "${Info} 流量同步周期: $(sec_to_min $TRAFFIC_INTERVAL_SECONDS) 分钟" 199 | [[ -z $DDNS_INTERVAL_SECONDS ]] || echo -e "${Info} DDNS同步周期: $(sec_to_min $DDNS_INTERVAL_SECONDS) 分钟" 200 | } 201 | 202 | function install() { 203 | install_all 204 | [[ -n $(docker ps | grep aurora) ]] && echo -e "${Tip} 极光面板已经安装,且正在运行!" && exit 0 205 | [[ -d ${AURORA_HOME} ]] || mkdir -p ${AURORA_HOME} 206 | cd ${AURORA_HOME} 207 | get_config || exit 1 208 | echo "-----------------------------------" 209 | read_config 210 | read_port 211 | echo_config 212 | echo "-----------------------------------" 213 | docker-compose up -d && docker-compose exec backend python app/initial_data.py && \ 214 | (echo -e "${Info} 极光面板安装成功,已启动!" && exit 0) || (echo -e "${Error} 极光面板安装失败!" && exit 1) 215 | } 216 | 217 | function update() { 218 | check_install && install_all || exit 1 219 | cd ${AURORA_HOME} 220 | echo -e "${Info} 同步旧配置文件中 ..." 221 | echo "-----------------------------------" 222 | read_config 223 | read_port 224 | echo_config 225 | echo "-----------------------------------" 226 | get_config || exit 1 227 | set_config 228 | set_port ${AURORA_DEF_PORT} $PORT 229 | echo -e "${Info} 同步新配置文件完成!" 230 | [[ -z $(docker ps | grep aurora | grep postgres) ]] && \ 231 | echo -e "${Error} 请先运行极光面板,以保证更新前完成自动备份旧数据库!" && exit 1 || \ 232 | (echo -e "${Tip} 正在备份旧数据库,如果更新后出现问题,请回退旧版本并恢复旧数据库!" && backup) 233 | docker-compose pull && docker-compose down --remove-orphans 234 | OLD_IMG_IDS=$(docker images | grep aurora | grep -v latest | awk '{ print $3; }') 235 | [[ -z $OLD_IMG_IDS ]] || (docker image rm $OLD_IMG_IDS && echo -e "${Info} 旧版镜像清理完成!") 236 | docker-compose up -d && \ 237 | (echo -e "${Info} 极光面板更新成功!" && exit 0) || (echo -e "${Error} 极光面板更新失败!" && exit 1) 238 | } 239 | 240 | function backup_data_after_uninstall(){ 241 | if [ ! -d ${AURORA_HOME_BACKUP} ]; then 242 | mkdir ${AURORA_HOME_BACKUP} 243 | fi 244 | cp -f ${AURORA_HOME}/data-*.sql ${AURORA_HOME_BACKUP}/ 245 | echo -e "${Tip} 已有的数据库备份文件已移动到备份目录:${AURORA_HOME_BACKUP}" && \ 246 | echo -e "${Tip} 如果不需要备份,可自行删除文件 rm -rf ${AURORA_HOME_BACKUP}" 247 | } 248 | 249 | function uninstall() { 250 | [ -f ${AURORA_DOCKER_YML} ] || (echo -e "${Tip} 未检测到已经安装极光面板!" && exit 0) 251 | [[ -n $(docker ps | grep aurora | grep postgres) ]] && \ 252 | echo -e "${Tip} 正在备份数据库,如果意外卸载请重新安装面板并恢复数据库!" && backup 253 | backup_data_after_uninstall 254 | cd ${AURORA_HOME} 255 | [[ -n $(docker ps | grep aurora) ]] && docker-compose down 256 | OLD_IMG_IDS=$(docker images | grep aurora | awk '{ print $3; }') 257 | [[ -z $OLD_IMG_IDS ]] || (docker image rm $OLD_IMG_IDS && echo -e "${Info} 镜像清理完成!") 258 | docker volume rm aurora_db-data && docker volume rm aurora_app-data && \ 259 | (rm -rf ${AURORA_HOME} && echo -e "${Info} 卸载成功!" && exit 0) || (echo -e "${Error} 卸载失败!" && exit 1) 260 | } 261 | 262 | function start() { 263 | check_install || exit 1 264 | [[ -n $(docker ps | grep aurora) ]] && echo -e "${Info} 极光面板正在运行" && exit 0 265 | cd ${AURORA_HOME} && docker-compose up -d && echo -e "${Info} 启动成功!" || echo -e "${Error} 启动失败!" 266 | } 267 | 268 | function stop() { 269 | check_install || exit 1 270 | check_run ${Info} && exit 0 271 | cd ${AURORA_HOME} && docker-compose down && echo -e "${Info} 停止成功!" || echo -e "${Error} 停止失败!" 272 | } 273 | 274 | function restart() { 275 | check_install || exit 1 276 | check_run ${Tip} "极光面板未在运行,请直接启动!" && exit 0 277 | cd ${AURORA_HOME} && docker-compose restart && echo -e "${Info} 重启成功!" || echo -e "${Error} 重启失败!" 278 | } 279 | 280 | function backend_logs() { 281 | check_install || exit 1 282 | check_run && exit 1 283 | cd ${AURORA_HOME} && docker-compose logs -f --tail="100" backend worker 284 | } 285 | 286 | function frontend_logs() { 287 | check_install || exit 1 288 | check_run && exit 1 289 | cd ${AURORA_HOME} && docker-compose logs -f --tail="100" frontend 290 | } 291 | 292 | function all_logs() { 293 | check_install || exit 1 294 | check_run && exit 1 295 | cd ${AURORA_HOME} && docker-compose logs -f --tail="100" 296 | } 297 | 298 | function export_logs() { 299 | check_install || exit 1 300 | check_run && exit 1 301 | cd ${AURORA_HOME} && docker-compose logs > logs && \ 302 | echo -e "${Info} 日志导出成功:${AURORA_HOME}/logs" || echo -e "${Error} 日志导出失败!" 303 | } 304 | 305 | function read_db_info() { 306 | DB_USER=$(grep POSTGRES_USER ${AURORA_DOCKER_YML} | awk '{print $2}') 307 | [[ -z $DB_USER ]] && DB_USER="aurora" 308 | DB_NAME=$(grep POSTGRES_DB ${AURORA_DOCKER_YML} | awk '{print $2}') 309 | [[ -z $DB_NAME ]] && DB_NAME="aurora" 310 | } 311 | 312 | function backup() { 313 | check_install || exit 1 314 | [[ -z $(docker ps | grep aurora | grep postgres) ]] && echo -e "${Tip} 极光面板未在运行,请先启动!" && exit 1 315 | BACKUP_FILE="data-$(date +%Y%m%d%H%M%S).sql" 316 | read_db_info 317 | cd ${AURORA_HOME} && docker-compose exec -T postgres pg_dump -d $DB_NAME -U $DB_USER -c > $BACKUP_FILE && \ 318 | echo -e "${Info} 数据库备份成功:${AURORA_HOME}/$BACKUP_FILE" || echo -e "${Error} 数据库备份失败!" 319 | } 320 | 321 | function restore() { 322 | check_install || exit 1 323 | [[ -z $(docker ps | grep aurora | grep postgres) ]] && \ 324 | echo -e "${Error} 请先运行极光面板,以保证还原前完成自动备份旧数据库!" && exit 1 || \ 325 | (echo -e "${Tip} 正在备份旧数据库,如果还原后出现问题,请恢复旧数据库!" && backup) 326 | read -r -e -p "请输入需恢复的数据库文件路径: " BACKUP_FILE 327 | [[ ! -f $BACKUP_FILE ]] && echo -e "${Error} 无法找到数据库文件!" && exit 1 328 | cd ${AURORA_HOME} 329 | read_db_info 330 | docker stop $(docker-compose ps | grep aurora | grep -v postgres | awk '{ print $1; }') && \ 331 | docker-compose exec -T postgres psql -d $DB_NAME -U $DB_USER < $BACKUP_FILE > /dev/null && \ 332 | docker-compose up -d && \ 333 | echo -e "${Info} 数据库还原成功!" || echo -e "${Error} 数据库还原失败!" 334 | } 335 | 336 | function add_superu() { 337 | check_install || exit 1 338 | [[ -z $(docker ps | grep aurora | grep backend) ]] && echo -e "${Tip} 极光面板未在运行,请先启动!" && exit 1 339 | cd ${AURORA_HOME} && docker-compose exec backend python app/initial_data.py 340 | } 341 | 342 | function set_traffic_interval() { 343 | check_install || exit 1 344 | check_run && exit 1 345 | read_config 346 | echo -e "${Info} 旧流量同步间隔: $(sec_to_min $TRAFFIC_INTERVAL_SECONDS) 分钟" 347 | read -r -e -p "请输入新同步间隔 [分钟]: " NEW_TRAFFIC_INTERVAL_MIN 348 | NEW_TRAFFIC_INTERVAL_SEC=$(min_to_sec $NEW_TRAFFIC_INTERVAL_MIN) 349 | [[ -z $NEW_TRAFFIC_INTERVAL_SEC ]] && echo -e "${Error} 请输入整数分钟!" && exit 1 || \ 350 | sed -i "s/TRAFFIC_INTERVAL_SECONDS:.*$/TRAFFIC_INTERVAL_SECONDS: $NEW_TRAFFIC_INTERVAL_SEC/" ${AURORA_DOCKER_YML} 351 | read_config 352 | [[ $TRAFFIC_INTERVAL_SECONDS = $NEW_TRAFFIC_INTERVAL_SEC ]] && cd ${AURORA_HOME} && docker-compose up -d && \ 353 | echo -e "${Info} 流量同步间隔修改成功!" || echo -e "${Error} 流量同步间隔修改失败!" 354 | } 355 | 356 | function set_ddns_interval() { 357 | check_install || exit 1 358 | check_run && exit 1 359 | read_config 360 | echo -e "${Info} 旧DDNS同步间隔: $(sec_to_min $DDNS_INTERVAL_SECONDS) 分钟" 361 | read -r -e -p "请输入新同步间隔 [分钟]: " NEW_DDNS_INTERVAL_MIN 362 | NEW_DDNS_INTERVAL_SEC=$(min_to_sec $NEW_DDNS_INTERVAL_MIN) 363 | [[ -z $NEW_DDNS_INTERVAL_SEC ]] && echo -e "${Error} 请输入整数分钟!" && exit 1 || \ 364 | sed -i "s/DDNS_INTERVAL_SECONDS:.*$/DDNS_INTERVAL_SECONDS: $NEW_DDNS_INTERVAL_SEC/" ${AURORA_DOCKER_YML} 365 | read_config 366 | [[ $DDNS_INTERVAL_SECONDS = $NEW_DDNS_INTERVAL_SEC ]] && cd ${AURORA_HOME} && docker-compose up -d && \ 367 | echo -e "${Info} DDNS同步间隔修改成功!" || echo -e "${Error} DDNS同步间隔修改失败!" 368 | } 369 | 370 | function welcome_aurora() { 371 | check_system 372 | echo -e "${Green_font_prefix} 373 | 极光面板 一键脚本 374 | -------------------------------- 375 | 1. 安装 极光面板 ${FASTGIT} ${AURORA_VERSION} 376 | 2. 更新 极光面板 ${FASTGIT} ${AURORA_VERSION} 377 | 3. 卸载 极光面板 378 | ———————————— 379 | 4. 启动 极光面板 380 | 5. 停止 极光面板 381 | 6. 重启 极光面板 382 | ———————————— 383 | 7. 查看 后端实时日志 384 | 8. 查看 前端实时日志 385 | 9. 查看 全部实时日志 386 | 10. 导出 全部日志 387 | ———————————— 388 | 11. 备份 数据库 389 | 12. 还原 数据库 390 | 13. 添加 管理员用户 391 | 14. 修改 面板访问端口(默认 ${AURORA_DEF_PORT}) 392 | 15. 修改 面板流量同步间隔(默认 ${AURORA_DEF_TRAFF_MIN} 分钟) 393 | 16. 修改 DDNS同步间隔(默认 ${AURORA_DEF_DDNS_MIN} 分钟) 394 | ———————————— 395 | 0. 退出脚本 396 | ———————————— 397 | ${Font_color_suffix}" 398 | read -r -e -p " 请输入数字 [1-16]: " num && echo 399 | case "$num" in 400 | 1) 401 | install 402 | ;; 403 | 2) 404 | update 405 | ;; 406 | 3) 407 | uninstall 408 | ;; 409 | 4) 410 | start 411 | ;; 412 | 5) 413 | stop 414 | ;; 415 | 6) 416 | restart 417 | ;; 418 | 7) 419 | backend_logs 420 | ;; 421 | 8) 422 | frontend_logs 423 | ;; 424 | 9) 425 | all_logs 426 | ;; 427 | 10) 428 | export_logs 429 | ;; 430 | 11) 431 | backup 432 | ;; 433 | 12) 434 | restore 435 | ;; 436 | 13) 437 | add_superu 438 | ;; 439 | 14) 440 | change_port 441 | ;; 442 | 15) 443 | set_traffic_interval 444 | ;; 445 | 16) 446 | set_ddns_interval 447 | ;; 448 | 0) 449 | exit 0 450 | ;; 451 | *) 452 | echo -e "${Error} 请输入正确数字 [1-16]" 453 | ;; 454 | esac 455 | } 456 | 457 | welcome_aurora 458 | -------------------------------------------------------------------------------- /dependencies/shbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamespan2012/shbox/787cf0fc98d83c7d824a7cc47b4ad9846c23ee48/dependencies/shbox.png -------------------------------------------------------------------------------- /dependencies/speedtest.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamespan2012/shbox/787cf0fc98d83c7d824a7cc47b4ad9846c23ee48/dependencies/speedtest.tgz -------------------------------------------------------------------------------- /dependencies/status.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 3 | export PATH 4 | 5 | #================================================= 6 | # System Required: CentOS/Debian/Ubuntu/ArchLinux 7 | # Description: ServerStatus client + server 8 | # Version: Test v0.4.1 9 | # Author: Toyo, Modified by APTX 10 | #================================================= 11 | 12 | sh_ver="0.4.1" 13 | filepath=$( 14 | cd "$(dirname "$0")" || exit 15 | pwd 16 | ) 17 | file_1=$(echo -e "${filepath}" | awk -F "$0" '{print $1}') 18 | file="/usr/local/ServerStatus" 19 | web_file="/usr/local/ServerStatus/web" 20 | server_file="/usr/local/ServerStatus/server" 21 | server_conf="/usr/local/ServerStatus/server/config.json" 22 | server_conf_1="/usr/local/ServerStatus/server/config.conf" 23 | client_file="/usr/local/ServerStatus/client" 24 | 25 | client_log_file="/tmp/serverstatus_client.log" 26 | server_log_file="/tmp/serverstatus_server.log" 27 | jq_file="${file}/jq" 28 | [[ ! -e ${jq_file} ]] && jq_file="/usr/bin/jq" 29 | region_json="${file}/region.json" 30 | 31 | github_prefix="https://raw.githubusercontent.com/CokeMine/ServerStatus-Hotaru/master" 32 | coding_prefix="https://cokemine.coding.net/p/hotarunet/d/ServerStatus-Hotaru/git/raw/master" 33 | link_prefix=${github_prefix} 34 | 35 | Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" 36 | Info="${Green_font_prefix}[信息]${Font_color_suffix}" 37 | Error="${Red_font_prefix}[错误]${Font_color_suffix}" 38 | Tip="${Green_font_prefix}[注意]${Font_color_suffix}" 39 | 40 | #检查系统 41 | check_sys() { 42 | if [[ -f /etc/redhat-release ]]; then 43 | release="centos" 44 | elif grep -q -E -i "debian|ubuntu" /etc/issue; then 45 | release="debian" 46 | elif grep -q -E -i "centos|red hat|redhat" /etc/issue; then 47 | release="centos" 48 | elif grep -q -E -i "Arch|Manjaro" /etc/issue; then 49 | release="archlinux" 50 | elif grep -q -E -i "debian|ubuntu" /proc/version; then 51 | release="debian" 52 | elif grep -q -E -i "centos|red hat|redhat" /proc/version; then 53 | release="centos" 54 | else 55 | echo -e "ServerStatus 暂不支持该Linux发行版" 56 | fi 57 | bit=$(uname -m) 58 | } 59 | check_installed_server_status() { 60 | [[ ! -e "${server_file}/sergate" ]] && echo -e "${Error} ServerStatus 服务端没有安装,请检查 !" && exit 1 61 | } 62 | check_installed_client_status() { 63 | [[ ! -e "${client_file}/status-client.py" ]] && echo -e "${Error} ServerStatus 客户端没有安装,请检查 !" && exit 1 64 | } 65 | check_pid_server() { 66 | #PID=$(ps -ef | grep "sergate" | grep -v grep | grep -v ".sh" | grep -v "init.d" | grep -v "service" | awk '{print $2}') 67 | PID=$(pgrep -f "sergate") 68 | } 69 | check_pid_client() { 70 | #PID=$(ps -ef | grep "status-client.py" | grep -v grep | grep -v ".sh" | grep -v "init.d" | grep -v "service" | awk '{print $2}') 71 | PID=$(pgrep -f "status-client.py") 72 | } 73 | check_region() { 74 | # 如果找不到 region 文件, 默认不检测 75 | [[ ! -e "${region_json}" ]] && return 0 76 | if ${jq_file} "[.countries | has(\"${region_s}}\")]" "${region_json}" | grep -q 'true' >/dev/null 2>&1; then 77 | return 0 78 | elif grep -qw "${region_s}" "${region_json}"; then 79 | region_s=$(grep -w "${region_s}" "${region_json}" | sed "s/[[:space:]]//g") 80 | region_s=${region_s:1:2} 81 | return 0 82 | fi 83 | return 1 84 | } 85 | Download_Server_Status_server() { 86 | cd "/tmp" || exit 1 87 | [[ ${mirror_num} == 2 ]] && bundle_link="https://cokemine.coding.net/p/hotarunet/d/ServerStatus-Hotaru/git/archive/master/?download=true" || bundle_link="https://github.com/CokeMine/ServerStatus-Hotaru/archive/master.zip" 88 | [[ ${mirror_num} == 2 ]] && github_link="https://hub.fastgit.org" || github_link="https://github.com" 89 | wget -N --no-check-certificate "${bundle_link}" -O "master.zip" 90 | [[ ! -e "master.zip" ]] && echo -e "${Error} ServerStatus 服务端下载失败 !" && exit 1 91 | unzip master.zip 92 | rm -rf master.zip 93 | [[ -d "/tmp/cokemine-hotarunet-ServerStatus-Hotaru-master" ]] && mv "/tmp/cokemine-hotarunet-ServerStatus-Hotaru-master" "/tmp/ServerStatus-Hotaru-master" 94 | [[ ! -d "/tmp/ServerStatus-Hotaru-master" ]] && echo -e "${Error} ServerStatus 服务端解压失败 !" && exit 1 95 | cd "/tmp/ServerStatus-Hotaru-master/server" || exit 1 96 | make 97 | [[ ! -e "sergate" ]] && echo -e "${Error} ServerStatus 服务端编译失败 !" && cd "${file_1}" && rm -rf "/tmp/ServerStatus-Hotaru-master" && exit 1 98 | cd "${file_1}" || exit 1 99 | mkdir -p "${server_file}" 100 | if [[ -e "${server_file}/sergate" ]]; then 101 | mv "${server_file}/sergate" "${server_file}/sergate1" 102 | mv "/tmp/ServerStatus-Hotaru-master/server/sergate" "${server_file}/sergate" 103 | else 104 | mv "/tmp/ServerStatus-Hotaru-master/server/sergate" "${server_file}/sergate" 105 | wget -N --no-check-certificate "${github_link}/cokemine/hotaru_theme/releases/latest/download/hotaru-theme.zip" 106 | unzip hotaru-theme.zip && mv "./hotaru-theme" "${web_file}" 107 | rm -rf hotaru-theme.zip 108 | fi 109 | rm -rf "/tmp/ServerStatus-Hotaru-master" 110 | if [[ ! -e "${server_file}/sergate" ]]; then 111 | echo -e "${Error} ServerStatus 服务端移动重命名失败 !" 112 | [[ -e "${server_file}/sergate1" ]] && mv "${server_file}/sergate1" "${server_file}/sergate" 113 | exit 1 114 | else 115 | [[ -e "${server_file}/sergate1" ]] && rm -rf "${server_file}/sergate1" 116 | fi 117 | } 118 | Download_Server_Status_client() { 119 | cd "/tmp" || exit 1 120 | wget -N --no-check-certificate "${link_prefix}/clients/status-client.py" 121 | [[ ! -e "status-client.py" ]] && echo -e "${Error} ServerStatus 客户端下载失败 !" && exit 1 122 | cd "${file_1}" || exit 1 123 | mkdir -p "${client_file}" 124 | [[ -e "${client_file}/status-client.py" ]] && mv "${client_file}/status-client.py" "${client_file}/status-client1.py" 125 | mv "/tmp/status-client.py" "${client_file}/status-client.py" 126 | if [[ ! -e "${client_file}/status-client.py" ]]; then 127 | echo -e "${Error} ServerStatus 客户端移动失败 !" 128 | [[ -e "${client_file}/status-client1.py" ]] && mv "${client_file}/status-client1.py" "${client_file}/status-client.py" 129 | rm -rf "/tmp/status-client.py" 130 | exit 1 131 | else 132 | [[ -e "${client_file}/status-client1.py" ]] && rm -rf "${client_file}/status-client1.py" 133 | rm -rf "/tmp/status-client.py" 134 | fi 135 | } 136 | Download_Server_Status_Service() { 137 | mode=$1 138 | [[ -z ${mode} ]] && mode="server" 139 | local service_note="服务端" 140 | [[ ${mode} == "client" ]] && service_note="客户端" 141 | if [[ ${release} == "archlinux" ]]; then 142 | wget --no-check-certificate "${link_prefix}/service/status-${mode}.service" -O "/usr/lib/systemd/system/status-${mode}.service" || 143 | { 144 | echo -e "${Error} ServerStatus ${service_note}服务管理脚本下载失败 !" 145 | exit 1 146 | } 147 | systemctl enable "status-${mode}.service" 148 | else 149 | wget --no-check-certificate "${link_prefix}/service/server_status_${mode}_${release}" -O "/etc/init.d/status-${mode}" || 150 | { 151 | echo -e "${Error} ServerStatus ${service_note}服务管理脚本下载失败 !" 152 | exit 1 153 | } 154 | chmod +x "/etc/init.d/status-${mode}" 155 | [[ ${release} == "centos" ]] && 156 | { 157 | chkconfig --add "status-${mode}" 158 | chkconfig "status-${mode}" on 159 | } 160 | 161 | [[ ${release} == "debian" ]] && update-rc.d -f "status-${mode}" defaults 162 | fi 163 | echo -e "${Info} ServerStatus ${service_note}服务管理脚本下载完成 !" 164 | } 165 | Service_Server_Status_server() { 166 | Download_Server_Status_Service "server" 167 | } 168 | Service_Server_Status_client() { 169 | Download_Server_Status_Service "client" 170 | } 171 | Installation_dependency() { 172 | mode=$1 173 | if [[ ${release} == "centos" ]]; then 174 | yum -y update 175 | yum -y install unzip 176 | yum -y install python3 >/dev/null 2>&1 || yum -y install python 177 | [[ ${mode} == "server" ]] && yum -y groupinstall "Development Tools" 178 | elif [[ ${release} == "debian" ]]; then 179 | apt -y update 180 | apt -y install unzip 181 | apt -y install python3 >/dev/null 2>&1 || apt -y install python 182 | [[ ${mode} == "server" ]] && apt -y install build-essential 183 | elif [[ ${release} == "archlinux" ]]; then 184 | pacman -Sy python python-pip unzip --noconfirm 185 | [[ ${mode} == "server" ]] && pacman -Sy base-devel --noconfirm 186 | fi 187 | [[ ! -e /usr/bin/python ]] && ln -s /usr/bin/python3 /usr/bin/python 188 | } 189 | Write_server_config() { 190 | cat >${server_conf} <<-EOF 191 | {"servers": 192 | [ 193 | { 194 | "username": "username01", 195 | "password": "password", 196 | "name": "Server 01", 197 | "type": "KVM", 198 | "host": "", 199 | "location": "Hong Kong", 200 | "disabled": false, 201 | "region": "HK" 202 | } 203 | ] 204 | } 205 | EOF 206 | } 207 | Write_server_config_conf() { 208 | cat >${server_conf_1} <<-EOF 209 | PORT = ${server_port_s} 210 | EOF 211 | } 212 | Read_config_client() { 213 | client_text="$(sed 's/\"//g;s/,//g;s/ //g' "${client_file}/status-client.py") " 214 | client_server="$(echo -e "${client_text}" | grep "SERVER=" | awk -F "=" '{print $2}')" 215 | client_port="$(echo -e "${client_text}" | grep "PORT=" | awk -F "=" '{print $2}')" 216 | client_user="$(echo -e "${client_text}" | grep "USER=" | awk -F "=" '{print $2}')" 217 | client_password="$(echo -e "${client_text}" | grep "PASSWORD=" | awk -F "=" '{print $2}')" 218 | grep -q "NET_IN, NET_OUT = get_traffic_vnstat()" "${client_file}/status-client.py" && client_vnstat="true" || client_vnstat="false" 219 | } 220 | Read_config_server() { 221 | if [[ ! -e "${server_conf_1}" ]]; then 222 | server_port_s="35601" 223 | Write_server_config_conf 224 | server_port="35601" 225 | else 226 | server_port="$(grep "PORT = " ${server_conf_1} | awk '{print $3}')" 227 | fi 228 | } 229 | Set_server() { 230 | mode=$1 231 | [[ -z ${mode} ]] && mode="server" 232 | if [[ ${mode} == "server" ]]; then 233 | echo -e "请输入 ServerStatus 服务端中网站要设置的 域名[server] 234 | 默认为本机IP为域名,例如输入: toyoo.pw ,如果要使用本机IP,请留空直接回车" 235 | read -erp "(默认: 本机IP):" server_s 236 | [[ -z "$server_s" ]] && server_s="" 237 | else 238 | echo -e "请输入 ServerStatus 服务端的 IP/域名[server],请注意,如果你的域名使用了CDN,请直接填写IP" 239 | read -erp "(默认: 127.0.0.1):" server_s 240 | [[ -z "$server_s" ]] && server_s="127.0.0.1" 241 | fi 242 | 243 | echo && echo " ================================================" 244 | echo -e " IP/域名[server]: ${Red_background_prefix} ${server_s} ${Font_color_suffix}" 245 | echo " ================================================" && echo 246 | } 247 | Set_server_http_port() { 248 | while true; do 249 | echo -e "请输入 ServerStatus 服务端中网站要设置的 域名/IP的端口[1-65535](如果是域名的话,一般用 80 端口)" 250 | read -erp "(默认: 8888):" server_http_port_s 251 | [[ -z "$server_http_port_s" ]] && server_http_port_s="8888" 252 | if [[ "$server_http_port_s" =~ ^[0-9]*$ ]]; then 253 | if [[ ${server_http_port_s} -ge 1 ]] && [[ ${server_http_port_s} -le 65535 ]]; then 254 | echo && echo " ================================================" 255 | echo -e " 端口: ${Red_background_prefix} ${server_http_port_s} ${Font_color_suffix}" 256 | echo " ================================================" && echo 257 | break 258 | else 259 | echo "输入错误, 请输入正确的端口。" 260 | fi 261 | else 262 | echo "输入错误, 请输入正确的端口。" 263 | fi 264 | done 265 | } 266 | Set_server_port() { 267 | while true; do 268 | echo -e "请输入 ServerStatus 服务端监听的端口[1-65535](用于服务端接收客户端消息的端口,客户端要填写这个端口)" 269 | read -erp "(默认: 35601):" server_port_s 270 | [[ -z "$server_port_s" ]] && server_port_s="35601" 271 | if [[ "$server_port_s" =~ ^[0-9]*$ ]]; then 272 | if [[ ${server_port_s} -ge 1 ]] && [[ ${server_port_s} -le 65535 ]]; then 273 | echo && echo " ================================================" 274 | echo -e " 端口: ${Red_background_prefix} ${server_port_s} ${Font_color_suffix}" 275 | echo " ================================================" && echo 276 | break 277 | else 278 | echo "输入错误, 请输入正确的端口。" 279 | fi 280 | else 281 | echo "输入错误, 请输入正确的端口。" 282 | fi 283 | done 284 | } 285 | Set_username() { 286 | mode=$1 287 | [[ -z ${mode} ]] && mode="server" 288 | if [[ ${mode} == "server" ]]; then 289 | echo -e "请输入 ServerStatus 服务端要设置的用户名[username](字母/数字,不可与其他账号重复)" 290 | else 291 | echo -e "请输入 ServerStatus 服务端中对应配置的用户名[username](字母/数字,不可与其他账号重复)" 292 | fi 293 | read -erp "(默认: 取消):" username_s 294 | [[ -z "$username_s" ]] && echo "已取消..." && exit 0 295 | echo && echo " ================================================" 296 | echo -e " 账号[username]: ${Red_background_prefix} ${username_s} ${Font_color_suffix}" 297 | echo " ================================================" && echo 298 | } 299 | Set_password() { 300 | mode=$1 301 | [[ -z ${mode} ]] && mode="server" 302 | if [[ ${mode} == "server" ]]; then 303 | echo -e "请输入 ServerStatus 服务端要设置的密码[password](字母/数字,可重复)" 304 | else 305 | echo -e "请输入 ServerStatus 服务端中对应配置的密码[password](字母/数字)" 306 | fi 307 | read -erp "(默认: doub.io):" password_s 308 | [[ -z "$password_s" ]] && password_s="doub.io" 309 | echo && echo " ================================================" 310 | echo -e " 密码[password]: ${Red_background_prefix} ${password_s} ${Font_color_suffix}" 311 | echo " ================================================" && echo 312 | } 313 | Set_vnstat() { 314 | echo -e "对于流量计算是否使用Vnstat每月自动清零? [y/N]" 315 | read -erp "(默认: N):" isVnstat 316 | [[ -z "$isVnstat" ]] && isVnstat="n" 317 | } 318 | Set_name() { 319 | echo -e "请输入 ServerStatus 服务端要设置的节点名称[name](支持中文,前提是你的系统和SSH工具支持中文输入,仅仅是个名字)" 320 | read -erp "(默认: Server 01):" name_s 321 | [[ -z "$name_s" ]] && name_s="Server 01" 322 | echo && echo " ================================================" 323 | echo -e " 节点名称[name]: ${Red_background_prefix} ${name_s} ${Font_color_suffix}" 324 | echo " ================================================" && echo 325 | } 326 | Set_type() { 327 | echo -e "请输入 ServerStatus 服务端要设置的节点虚拟化类型[type](例如 OpenVZ / KVM)" 328 | read -erp "(默认: KVM):" type_s 329 | [[ -z "$type_s" ]] && type_s="KVM" 330 | echo && echo " ================================================" 331 | echo -e " 虚拟化类型[type]: ${Red_background_prefix} ${type_s} ${Font_color_suffix}" 332 | echo " ================================================" && echo 333 | } 334 | Set_location() { 335 | echo -e "请输入 ServerStatus 服务端要设置的节点位置[location](支持中文,前提是你的系统和SSH工具支持中文输入)" 336 | read -erp "(默认: Hong Kong):" location_s 337 | [[ -z "$location_s" ]] && location_s="Hong Kong" 338 | echo && echo " ================================================" 339 | echo -e " 节点位置[location]: ${Red_background_prefix} ${location_s} ${Font_color_suffix}" 340 | echo " ================================================" && echo 341 | } 342 | Set_region() { 343 | echo -e "请输入 ServerStatus 服务端要设置的节点地区[region](用于国家/地区的旗帜图标显示)" 344 | read -erp "(默认: HK):" region_s 345 | [[ -z "$region_s" ]] && region_s="HK" 346 | while ! check_region; do 347 | read -erp "你输入的节点地区不合法,请重新输入:" region_s 348 | done 349 | echo && echo " ================================================" 350 | echo -e " 节点地区[region]: ${Red_background_prefix} ${region_s} ${Font_color_suffix}" 351 | echo " ================================================" && echo 352 | } 353 | Set_config_server() { 354 | Set_username "server" 355 | Set_password "server" 356 | Set_name 357 | Set_type 358 | Set_location 359 | Set_region 360 | } 361 | Set_config_client() { 362 | Set_server "client" 363 | Set_server_port 364 | Set_username "client" 365 | Set_password "client" 366 | Set_vnstat 367 | } 368 | Set_ServerStatus_server() { 369 | check_installed_server_status 370 | echo && echo -e " 你要做什么? 371 | 372 | ${Green_font_prefix} 1.${Font_color_suffix} 添加 节点配置 373 | ${Green_font_prefix} 2.${Font_color_suffix} 删除 节点配置 374 | ———————— 375 | ${Green_font_prefix} 3.${Font_color_suffix} 修改 节点配置 - 节点用户名 376 | ${Green_font_prefix} 4.${Font_color_suffix} 修改 节点配置 - 节点密码 377 | ${Green_font_prefix} 5.${Font_color_suffix} 修改 节点配置 - 节点名称 378 | ${Green_font_prefix} 6.${Font_color_suffix} 修改 节点配置 - 节点虚拟化 379 | ${Green_font_prefix} 7.${Font_color_suffix} 修改 节点配置 - 节点位置 380 | ${Green_font_prefix} 8.${Font_color_suffix} 修改 节点配置 - 节点区域 381 | ${Green_font_prefix} 9.${Font_color_suffix} 修改 节点配置 - 全部参数 382 | ———————— 383 | ${Green_font_prefix} 10.${Font_color_suffix} 启用/禁用 节点配置 384 | ———————— 385 | ${Green_font_prefix}11.${Font_color_suffix} 修改 服务端监听端口" && echo 386 | read -erp "(默认: 取消):" server_num 387 | [[ -z "${server_num}" ]] && echo "已取消..." && exit 1 388 | if [[ ${server_num} == "1" ]]; then 389 | Add_ServerStatus_server 390 | elif [[ ${server_num} == "2" ]]; then 391 | Del_ServerStatus_server 392 | elif [[ ${server_num} == "3" ]]; then 393 | Modify_ServerStatus_server_username 394 | elif [[ ${server_num} == "4" ]]; then 395 | Modify_ServerStatus_server_password 396 | elif [[ ${server_num} == "5" ]]; then 397 | Modify_ServerStatus_server_name 398 | elif [[ ${server_num} == "6" ]]; then 399 | Modify_ServerStatus_server_type 400 | elif [[ ${server_num} == "7" ]]; then 401 | Modify_ServerStatus_server_location 402 | elif [[ ${server_num} == "8" ]]; then 403 | Modify_ServerStatus_server_region 404 | elif [[ ${server_num} == "9" ]]; then 405 | Modify_ServerStatus_server_all 406 | elif [[ ${server_num} == "10" ]]; then 407 | Modify_ServerStatus_server_disabled 408 | elif [[ ${server_num} == "11" ]]; then 409 | Read_config_server 410 | Set_server_port 411 | Write_server_config_conf 412 | else 413 | echo -e "${Error} 请输入正确的数字[1-11]" && exit 1 414 | fi 415 | Restart_ServerStatus_server 416 | } 417 | List_ServerStatus_server() { 418 | conf_text=$(${jq_file} '.servers' ${server_conf} | ${jq_file} ".[]|.username" | sed 's/\"//g') 419 | conf_text_total=$(echo -e "${conf_text}" | wc -l) 420 | [[ ${conf_text_total} == "0" ]] && echo -e "${Error} 没有发现 一个节点配置,请检查 !" && exit 1 421 | conf_text_total_a=$((conf_text_total - 1)) 422 | conf_list_all="" 423 | for ((integer = 0; integer <= conf_text_total_a; integer++)); do 424 | now_text=$(${jq_file} '.servers' ${server_conf} | ${jq_file} ".[${integer}]" | sed 's/\"//g;s/,$//g' | sed '$d;1d') 425 | now_text_username=$(echo -e "${now_text}" | grep "username" | awk -F ": " '{print $2}') 426 | now_text_password=$(echo -e "${now_text}" | grep "password" | awk -F ": " '{print $2}') 427 | now_text_name=$(echo -e "${now_text}" | grep "name" | grep -v "username" | awk -F ": " '{print $2}') 428 | now_text_type=$(echo -e "${now_text}" | grep "type" | awk -F ": " '{print $2}') 429 | now_text_location=$(echo -e "${now_text}" | grep "location" | awk -F ": " '{print $2}') 430 | now_text_region=$(echo -e "${now_text}" | grep "region" | awk -F ": " '{print $2}') 431 | now_text_disabled=$(echo -e "${now_text}" | grep "disabled" | awk -F ": " '{print $2}') 432 | if [[ ${now_text_disabled} == "false" ]]; then 433 | now_text_disabled_status="${Green_font_prefix}启用${Font_color_suffix}" 434 | else 435 | now_text_disabled_status="${Red_font_prefix}禁用${Font_color_suffix}" 436 | fi 437 | conf_list_all=${conf_list_all}"用户名: ${Green_font_prefix}${now_text_username}${Font_color_suffix} 密码: ${Green_font_prefix}${now_text_password}${Font_color_suffix} 节点名: ${Green_font_prefix}${now_text_name}${Font_color_suffix} 类型: ${Green_font_prefix}${now_text_type}${Font_color_suffix} 位置: ${Green_font_prefix}${now_text_location}${Font_color_suffix} 区域: ${Green_font_prefix}${now_text_region}${Font_color_suffix} 状态: ${Green_font_prefix}${now_text_disabled_status}${Font_color_suffix}\n" 438 | done 439 | echo && echo -e "节点总数 ${Green_font_prefix}${conf_text_total}${Font_color_suffix}" 440 | echo -e "${conf_list_all}" 441 | } 442 | Add_ServerStatus_server() { 443 | Set_config_server 444 | Set_username_ch=$(grep '"username": "'"${username_s}"'"' ${server_conf}) 445 | [[ -n "${Set_username_ch}" ]] && echo -e "${Error} 用户名已被使用 !" && exit 1 446 | sed -i '3i\ },' ${server_conf} 447 | sed -i '3i\ "region": "'"${region_s}"'"' ${server_conf} 448 | sed -i '3i\ "disabled": false ,' ${server_conf} 449 | sed -i '3i\ "location": "'"${location_s}"'",' ${server_conf} 450 | sed -i '3i\ "host": "'"None"'",' ${server_conf} 451 | sed -i '3i\ "type": "'"${type_s}"'",' ${server_conf} 452 | sed -i '3i\ "name": "'"${name_s}"'",' ${server_conf} 453 | sed -i '3i\ "password": "'"${password_s}"'",' ${server_conf} 454 | sed -i '3i\ "username": "'"${username_s}"'",' ${server_conf} 455 | sed -i '3i\ {' ${server_conf} 456 | echo -e "${Info} 添加节点成功 ${Green_font_prefix}[ 节点名称: ${name_s}, 节点用户名: ${username_s}, 节点密码: ${password_s} ]${Font_color_suffix} !" 457 | } 458 | Del_ServerStatus_server() { 459 | List_ServerStatus_server 460 | [[ "${conf_text_total}" == "1" ]] && echo -e "${Error} 节点配置仅剩 1个,不能删除 !" && exit 1 461 | echo -e "请输入要删除的节点用户名" 462 | read -erp "(默认: 取消):" del_server_username 463 | [[ -z "${del_server_username}" ]] && echo -e "已取消..." && exit 1 464 | del_username=$(cat -n ${server_conf} | grep '"username": "'"${del_server_username}"'"' | awk '{print $1}') 465 | if [[ -n ${del_username} ]]; then 466 | del_username_min=$((del_username - 1)) 467 | del_username_max=$((del_username + 8)) 468 | del_username_max_text=$(sed -n "${del_username_max}p" ${server_conf}) 469 | del_username_max_text_last=${del_username_max_text:((${#del_username_max_text} - 1))} 470 | if [[ ${del_username_max_text_last} != "," ]]; then 471 | del_list_num=$((del_username_min - 1)) 472 | sed -i "${del_list_num}s/,$//g" ${server_conf} 473 | fi 474 | sed -i "${del_username_min},${del_username_max}d" ${server_conf} 475 | echo -e "${Info} 节点删除成功 ${Green_font_prefix}[ 节点用户名: ${del_server_username} ]${Font_color_suffix} " 476 | else 477 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 478 | fi 479 | } 480 | Modify_ServerStatus_server_username() { 481 | List_ServerStatus_server 482 | echo -e "请输入要修改的节点用户名" 483 | read -erp "(默认: 取消):" manually_username 484 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 485 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 486 | if [[ -n ${Set_username_num} ]]; then 487 | Set_username 488 | Set_username_ch=$(grep '"username": "'"${username_s}"'"' ${server_conf}) 489 | [[ -n "${Set_username_ch}" ]] && echo -e "${Error} 用户名已被使用 !" && exit 1 490 | sed -i "${Set_username_num}"'s/"username": "'"${manually_username}"'"/"username": "'"${username_s}"'"/g' ${server_conf} 491 | echo -e "${Info} 修改成功 [ 原节点用户名: ${manually_username}, 新节点用户名: ${username_s} ]" 492 | else 493 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 494 | fi 495 | } 496 | Modify_ServerStatus_server_password() { 497 | List_ServerStatus_server 498 | echo -e "请输入要修改的节点用户名" 499 | read -erp "(默认: 取消):" manually_username 500 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 501 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 502 | if [[ -n ${Set_username_num} ]]; then 503 | Set_password 504 | Set_password_num_a=$((Set_username_num + 1)) 505 | Set_password_num_text=$(sed -n "${Set_password_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 506 | sed -i "${Set_password_num_a}"'s/"password": "'"${Set_password_num_text}"'"/"password": "'"${password_s}"'"/g' ${server_conf} 507 | echo -e "${Info} 修改成功 [ 原节点密码: ${Set_password_num_text}, 新节点密码: ${password_s} ]" 508 | else 509 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 510 | fi 511 | } 512 | Modify_ServerStatus_server_name() { 513 | List_ServerStatus_server 514 | echo -e "请输入要修改的节点用户名" 515 | read -erp "(默认: 取消):" manually_username 516 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 517 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 518 | if [[ -n ${Set_username_num} ]]; then 519 | Set_name 520 | Set_name_num_a=$((Set_username_num + 2)) 521 | Set_name_num_a_text=$(sed -n "${Set_name_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 522 | sed -i "${Set_name_num_a}"'s/"name": "'"${Set_name_num_a_text}"'"/"name": "'"${name_s}"'"/g' ${server_conf} 523 | echo -e "${Info} 修改成功 [ 原节点名称: ${Set_name_num_a_text}, 新节点名称: ${name_s} ]" 524 | else 525 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 526 | fi 527 | } 528 | Modify_ServerStatus_server_type() { 529 | List_ServerStatus_server 530 | echo -e "请输入要修改的节点用户名" 531 | read -erp "(默认: 取消):" manually_username 532 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 533 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 534 | if [[ -n ${Set_username_num} ]]; then 535 | Set_type 536 | Set_type_num_a=$((Set_username_num + 3)) 537 | Set_type_num_a_text=$(sed -n "${Set_type_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 538 | sed -i "${Set_type_num_a}"'s/"type": "'"${Set_type_num_a_text}"'"/"type": "'"${type_s}"'"/g' ${server_conf} 539 | echo -e "${Info} 修改成功 [ 原节点虚拟化: ${Set_type_num_a_text}, 新节点虚拟化: ${type_s} ]" 540 | else 541 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 542 | fi 543 | } 544 | Modify_ServerStatus_server_location() { 545 | List_ServerStatus_server 546 | echo -e "请输入要修改的节点用户名" 547 | read -erp "(默认: 取消):" manually_username 548 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 549 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 550 | if [[ -n ${Set_username_num} ]]; then 551 | Set_location 552 | Set_location_num_a=$((Set_username_num + 5)) 553 | Set_location_num_a_text=$(sed -n "${Set_location_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 554 | sed -i "${Set_location_num_a}"'s/"location": "'"${Set_location_num_a_text}"'"/"location": "'"${location_s}"'"/g' ${server_conf} 555 | echo -e "${Info} 修改成功 [ 原节点位置: ${Set_location_num_a_text}, 新节点位置: ${location_s} ]" 556 | else 557 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 558 | fi 559 | } 560 | Modify_ServerStatus_server_region() { 561 | List_ServerStatus_server 562 | echo -e "请输入要修改的节点用户名" 563 | read -erp "(默认: 取消):" manually_username 564 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 565 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 566 | if [[ -n ${Set_username_num} ]]; then 567 | Set_region 568 | Set_region_num_a=$((Set_username_num + 7)) 569 | Set_region_num_a_text=$(sed -n "${Set_region_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 570 | sed -i "${Set_region_num_a}"'s/"region": "'"${Set_region_num_a_text}"'"/"region": "'"${region_s}"'"/g' ${server_conf} 571 | echo -e "${Info} 修改成功 [ 原节点地区: ${Set_region_num_a_text}, 新节点地区: ${region_s} ]" 572 | else 573 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 574 | fi 575 | } 576 | Modify_ServerStatus_server_all() { 577 | List_ServerStatus_server 578 | echo -e "请输入要修改的节点用户名" 579 | read -erp "(默认: 取消):" manually_username 580 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 581 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 582 | if [[ -n ${Set_username_num} ]]; then 583 | Set_username 584 | Set_password 585 | Set_name 586 | Set_type 587 | Set_location 588 | Set_region 589 | sed -i "${Set_username_num}"'s/"username": "'"${manually_username}"'"/"username": "'"${username_s}"'"/g' ${server_conf} 590 | Set_password_num_a=$((Set_username_num + 1)) 591 | Set_password_num_text=$(sed -n "${Set_password_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 592 | sed -i "${Set_password_num_a}"'s/"password": "'"${Set_password_num_text}"'"/"password": "'"${password_s}"'"/g' ${server_conf} 593 | Set_name_num_a=$((Set_username_num + 2)) 594 | Set_name_num_a_text=$(sed -n "${Set_name_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 595 | sed -i "${Set_name_num_a}"'s/"name": "'"${Set_name_num_a_text}"'"/"name": "'"${name_s}"'"/g' ${server_conf} 596 | Set_type_num_a=$((Set_username_num + 3)) 597 | Set_type_num_a_text=$(sed -n "${Set_type_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 598 | sed -i "${Set_type_num_a}"'s/"type": "'"${Set_type_num_a_text}"'"/"type": "'"${type_s}"'"/g' ${server_conf} 599 | Set_location_num_a=$((Set_username_num + 5)) 600 | Set_location_num_a_text=$(sed -n "${Set_location_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 601 | sed -i "${Set_location_num_a}"'s/"location": "'"${Set_location_num_a_text}"'"/"location": "'"${location_s}"'"/g' ${server_conf} 602 | Set_region_num_a=$((Set_username_num + 7)) 603 | Set_region_num_a_text=$(sed -n "${Set_region_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 604 | sed -i "${Set_region_num_a}"'s/"region": "'"${Set_region_num_a_text}"'"/"region": "'"${region_s}"'"/g' ${server_conf} 605 | echo -e "${Info} 修改成功。" 606 | else 607 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 608 | fi 609 | } 610 | Modify_ServerStatus_server_disabled() { 611 | List_ServerStatus_server 612 | echo -e "请输入要修改的节点用户名" 613 | read -erp "(默认: 取消):" manually_username 614 | [[ -z "${manually_username}" ]] && echo -e "已取消..." && exit 1 615 | Set_username_num=$(cat -n ${server_conf} | grep '"username": "'"${manually_username}"'"' | awk '{print $1}') 616 | if [[ -n ${Set_username_num} ]]; then 617 | Set_disabled_num_a=$((Set_username_num + 6)) 618 | Set_disabled_num_a_text=$(sed -n "${Set_disabled_num_a}p" ${server_conf} | sed 's/\"//g;s/,$//g' | awk -F ": " '{print $2}') 619 | if [[ ${Set_disabled_num_a_text} == "false" ]]; then 620 | disabled_s="true" 621 | else 622 | disabled_s="false" 623 | fi 624 | sed -i "${Set_disabled_num_a}"'s/"disabled": '"${Set_disabled_num_a_text}"'/"disabled": '"${disabled_s}"'/g' ${server_conf} 625 | echo -e "${Info} 修改成功 [ 原禁用状态: ${Set_disabled_num_a_text}, 新禁用状态: ${disabled_s} ]" 626 | else 627 | echo -e "${Error} 请输入正确的节点用户名 !" && exit 1 628 | fi 629 | } 630 | Set_ServerStatus_client() { 631 | check_installed_client_status 632 | Set_config_client 633 | Read_config_client 634 | Modify_config_client 635 | Restart_ServerStatus_client 636 | } 637 | Install_vnStat() { 638 | if [[ ${release} == "archlinux" ]]; then 639 | pacman -Sy vnstat --noconfirm 640 | systemctl enable vnstat 641 | systemctl start vnstat 642 | return 0 643 | elif [[ ${release} == "centos" ]]; then 644 | yum -y update 645 | yum -y install sqlite sqlite-devel 646 | yum -y groupinstall "Development Tools" 647 | elif [[ ${release} == "debian" ]]; then 648 | apt -y update 649 | apt -y install sqlite3 libsqlite3-dev build-essential 650 | fi 651 | cd "/tmp" || return 1 652 | wget --no-check-certificate https://humdi.net/vnstat/vnstat-latest.tar.gz 653 | tar zxvf vnstat-latest.tar.gz 654 | cd vnstat-*/ || return 1 655 | ./configure --prefix=/usr --sysconfdir=/etc && make && make install 656 | if ! vnstat -v >/dev/null 2>&1; then 657 | echo "编译安装vnStat失败,请手动安装vnStat" 658 | exit 1 659 | fi 660 | vnstatd -d 661 | if [[ ${release} == "centos" ]]; then 662 | if grep "6\..*" /etc/redhat-release | grep -i "centos" | grep -v "{^6}\.6" >/dev/null; then 663 | [[ ! -e /etc/init.d/vnstat ]] && cp examples/init.d/redhat/vnstat /etc/init.d/ 664 | chkconfig vnstat on 665 | service vnstat restart 666 | fi 667 | else 668 | if grep -i "debian" /etc/issue | grep -q "7" || grep -i "ubuntu" /etc/issue | grep -q "14"; then 669 | [[ ! -e /etc/init.d/vnstat ]] && cp examples/init.d/debian/vnstat /etc/init.d/ 670 | update-rc.d vnstat defaults 671 | service vnstat restart 672 | fi 673 | fi 674 | if [[ ! -e /etc/init.d/vnstat ]]; then 675 | cp -v examples/systemd/simple/vnstat.service /etc/systemd/system/ 676 | systemctl enable vnstat 677 | systemctl start vnstat 678 | fi 679 | rm -rf vnstat* 680 | cd ~ || exit 681 | } 682 | Modify_config_client_traffic() { 683 | [ -z ${isVnstat} ] && [[ ${client_vnstat_s} == "false" ]] && return 684 | if [[ ${isVnstat="y"} == [Yy] ]]; then 685 | vnstat -v >/dev/null 2>&1 || Install_vnStat 686 | netName=$(awk '{i++; if( i>2 && ($2 != 0 && $10 != 0) ){print $1}}' /proc/net/dev | sed 's/^lo:$//g' | sed 's/^tun:$//g' | sed '/^$/d' | sed 's/^[\t]*//g' | sed 's/[:]*$//g') 687 | if [ -z "$netName" ]; then 688 | echo -e "获取网卡名称失败,请在Github反馈" 689 | exit 1 690 | fi 691 | if [[ $netName =~ [[:space:]] ]]; then 692 | read -erp "检测到多个网卡: ${netName},请手动输入网卡名称" netName 693 | fi 694 | read -erp "请输入每月流量归零的日期(1~28),默认为1(即每月1日): " time_N 695 | [[ -z "$time_N" ]] && time_N="1" 696 | while ! [[ $time_N =~ ^[0-9]*$ ]] || ((time_N < 1 || time_N > 28)); do 697 | read -erp "你输入的日期不合法,请重新输入: " time_N 698 | done 699 | sed -i "s/$(grep -w "MonthRotate" /etc/vnstat.conf)/MonthRotate $time_N/" /etc/vnstat.conf 700 | sed -i "s/$(grep -w "Interface" /etc/vnstat.conf)/Interface \"$netName\"/" /etc/vnstat.conf 701 | chmod -R 777 /var/lib/vnstat/ 702 | systemctl restart vnstat 703 | if ! grep -q "NET_IN, NET_OUT = get_traffic_vnstat()" ${client_file}/status-client.py; then 704 | sed -i 's/\t/ /g' ${client_file}/status-client.py 705 | sed -i 's/NET_IN, NET_OUT = traffic.get_traffic()/NET_IN, NET_OUT = get_traffic_vnstat()/' ${client_file}/status-client.py 706 | fi 707 | elif grep -q "NET_IN, NET_OUT = get_traffic_vnstat()" ${client_file}/status-client.py; then 708 | sed -i 's/\t/ /g' ${client_file}/status-client.py 709 | sed -i 's/NET_IN, NET_OUT = get_traffic_vnstat()/NET_IN, NET_OUT = traffic.get_traffic()/' ${client_file}/status-client.py 710 | fi 711 | } 712 | Modify_config_client() { 713 | sed -i 's/SERVER = "'"${client_server}"'"/SERVER = "'"${server_s}"'"/g' "${client_file}/status-client.py" 714 | sed -i "s/PORT = ${client_port}/PORT = ${server_port_s}/g" "${client_file}/status-client.py" 715 | sed -i 's/USER = "'"${client_user}"'"/USER = "'"${username_s}"'"/g' "${client_file}/status-client.py" 716 | sed -i 's/PASSWORD = "'"${client_password}"'"/PASSWORD = "'"${password_s}"'"/g' "${client_file}/status-client.py" 717 | Modify_config_client_traffic 718 | } 719 | Install_jq() { 720 | [[ ${mirror_num} == 2 ]] && { 721 | github_link="https://hub.fastgit.org" 722 | raw_link="https://raw.fastgit.org" 723 | } || { 724 | github_link="https://github.com" 725 | raw_link="https://raw.githubusercontent.com" 726 | } 727 | if [[ ! -e ${jq_file} ]]; then 728 | if [[ ${bit} == "x86_64" ]]; then 729 | jq_file="${file}/jq" 730 | wget --no-check-certificate "${github_link}/stedolan/jq/releases/download/jq-1.5/jq-linux64" -O ${jq_file} 731 | elif [[ ${bit} == "i386" ]]; then 732 | jq_file="${file}/jq" 733 | wget --no-check-certificate "${github_link}/stedolan/jq/releases/download/jq-1.5/jq-linux32" -O ${jq_file} 734 | else 735 | # ARM fallback to package manager 736 | [[ ${release} == "archlinux" ]] && pacman -Sy jq --noconfirm 737 | [[ ${release} == "centos" ]] && yum -y install jq 738 | [[ ${release} == "debian" ]] && apt -y install jq 739 | jq_file="/usr/bin/jq" 740 | fi 741 | [[ ! -e ${jq_file} ]] && echo -e "${Error} JQ解析器 下载失败,请检查 !" && exit 1 742 | chmod +x ${jq_file} 743 | echo -e "${Info} JQ解析器 安装完成,继续..." 744 | else 745 | echo -e "${Info} JQ解析器 已安装,继续..." 746 | fi 747 | if [[ ! -e ${region_json} ]]; then 748 | wget --no-check-certificate "${raw_link}/michaelwittig/node-i18n-iso-countries/master/langs/zh.json" -O ${region_json} 749 | [[ ! -e ${region_json} ]] && echo -e "${Error} ISO 3166-1 json文件下载失败,请检查!" && exit 1 750 | fi 751 | } 752 | Install_caddy() { 753 | echo 754 | echo -e "${Info} 是否由脚本自动配置HTTP服务(服务端的在线监控网站),如果选择 N,则请在其他HTTP服务中配置网站根目录为:${Green_font_prefix}${web_file}${Font_color_suffix} [Y/n]" 755 | read -erp "(默认: Y 自动部署):" caddy_yn 756 | [[ -z "$caddy_yn" ]] && caddy_yn="y" 757 | if [[ "${caddy_yn}" == [Yy] ]]; then 758 | caddy_file="/etc/caddy/Caddyfile" # Where is the default Caddyfile specified in Archlinux? 759 | [[ ! -e /usr/bin/caddy ]] && { 760 | if [[ ${release} == "debian" ]]; then 761 | apt install -y debian-keyring debian-archive-keyring apt-transport-https curl 762 | curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/gpg.key" | tee /etc/apt/trusted.gpg.d/caddy-stable.asc 763 | curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt" | tee /etc/apt/sources.list.d/caddy-stable.list 764 | apt update && apt install caddy 765 | elif [[ ${release} == "centos" ]]; then 766 | yum install yum-plugin-copr -y 767 | yum copr enable @caddy/caddy -y 768 | yum install caddy -y 769 | elif [[ ${release} == "archlinux" ]]; then 770 | pacman -Sy caddy --noconfirm 771 | fi 772 | [[ ! -e "/usr/bin/caddy" ]] && echo -e "${Error} Caddy安装失败,请手动部署,Web网页文件位置:${web_file}" && exit 1 773 | systemctl enable caddy 774 | echo "" >${caddy_file} 775 | } 776 | Set_server "server" 777 | Set_server_http_port 778 | cat >>${caddy_file} <<-EOF 779 | http://${server_s}:${server_http_port_s} { 780 | root * ${web_file} 781 | encode gzip 782 | file_server 783 | } 784 | EOF 785 | systemctl restart caddy 786 | else 787 | echo -e "${Info} 跳过 HTTP服务部署,请手动部署,Web网页文件位置:${web_file} ,如果位置改变,请注意修改服务脚本文件 /etc/init.d/status-server 中的 WEB_BIN 变量 !" 788 | fi 789 | } 790 | Install_ServerStatus_server() { 791 | Set_Mirror 792 | [[ -e "${server_file}/sergate" ]] && echo -e "${Error} 检测到 ServerStatus 服务端已安装 !" && exit 1 793 | Set_server_port 794 | echo -e "${Info} 开始安装/配置 依赖..." 795 | Installation_dependency "server" 796 | Install_caddy 797 | echo -e "${Info} 开始下载/安装..." 798 | Download_Server_Status_server 799 | Install_jq 800 | echo -e "${Info} 开始下载/安装 服务脚本(init)..." 801 | Service_Server_Status_server 802 | echo -e "${Info} 开始写入 配置文件..." 803 | Write_server_config 804 | Write_server_config_conf 805 | echo -e "${Info} 所有步骤 安装完毕,开始启动..." 806 | Start_ServerStatus_server 807 | } 808 | Install_ServerStatus_client() { 809 | Set_Mirror 810 | [[ -e "${client_file}/status-client.py" ]] && echo -e "${Error} 检测到 ServerStatus 客户端已安装 !" && exit 1 811 | check_sys 812 | echo -e "${Info} 开始设置 用户配置..." 813 | Set_config_client 814 | echo -e "${Info} 开始安装/配置 依赖..." 815 | Installation_dependency "client" 816 | echo -e "${Info} 开始下载/安装..." 817 | Download_Server_Status_client 818 | echo -e "${Info} 开始下载/安装 服务脚本(init)..." 819 | Service_Server_Status_client 820 | echo -e "${Info} 开始写入 配置..." 821 | Read_config_client 822 | Modify_config_client 823 | echo -e "${Info} 所有步骤 安装完毕,开始启动..." 824 | Start_ServerStatus_client 825 | } 826 | Update_ServerStatus_server() { 827 | Set_Mirror 828 | check_installed_server_status 829 | check_pid_server 830 | if [[ -n ${PID} ]]; then 831 | if [[ ${release} == "archlinux" ]]; then 832 | systemctl stop status-server 833 | else 834 | /etc/init.d/status-server stop 835 | fi 836 | fi 837 | Download_Server_Status_server 838 | rm -rf /etc/init.d/status-server 839 | Service_Server_Status_server 840 | Start_ServerStatus_server 841 | } 842 | Update_ServerStatus_client() { 843 | Set_Mirror 844 | check_installed_client_status 845 | check_pid_client 846 | if [[ -n ${PID} ]]; then 847 | if [[ ${release} == "archlinux" ]]; then 848 | systemctl stop status-client 849 | else 850 | /etc/init.d/status-client stop 851 | fi 852 | fi 853 | if [[ ! -e "${client_file}/status-client.py" ]]; then 854 | if [[ ! -e "${file}/status-client.py" ]]; then 855 | echo -e "${Error} ServerStatus 客户端文件不存在 !" && exit 1 856 | else 857 | client_text="$(sed 's/\"//g;s/,//g;s/ //g' "${file}/status-client.py")" 858 | rm -rf "${file}/status-client.py" 859 | fi 860 | else 861 | client_text="$(sed 's/\"//g;s/,//g;s/ //g' "${client_file}/status-client.py")" 862 | fi 863 | server_s="$(echo -e "${client_text}" | grep "SERVER=" | awk -F "=" '{print $2}')" 864 | server_port_s="$(echo -e "${client_text}" | grep "PORT=" | awk -F "=" '{print $2}')" 865 | username_s="$(echo -e "${client_text}" | grep "USER=" | awk -F "=" '{print $2}')" 866 | password_s="$(echo -e "${client_text}" | grep "PASSWORD=" | awk -F "=" '{print $2}')" 867 | grep -q "NET_IN, NET_OUT = get_traffic_vnstat()" "${client_file}/status-client.py" && client_vnstat_s="true" || client_vnstat_s="false" 868 | Download_Server_Status_client 869 | Read_config_client 870 | Modify_config_client 871 | rm -rf /etc/init.d/status-client 872 | Service_Server_Status_client 873 | Start_ServerStatus_client 874 | } 875 | Start_ServerStatus_server() { 876 | check_installed_server_status 877 | check_pid_server 878 | [[ -n ${PID} ]] && echo -e "${Error} ServerStatus 正在运行,请检查 !" && exit 1 879 | if [[ ${release} == "archlinux" ]]; then 880 | systemctl start status-server.service 881 | else 882 | /etc/init.d/status-server start 883 | fi 884 | } 885 | Stop_ServerStatus_server() { 886 | check_installed_server_status 887 | check_pid_server 888 | [[ -z ${PID} ]] && echo -e "${Error} ServerStatus 没有运行,请检查 !" && exit 1 889 | if [[ ${release} == "archlinux" ]]; then 890 | systemctl stop status-server.service 891 | else 892 | /etc/init.d/status-server stop 893 | fi 894 | } 895 | Restart_ServerStatus_server() { 896 | check_installed_server_status 897 | check_pid_server 898 | if [[ -n ${PID} ]]; then 899 | if [[ ${release} == "archlinux" ]]; then 900 | systemctl stop status-server.service 901 | else 902 | /etc/init.d/status-server stop 903 | fi 904 | fi 905 | if [[ ${release} == "archlinux" ]]; then 906 | systemctl start status-server.service 907 | else 908 | /etc/init.d/status-server start 909 | fi 910 | } 911 | Uninstall_ServerStatus_server() { 912 | check_installed_server_status 913 | echo "确定要卸载 ServerStatus 服务端(如果同时安装了客户端,则只会删除服务端) ? [y/N]" 914 | echo 915 | read -erp "(默认: n):" unyn 916 | [[ -z ${unyn} ]] && unyn="n" 917 | if [[ ${unyn} == [Yy] ]]; then 918 | check_pid_server 919 | [[ -n $PID ]] && kill -9 "${PID}" 920 | Read_config_server 921 | if [[ -e "${client_file}/status-client.py" ]]; then 922 | rm -rf "${server_file}" 923 | rm -rf "${web_file}" 924 | else 925 | rm -rf "${file}" 926 | fi 927 | rm -rf "/etc/init.d/status-server" 928 | if [[ -e "/usr/bin/caddy" ]]; then 929 | systemctl stop caddy 930 | systemctl disable caddy 931 | [[ ${release} == "debian" ]] && apt purge -y caddy 932 | [[ ${release} == "centos" ]] && yum -y remove caddy 933 | [[ ${release} == "archlinux" ]] && pacman -R caddy --noconfirm 934 | fi 935 | if [[ ${release} == "centos" ]]; then 936 | chkconfig --del status-server 937 | elif [[ ${release} == "debian" ]]; then 938 | update-rc.d -f status-server remove 939 | elif [[ ${release} == "archlinux" ]]; then 940 | systemctl stop status-server 941 | systemctl disable status-server 942 | rm /usr/lib/systemd/system/status-server.service 943 | fi 944 | echo && echo "ServerStatus 卸载完成 !" && echo 945 | else 946 | echo && echo "卸载已取消..." && echo 947 | fi 948 | } 949 | Start_ServerStatus_client() { 950 | check_installed_client_status 951 | check_pid_client 952 | [[ -n ${PID} ]] && echo -e "${Error} ServerStatus 正在运行,请检查 !" && exit 1 953 | if [[ ${release} == "archlinux" ]]; then 954 | systemctl start status-client.service 955 | else 956 | /etc/init.d/status-client start 957 | fi 958 | } 959 | Stop_ServerStatus_client() { 960 | check_installed_client_status 961 | check_pid_client 962 | [[ -z ${PID} ]] && echo -e "${Error} ServerStatus 没有运行,请检查 !" && exit 1 963 | if [[ ${release} == "archlinux" ]]; then 964 | systemctl stop status-client.service 965 | else 966 | /etc/init.d/status-client stop 967 | fi 968 | } 969 | Restart_ServerStatus_client() { 970 | check_installed_client_status 971 | check_pid_client 972 | if [[ -n ${PID} ]]; then 973 | if [[ ${release} == "archlinux" ]]; then 974 | systemctl restart status-client.service 975 | else 976 | /etc/init.d/status-client restart 977 | fi 978 | fi 979 | } 980 | Uninstall_ServerStatus_client() { 981 | check_installed_client_status 982 | echo "确定要卸载 ServerStatus 客户端(如果同时安装了服务端,则只会删除客户端) ? [y/N]" 983 | echo 984 | read -erp "(默认: n):" unyn 985 | [[ -z ${unyn} ]] && unyn="n" 986 | if [[ ${unyn} == [Yy] ]]; then 987 | check_pid_client 988 | [[ -n $PID ]] && kill -9 "${PID}" 989 | Read_config_client 990 | if [[ -e "${server_file}/sergate" ]]; then 991 | rm -rf "${client_file}" 992 | else 993 | rm -rf "${file}" 994 | fi 995 | rm -rf /etc/init.d/status-client 996 | if [[ ${release} == "centos" ]]; then 997 | chkconfig --del status-client 998 | elif [[ ${release} == "debian" ]]; then 999 | update-rc.d -f status-client remove 1000 | elif [[ ${release} == "archlinux" ]]; then 1001 | systemctl stop status-client 1002 | systemctl disable status-client 1003 | rm /usr/lib/systemd/system/status-client.service 1004 | fi 1005 | echo && echo "ServerStatus 卸载完成 !" && echo 1006 | else 1007 | echo && echo "卸载已取消..." && echo 1008 | fi 1009 | } 1010 | View_ServerStatus_client() { 1011 | check_installed_client_status 1012 | Read_config_client 1013 | clear && echo "————————————————————" && echo 1014 | echo -e " ServerStatus 客户端配置信息: 1015 | 1016 | IP \t: ${Green_font_prefix}${client_server}${Font_color_suffix} 1017 | 端口 \t: ${Green_font_prefix}${client_port}${Font_color_suffix} 1018 | 账号 \t: ${Green_font_prefix}${client_user}${Font_color_suffix} 1019 | 密码 \t: ${Green_font_prefix}${client_password}${Font_color_suffix} 1020 | vnStat : ${Green_font_prefix}${client_vnstat}${Font_color_suffix} 1021 | 1022 | ————————————————————" 1023 | } 1024 | View_client_Log() { 1025 | [[ ! -e ${client_log_file} ]] && echo -e "${Error} 没有找到日志文件 !" && exit 1 1026 | echo && echo -e "${Tip} 按 ${Red_font_prefix}Ctrl+C${Font_color_suffix} 终止查看日志" && echo -e "如果需要查看完整日志内容,请用 ${Red_font_prefix}cat ${client_log_file}${Font_color_suffix} 命令。" && echo 1027 | tail -f ${client_log_file} 1028 | } 1029 | View_server_Log() { 1030 | [[ ! -e ${server_log_file} ]] && echo -e "${Error} 没有找到日志文件 !" && exit 1 1031 | echo && echo -e "${Tip} 按 ${Red_font_prefix}Ctrl+C${Font_color_suffix} 终止查看日志" && echo -e "如果需要查看完整日志内容,请用 ${Red_font_prefix}cat ${server_log_file}${Font_color_suffix} 命令。" && echo 1032 | tail -f ${server_log_file} 1033 | } 1034 | Update_Shell() { 1035 | Set_Mirror 1036 | sh_new_ver=$(wget --no-check-certificate -qO- -t1 -T3 "${link_prefix}/status.sh" | grep 'sh_ver="' | awk -F "=" '{print $NF}' | sed 's/\"//g' | head -1) 1037 | [[ -z ${sh_new_ver} ]] && echo -e "${Error} 无法链接到 Github !" && exit 0 1038 | if [[ -e "/etc/init.d/status-client" ]] || [[ -e "/usr/lib/systemd/system/status-client.service" ]]; then 1039 | rm -rf /etc/init.d/status-client 1040 | rm -rf /usr/lib/systemd/system/status-client.service 1041 | Service_Server_Status_client 1042 | fi 1043 | if [[ -e "/etc/init.d/status-server" ]] || [[ -e "/usr/lib/systemd/system/status-server.service" ]]; then 1044 | rm -rf /etc/init.d/status-server 1045 | rm -rf /usr/lib/systemd/system/status-server.service 1046 | Service_Server_Status_server 1047 | fi 1048 | wget -N --no-check-certificate "${link_prefix}/status.sh" && chmod +x status.sh 1049 | echo -e "脚本已更新为最新版本[ ${sh_new_ver} ] !(注意:因为更新方式为直接覆盖当前运行的脚本,所以可能下面会提示一些报错,无视即可)" && exit 0 1050 | } 1051 | menu_client() { 1052 | echo && echo -e " ServerStatus 一键安装管理脚本 ${Red_font_prefix}[v${sh_ver}]${Font_color_suffix} 1053 | -- Toyo | doub.io/shell-jc3 -- 1054 | -- Modified by APTX -- 1055 | ${Green_font_prefix} 0.${Font_color_suffix} 升级脚本 1056 | ———————————— 1057 | ${Green_font_prefix} 1.${Font_color_suffix} 安装 客户端 1058 | ${Green_font_prefix} 2.${Font_color_suffix} 更新 客户端 1059 | ${Green_font_prefix} 3.${Font_color_suffix} 卸载 客户端 1060 | ———————————— 1061 | ${Green_font_prefix} 4.${Font_color_suffix} 启动 客户端 1062 | ${Green_font_prefix} 5.${Font_color_suffix} 停止 客户端 1063 | ${Green_font_prefix} 6.${Font_color_suffix} 重启 客户端 1064 | ———————————— 1065 | ${Green_font_prefix} 7.${Font_color_suffix} 设置 客户端配置 1066 | ${Green_font_prefix} 8.${Font_color_suffix} 查看 客户端信息 1067 | ${Green_font_prefix} 9.${Font_color_suffix} 查看 客户端日志 1068 | ———————————— 1069 | ${Green_font_prefix}10.${Font_color_suffix} 切换为 服务端菜单" && echo 1070 | if [[ -e "${client_file}/status-client.py" ]]; then 1071 | check_pid_client 1072 | if [[ -n "${PID}" ]]; then 1073 | echo -e " 当前状态: 客户端 ${Green_font_prefix}已安装${Font_color_suffix} 并 ${Green_font_prefix}已启动${Font_color_suffix}" 1074 | else 1075 | echo -e " 当前状态: 客户端 ${Green_font_prefix}已安装${Font_color_suffix} 但 ${Red_font_prefix}未启动${Font_color_suffix}" 1076 | fi 1077 | else 1078 | if [[ -e "${file}/status-client.py" ]]; then 1079 | check_pid_client 1080 | if [[ -n "${PID}" ]]; then 1081 | echo -e " 当前状态: 客户端 ${Green_font_prefix}已安装${Font_color_suffix} 并 ${Green_font_prefix}已启动${Font_color_suffix}" 1082 | else 1083 | echo -e " 当前状态: 客户端 ${Green_font_prefix}已安装${Font_color_suffix} 但 ${Red_font_prefix}未启动${Font_color_suffix}" 1084 | fi 1085 | else 1086 | echo -e " 当前状态: 客户端 ${Red_font_prefix}未安装${Font_color_suffix}" 1087 | fi 1088 | fi 1089 | echo 1090 | read -erp " 请输入数字 [0-10]:" num 1091 | case "$num" in 1092 | 0) 1093 | Update_Shell 1094 | ;; 1095 | 1) 1096 | Install_ServerStatus_client 1097 | ;; 1098 | 2) 1099 | Update_ServerStatus_client 1100 | ;; 1101 | 3) 1102 | Uninstall_ServerStatus_client 1103 | ;; 1104 | 4) 1105 | Start_ServerStatus_client 1106 | ;; 1107 | 5) 1108 | Stop_ServerStatus_client 1109 | ;; 1110 | 6) 1111 | Restart_ServerStatus_client 1112 | ;; 1113 | 7) 1114 | Set_ServerStatus_client 1115 | ;; 1116 | 8) 1117 | View_ServerStatus_client 1118 | ;; 1119 | 9) 1120 | View_client_Log 1121 | ;; 1122 | 10) 1123 | menu_server 1124 | ;; 1125 | *) 1126 | echo "请输入正确数字 [0-10]" 1127 | ;; 1128 | esac 1129 | } 1130 | menu_server() { 1131 | echo && echo -e " ServerStatus 一键安装管理脚本 ${Red_font_prefix}[v${sh_ver}]${Font_color_suffix} 1132 | -- Toyo | doub.io/shell-jc3 -- 1133 | -- Modified by APTX -- 1134 | ${Green_font_prefix} 0.${Font_color_suffix} 升级脚本 1135 | ———————————— 1136 | ${Green_font_prefix} 1.${Font_color_suffix} 安装 服务端 1137 | ${Green_font_prefix} 2.${Font_color_suffix} 更新 服务端 1138 | ${Green_font_prefix} 3.${Font_color_suffix} 卸载 服务端 1139 | ———————————— 1140 | ${Green_font_prefix} 4.${Font_color_suffix} 启动 服务端 1141 | ${Green_font_prefix} 5.${Font_color_suffix} 停止 服务端 1142 | ${Green_font_prefix} 6.${Font_color_suffix} 重启 服务端 1143 | ———————————— 1144 | ${Green_font_prefix} 7.${Font_color_suffix} 设置 服务端配置 1145 | ${Green_font_prefix} 8.${Font_color_suffix} 查看 服务端信息 1146 | ${Green_font_prefix} 9.${Font_color_suffix} 查看 服务端日志 1147 | ———————————— 1148 | ${Green_font_prefix}10.${Font_color_suffix} 切换为 客户端菜单" && echo 1149 | if [[ -e "${server_file}/sergate" ]]; then 1150 | check_pid_server 1151 | if [[ -n "${PID}" ]]; then 1152 | echo -e " 当前状态: 服务端 ${Green_font_prefix}已安装${Font_color_suffix} 并 ${Green_font_prefix}已启动${Font_color_suffix}" 1153 | else 1154 | echo -e " 当前状态: 服务端 ${Green_font_prefix}已安装${Font_color_suffix} 但 ${Red_font_prefix}未启动${Font_color_suffix}" 1155 | fi 1156 | else 1157 | echo -e " 当前状态: 服务端 ${Red_font_prefix}未安装${Font_color_suffix}" 1158 | fi 1159 | echo 1160 | read -erp " 请输入数字 [0-10]:" num 1161 | case "$num" in 1162 | 0) 1163 | Update_Shell 1164 | ;; 1165 | 1) 1166 | Install_ServerStatus_server 1167 | ;; 1168 | 2) 1169 | Update_ServerStatus_server 1170 | ;; 1171 | 3) 1172 | Uninstall_ServerStatus_server 1173 | ;; 1174 | 4) 1175 | Start_ServerStatus_server 1176 | ;; 1177 | 5) 1178 | Stop_ServerStatus_server 1179 | ;; 1180 | 6) 1181 | Restart_ServerStatus_server 1182 | ;; 1183 | 7) 1184 | Set_ServerStatus_server 1185 | ;; 1186 | 8) 1187 | List_ServerStatus_server 1188 | ;; 1189 | 9) 1190 | View_server_Log 1191 | ;; 1192 | 10) 1193 | menu_client 1194 | ;; 1195 | *) 1196 | echo "请输入正确数字 [0-10]" 1197 | ;; 1198 | esac 1199 | } 1200 | Set_Mirror() { 1201 | echo -e "${Info} 请输入要选择的下载源,默认使用GitHub,中国大陆建议选择Coding.net,但是不建议将服务端部署在中国大陆主机上 1202 | ${Green_font_prefix} 1.${Font_color_suffix} GitHub 1203 | ${Green_font_prefix} 2.${Font_color_suffix} Coding.net (部分资源通过 FastGit 提供服务下载, Thanks to FastGit.org for the service)" 1204 | read -erp "请输入数字 [1-2], 默认为 1:" mirror_num 1205 | [[ -z "${mirror_num}" ]] && mirror_num=1 1206 | [[ ${mirror_num} == 2 ]] && link_prefix=${coding_prefix} || link_prefix=${github_prefix} 1207 | } 1208 | check_sys 1209 | action=$1 1210 | if [[ -n $action ]]; then 1211 | if [[ $action == "s" ]]; then 1212 | menu_server 1213 | elif [[ $action == "c" ]]; then 1214 | menu_client 1215 | fi 1216 | else 1217 | menu_client 1218 | fi 1219 | -------------------------------------------------------------------------------- /dependencies/superbench.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Description: Auto system info & I/O test & network to China script 4 | # 5 | 6 | RED='\033[0;31m' 7 | GREEN='\033[0;32m' 8 | YELLOW='\033[0;33m' 9 | SKYBLUE='\033[0;36m' 10 | PLAIN='\033[0m' 11 | BrowserUA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" 12 | 13 | about() { 14 | echo "" 15 | echo " ========================================================= " 16 | echo " \ Superbench.sh Script / " 17 | echo " \ Basic system info, I/O test and speedtest / " 18 | echo " \ v1.3.2 (2022-03-20) / " 19 | echo " ========================================================= " 20 | echo "" 21 | echo "" 22 | } 23 | 24 | cancel() { 25 | echo "" 26 | next; 27 | echo " Abort ..." 28 | echo " Cleanup ..." 29 | cleanup; 30 | echo " Done" 31 | exit 32 | } 33 | 34 | trap cancel SIGINT 35 | 36 | benchinit() { 37 | if [ -f /etc/redhat-release ]; then 38 | release="centos" 39 | elif cat /etc/issue | grep -Eqi "debian"; then 40 | release="debian" 41 | elif cat /etc/issue | grep -Eqi "ubuntu"; then 42 | release="ubuntu" 43 | elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then 44 | release="centos" 45 | elif cat /proc/version | grep -Eqi "debian"; then 46 | release="debian" 47 | elif cat /proc/version | grep -Eqi "ubuntu"; then 48 | release="ubuntu" 49 | elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 50 | release="centos" 51 | fi 52 | 53 | [[ $EUID -ne 0 ]] && echo -e "${RED}Error:${PLAIN} This script must be run as root!" && exit 1 54 | 55 | if [ "$(command -v python)" == "" ]; then 56 | echo " Installing Python2 ..." 57 | if [ "${release}" == "centos" ]; then 58 | #yum update > /dev/null 2>&1 59 | os_version=$(cat /etc/redhat-release | awk -F'.' '{print $1}' | awk -F' ' '{print $4}') 60 | if [ "${os_version}" == "8" ]; then 61 | if [ ! -e '/bin/python2' ]; then 62 | yum -y install python2 > /dev/null 2>&1 63 | fi 64 | ln -s /bin/python2 /bin/python 65 | else 66 | yum -y install python > /dev/null 2>&1 67 | fi 68 | else 69 | if [ ! -e '/usr/bin/python2' ]; then 70 | apt-get update > /dev/null 2>&1 71 | apt-get -y install python2 > /dev/null 2>&1 72 | fi 73 | [ ! -e '/usr/bin/python' ] && ln -s /usr/bin/python2 /usr/bin/python 74 | fi 75 | fi 76 | 77 | if [ "$(command -v curl)" == "" ]; then 78 | echo " Installing Curl ..." 79 | if [ "${release}" == "centos" ]; then 80 | yum -y install curl > /dev/null 2>&1 81 | else 82 | apt-get update > /dev/null 2>&1 83 | apt-get -y install curl > /dev/null 2>&1 84 | fi 85 | fi 86 | 87 | if [ "$(command -v tar)" == "" ]; then 88 | echo " Installing Tar ..." 89 | if [ "${release}" == "centos" ]; then 90 | yum -y install tar > /dev/null 2>&1 91 | else 92 | apt-get update > /dev/null 2>&1 93 | apt-get -y install tar > /dev/null 2>&1 94 | fi 95 | fi 96 | 97 | if [ "$(command -v wget)" == "" ]; then 98 | echo " Installing Wget ..." 99 | if [ "${release}" == "centos" ]; then 100 | yum -y install wget > /dev/null 2>&1 101 | else 102 | apt-get update > /dev/null 2>&1 103 | apt-get -y install wget > /dev/null 2>&1 104 | fi 105 | fi 106 | 107 | if [ "$(command -v unzip)" == "" ]; then 108 | echo " Installing UnZip ..." 109 | if [ "${release}" == "centos" ]; then 110 | yum -y install unzip > /dev/null 2>&1 111 | else 112 | apt-get update > /dev/null 2>&1 113 | apt-get -y install unzip > /dev/null 2>&1 114 | fi 115 | fi 116 | 117 | if [ ! -e './speedtest-cli/speedtest' ]; then 118 | echo " Installing Speedtest-cli ..." 119 | wget --no-check-certificate -qO speedtest.tgz https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/speedtest.tgz > /dev/null 2>&1 120 | if [[ $? -ne '0' ]]; then 121 | wget --no-check-certificate -qO speedtest.tgz https://install.speedtest.net/app/cli/ookla-speedtest-1.1.0-x86_64-linux.tgz > /dev/null 2>&1 122 | fi 123 | fi 124 | mkdir -p speedtest-cli && tar zxvf speedtest.tgz -C ./speedtest-cli/ > /dev/null 2>&1 && chmod a+rx ./speedtest-cli/speedtest 125 | 126 | if [ ! -e './besttrace4/besttrace' ]; then 127 | echo " Installing Best Trace..." 128 | wget --no-check-certificate -T 10 -qO besttrace4linux.zip https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/besttrace4linux.zip > /dev/null 2>&1 129 | if [[ $? -ne '0' ]]; then 130 | wget --no-check-certificate -O besttrace4linux.zip https://cdn.ipip.net/17mon/besttrace4linux.zip > /dev/null 2>&1 131 | fi 132 | unzip besttrace4linux.zip -d besttrace4 > /dev/null 2>&1 133 | fi 134 | chmod +x ./besttrace4/besttrace 135 | 136 | # if [ ! -e './geekbench/geekbench4' ]; then 137 | # echo " Installing Geekbench 4..." 138 | # wget --no-check-certificate -qO Geekbench.tar.gz https://down.vpsxb.net/Geekbench.tar.gz > /dev/null 2>&1 139 | # tar -xzf Geekbench.tar.gz > /dev/null 2>&1 140 | # mv -f Geekbench-4.4.2-Linux geekbench > /dev/null 2>&1 141 | # fi 142 | # chmod +x ./geekbench/geekbench4 143 | 144 | if [ ! -e 'tools.py' ]; then 145 | echo " Installing tools.py ..." 146 | wget --no-check-certificate https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/tools.py > /dev/null 2>&1 147 | fi 148 | chmod a+rx tools.py 149 | 150 | if [ ! -e 'fast_com.py' ]; then 151 | echo " Installing Fast.com-cli ..." 152 | wget --no-check-certificate https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/fast_com.py > /dev/null 2>&1 153 | wget --no-check-certificate https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/fast_com_example_usage.py > /dev/null 2>&1 154 | fi 155 | chmod a+rx fast_com.py 156 | chmod a+rx fast_com_example_usage.py 157 | 158 | sleep 5 159 | 160 | start=$(date +%s) 161 | } 162 | 163 | get_opsy() { 164 | [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return 165 | [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return 166 | [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return 167 | } 168 | 169 | next() { 170 | printf "%-70s\n" "-" | sed 's/\s/-/g' | tee -a $log 171 | } 172 | 173 | speed_test(){ 174 | if [[ $1 == '' ]]; then 175 | speedtest-cli/speedtest -p no --accept-license --accept-gdpr > $speedLog 2>&1 176 | is_upload=$(cat $speedLog | grep 'Upload') 177 | result_speed=$(cat $speedLog | awk -F ' ' '/Result/{print $3}') 178 | if [[ ${is_upload} ]]; then 179 | local REDownload=$(cat $speedLog | awk -F ' ' '/Download/{print $3}') 180 | local reupload=$(cat $speedLog | awk -F ' ' '/Upload/{print $3}') 181 | local relatency=$(cat $speedLog | awk -F ' ' '/Latency/{print $2}') 182 | 183 | temp=$(echo "$relatency" | awk -F '.' '{print $1}') 184 | if [[ ${temp} -gt 50 ]]; then 185 | relatency="(*)"${relatency} 186 | fi 187 | local nodeName=$2 188 | 189 | temp=$(echo "${REDownload}" | awk -F ' ' '{print $1}') 190 | if [[ $(awk -v num1=${temp} -v num2=0 'BEGIN{print(num1>num2)?"1":"0"}') -eq 1 ]]; then 191 | printf "${YELLOW}%-18s${GREEN}%-18s${RED}%-20s${SKYBLUE}%-12s${PLAIN}\n" " ${nodeName}" "${reupload} Mbit/s" "${REDownload} Mbit/s" "${relatency} ms" | tee -a $log 192 | fi 193 | else 194 | local cerror="ERROR" 195 | fi 196 | else 197 | speedtest-cli/speedtest -p no -s $1 --accept-license --accept-gdpr > $speedLog 2>&1 198 | is_upload=$(cat $speedLog | grep 'Upload') 199 | if [[ ${is_upload} ]]; then 200 | local REDownload=$(cat $speedLog | awk -F ' ' '/Download/{print $3}') 201 | local reupload=$(cat $speedLog | awk -F ' ' '/Upload/{print $3}') 202 | local relatency=$(cat $speedLog | awk -F ' ' '/Latency/{print $2}') 203 | local nodeName=$2 204 | 205 | temp=$(echo "${REDownload}" | awk -F ' ' '{print $1}') 206 | if [[ $(awk -v num1=${temp} -v num2=0 'BEGIN{print(num1>num2)?"1":"0"}') -eq 1 ]]; then 207 | printf "${YELLOW}%-18s${GREEN}%-18s${RED}%-20s${SKYBLUE}%-12s${PLAIN}\n" " ${nodeName}" "${reupload} Mbit/s" "${REDownload} Mbit/s" "${relatency} ms" | tee -a $log 208 | fi 209 | else 210 | local cerror="ERROR" 211 | fi 212 | fi 213 | } 214 | 215 | print_china_speedtest() { 216 | printf "%-18s%-18s%-20s%-12s\n" " Node Name" "Upload Speed" "Download Speed" "Latency" | tee -a $log 217 | speed_test '' 'Speedtest.net' 218 | speed_fast_com 219 | speed_test '3633' 'Shanghai CT' 220 | speed_test '27594' 'Guangzhou 5G CT' 221 | speed_test '26352' 'Nanjing 5G CT' 222 | speed_test '34115' 'TianJin 5G CT' 223 | speed_test '7509' 'Hangzhou CT' 224 | # speed_test '23844' 'Wuhan CT' 225 | speed_test '5145' 'Beijing CU' 226 | speed_test '24447' 'Shanghai 5G CU' 227 | speed_test '26678' 'Guangzhou 5G CU' 228 | speed_test '16192' 'ShenZhen CU' 229 | speed_test '9484' 'Changchun CU' 230 | speed_test '13704' 'Nanjing CU' 231 | # speed_test '37235' 'Shenyang CU' 232 | # speed_test '41009' 'Wuhan 5G CU' 233 | speed_test '25637' 'Shanghai 5G CM' 234 | speed_test '4647' 'Hangzhou CM' 235 | speed_test '26656' 'Harbin CM' 236 | speed_test '26940' 'Yinchuan CM' 237 | speed_test '27249' 'Nanjing 5G CM' 238 | speed_test '40131' 'Suzhou 5G CM' 239 | speed_test '5505' 'Beijing BN' 240 | } 241 | 242 | print_global_speedtest() { 243 | printf "%-18s%-18s%-20s%-12s\n" " Node Name" "Upload Speed" "Download Speed" "Latency" | tee -a $log 244 | speed_test '1536' 'Hong Kong CN' 245 | speed_test '33250' 'Macau CN' 246 | speed_test '29106' 'Taiwan CN' 247 | speed_test '40508' 'Singapore SG' 248 | # speed_test '4956' 'Kuala Lumpur MY' 249 | # speed_test '38134' 'Fukuoka JP' 250 | speed_test '28910' 'Tokyo JP' 251 | speed_test '6527' 'Seoul KR' 252 | speed_test '18229' 'Los Angeles US' 253 | # speed_test '15786' 'San Jose US' 254 | speed_test '41248' 'London UK' 255 | speed_test '31120' 'Frankfurt DE' 256 | speed_test '21268' 'France FR' 257 | } 258 | 259 | print_speedtest_fast() { 260 | printf "%-18s%-18s%-20s%-12s\n" " Node Name" "Upload Speed" "Download Speed" "Latency" | tee -a $log 261 | speed_test '' 'Speedtest.net' 262 | speed_fast_com 263 | speed_test '1536' 'Hong Kong CN' 264 | speed_test '29106' 'Taiwan CN' 265 | speed_test '40508' 'Singapore SG' 266 | speed_test '28910' 'Tokyo JP' 267 | speed_test '14236' 'Los Angeles US' 268 | speed_test '31120' 'Frankfurt DE' 269 | speed_test '3633' 'Shanghai CT' 270 | speed_test '27594' 'Guangzhou 5G CT' 271 | speed_test '24447' 'ShangHai 5G CU' 272 | speed_test '13704' 'Nanjing CU' 273 | speed_test '25637' 'Shanghai 5G CM' 274 | speed_test '4647' 'Hangzhou CM' 275 | 276 | rm -rf speedtest* 277 | } 278 | 279 | speed_fast_com() { 280 | temp=$(python fast_com_example_usage.py 2>&1) 281 | is_down=$(echo "$temp" | grep 'Result') 282 | if [[ ${is_down} ]]; then 283 | temp1=$(echo "$temp" | awk -F ':' '/Result/{print $2}') 284 | temp2=$(echo "$temp1" | awk -F ' ' '/Mbps/{print $1}') 285 | local REDownload="$temp2 Mbit/s" 286 | local reupload="0.00 Mbit/s" 287 | local relatency="-" 288 | local nodeName="Fast.com" 289 | 290 | printf "${YELLOW}%-18s${GREEN}%-18s${RED}%-20s${SKYBLUE}%-12s${PLAIN}\n" " ${nodeName}" "${reupload}" "${REDownload}" "${relatency}" | tee -a $log 291 | else 292 | local cerror="ERROR" 293 | fi 294 | rm -rf fast_com_example_usage.py 295 | rm -rf fast_com.py 296 | 297 | } 298 | 299 | io_test() { 300 | (LANG=C dd if=/dev/zero of=test_file_$$ bs=512K count=$1 conv=fdatasync && rm -f test_file_$$ ) 2>&1 | awk -F, '{io=$NF} END { print io}' | sed 's/^[ \t]*//;s/[ \t]*$//' 301 | } 302 | 303 | calc_disk() { 304 | local total_size=0 305 | local array=$@ 306 | for size in ${array[@]} 307 | do 308 | [ "${size}" == "0" ] && size_t=0 || size_t=`echo ${size:0:${#size}-1}` 309 | [ "`echo ${size:(-1)}`" == "K" ] && size=0 310 | [ "`echo ${size:(-1)}`" == "M" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' / 1024}' ) 311 | [ "`echo ${size:(-1)}`" == "T" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' * 1024}' ) 312 | [ "`echo ${size:(-1)}`" == "G" ] && size=${size_t} 313 | total_size=$( awk 'BEGIN{printf "%.1f", '$total_size' + '$size'}' ) 314 | done 315 | echo ${total_size} 316 | } 317 | 318 | power_time() { 319 | 320 | result=$(smartctl -a $(result=$(cat /proc/mounts) && echo $(echo "$result" | awk '/data=ordered/{print $1}') | awk '{print $1}') 2>&1) && power_time=$(echo "$result" | awk '/Power_On/{print $10}') && echo "$power_time" 321 | } 322 | 323 | install_smart() { 324 | if [ ! -e '/usr/sbin/smartctl' ]; then 325 | echo "Installing Smartctl ..." 326 | if [ "${release}" == "centos" ]; then 327 | yum update > /dev/null 2>&1 328 | yum -y install smartmontools > /dev/null 2>&1 329 | else 330 | apt-get update > /dev/null 2>&1 331 | apt-get -y install smartmontools > /dev/null 2>&1 332 | fi 333 | fi 334 | } 335 | 336 | ip_info4(){ 337 | ip_date=$(curl -4 -s http://api.ip.la/en?json) 338 | echo $ip_date > ip_json.json 339 | isp=$(python tools.py geoip isp) 340 | as_tmp=$(python tools.py geoip as) 341 | asn=$(echo $as_tmp | awk -F ' ' '{print $1}') 342 | org=$(python tools.py geoip org) 343 | if [ -z "ip_date" ]; then 344 | echo $ip_date 345 | echo "hala" 346 | country=$(python tools.py ipip country_name) 347 | city=$(python tools.py ipip city) 348 | countryCode=$(python tools.py ipip country_code) 349 | region=$(python tools.py ipip province) 350 | else 351 | country=$(python tools.py geoip country) 352 | city=$(python tools.py geoip city) 353 | countryCode=$(python tools.py geoip countryCode) 354 | region=$(python tools.py geoip regionName) 355 | fi 356 | if [ -z "$city" ]; then 357 | city=${region} 358 | fi 359 | 360 | echo -e " ASN & ISP : ${SKYBLUE}$asn, $isp${PLAIN}" | tee -a $log 361 | echo -e " Organization : ${YELLOW}$org${PLAIN}" | tee -a $log 362 | echo -e " Location : ${SKYBLUE}$city, ${YELLOW}$country / $countryCode${PLAIN}" | tee -a $log 363 | echo -e " Region : ${SKYBLUE}$region${PLAIN}" | tee -a $log 364 | 365 | rm -rf tools.py 366 | rm -rf ip_json.json 367 | } 368 | 369 | virt_check(){ 370 | if hash ifconfig 2>/dev/null; then 371 | eth=$(ifconfig) 372 | fi 373 | 374 | virtualx=$(dmesg) 2>/dev/null 375 | 376 | if [ $(which dmidecode) ]; then 377 | sys_manu=$(dmidecode -s system-manufacturer) 2>/dev/null 378 | sys_product=$(dmidecode -s system-product-name) 2>/dev/null 379 | sys_ver=$(dmidecode -s system-version) 2>/dev/null 380 | else 381 | sys_manu="" 382 | sys_product="" 383 | sys_ver="" 384 | fi 385 | 386 | if grep docker /proc/1/cgroup -qa; then 387 | virtual="Docker" 388 | elif grep lxc /proc/1/cgroup -qa; then 389 | virtual="Lxc" 390 | elif grep -qa container=lxc /proc/1/environ; then 391 | virtual="Lxc" 392 | elif [[ -f /proc/user_beancounters ]]; then 393 | virtual="OpenVZ" 394 | elif [[ "$virtualx" == *kvm-clock* ]]; then 395 | virtual="KVM" 396 | elif [[ "$cname" == *KVM* ]]; then 397 | virtual="KVM" 398 | elif [[ "$cname" == *QEMU* ]]; then 399 | virtual="KVM" 400 | elif [[ "$virtualx" == *"VMware Virtual Platform"* ]]; then 401 | virtual="VMware" 402 | elif [[ "$virtualx" == *"Parallels Software International"* ]]; then 403 | virtual="Parallels" 404 | elif [[ "$virtualx" == *VirtualBox* ]]; then 405 | virtual="VirtualBox" 406 | elif [[ -e /proc/xen ]]; then 407 | virtual="Xen" 408 | elif [[ "$sys_manu" == *"Microsoft Corporation"* ]]; then 409 | if [[ "$sys_product" == *"Virtual Machine"* ]]; then 410 | if [[ "$sys_ver" == *"7.0"* || "$sys_ver" == *"Hyper-V" ]]; then 411 | virtual="Hyper-V" 412 | else 413 | virtual="Microsoft Virtual Machine" 414 | fi 415 | fi 416 | else 417 | virtual="Dedicated" 418 | fi 419 | } 420 | 421 | power_time_check(){ 422 | echo -ne " Power time of disk : " 423 | install_smart 424 | ptime=$(power_time) 425 | echo -e "${SKYBLUE}$ptime Hours${PLAIN}" 426 | } 427 | 428 | freedisk() { 429 | freespace=$( df -m . | awk 'NR==2 {print $4}' ) 430 | if [[ $freespace == "" ]]; then 431 | $freespace=$( df -m . | awk 'NR==3 {print $3}' ) 432 | fi 433 | if [[ $freespace -gt 1024 ]]; then 434 | printf "%s" $((1024*2)) 435 | elif [[ $freespace -gt 512 ]]; then 436 | printf "%s" $((512*2)) 437 | elif [[ $freespace -gt 256 ]]; then 438 | printf "%s" $((256*2)) 439 | elif [[ $freespace -gt 128 ]]; then 440 | printf "%s" $((128*2)) 441 | else 442 | printf "1" 443 | fi 444 | } 445 | 446 | print_io() { 447 | if [[ $1 == "fast" ]]; then 448 | writemb=$((128*2)) 449 | else 450 | writemb=$(freedisk) 451 | fi 452 | 453 | writemb_size="$(( writemb / 2 ))MB" 454 | if [[ $writemb_size == "1024MB" ]]; then 455 | writemb_size="1.0GB" 456 | fi 457 | 458 | if [[ $writemb != "1" ]]; then 459 | echo -n " I/O Speed( $writemb_size ) : " | tee -a $log 460 | io1=$( io_test $writemb ) 461 | echo -e "${YELLOW}$io1${PLAIN}" | tee -a $log 462 | echo -n " I/O Speed( $writemb_size ) : " | tee -a $log 463 | io2=$( io_test $writemb ) 464 | echo -e "${YELLOW}$io2${PLAIN}" | tee -a $log 465 | echo -n " I/O Speed( $writemb_size ) : " | tee -a $log 466 | io3=$( io_test $writemb ) 467 | echo -e "${YELLOW}$io3${PLAIN}" | tee -a $log 468 | ioraw1=$( echo $io1 | awk 'NR==1 {print $1}' ) 469 | [ "`echo $io1 | awk 'NR==1 {print $2}'`" == "GB/s" ] && ioraw1=$( awk 'BEGIN{print '$ioraw1' * 1024}' ) 470 | ioraw2=$( echo $io2 | awk 'NR==1 {print $1}' ) 471 | [ "`echo $io2 | awk 'NR==1 {print $2}'`" == "GB/s" ] && ioraw2=$( awk 'BEGIN{print '$ioraw2' * 1024}' ) 472 | ioraw3=$( echo $io3 | awk 'NR==1 {print $1}' ) 473 | [ "`echo $io3 | awk 'NR==1 {print $2}'`" == "GB/s" ] && ioraw3=$( awk 'BEGIN{print '$ioraw3' * 1024}' ) 474 | ioall=$( awk 'BEGIN{print '$ioraw1' + '$ioraw2' + '$ioraw3'}' ) 475 | ioavg=$( awk 'BEGIN{printf "%.1f", '$ioall' / 3}' ) 476 | echo -e " Average I/O Speed : ${YELLOW}$ioavg MB/s${PLAIN}" | tee -a $log 477 | else 478 | echo -e " ${RED}Not enough space!${PLAIN}" 479 | fi 480 | } 481 | 482 | print_system_info() { 483 | echo -e " CPU Model : ${SKYBLUE}$cname${PLAIN}" | tee -a $log 484 | echo -e " CPU Cores : ${YELLOW}$cores Cores ${SKYBLUE}$freq MHz $arch${PLAIN}" | tee -a $log 485 | echo -e " CPU Cache : ${SKYBLUE}$corescache ${PLAIN}" | tee -a $log 486 | echo -e " CPU Flags : ${SKYBLUE}AES-NI $aes & ${YELLOW}VM-x/AMD-V $virt ${PLAIN}" | tee -a $log 487 | echo -e " OS : ${SKYBLUE}$opsy ($lbit Bit) ${YELLOW}$virtual${PLAIN}" | tee -a $log 488 | echo -e " Kernel : ${SKYBLUE}$kern${PLAIN}" | tee -a $log 489 | echo -e " Total Space : ${SKYBLUE}$disk_used_size GB / ${YELLOW}$disk_total_size GB ${PLAIN}" | tee -a $log 490 | echo -e " Total RAM : ${SKYBLUE}$uram MB / ${YELLOW}$tram MB ${SKYBLUE}($bram MB Buff)${PLAIN}" | tee -a $log 491 | echo -e " Total SWAP : ${SKYBLUE}$uswap MB / $swap MB${PLAIN}" | tee -a $log 492 | echo -e " Uptime : ${SKYBLUE}$up${PLAIN}" | tee -a $log 493 | echo -e " Load Average : ${SKYBLUE}$load${PLAIN}" | tee -a $log 494 | echo -e " TCP CC : ${YELLOW}$tcpctrl${PLAIN}" | tee -a $log 495 | } 496 | 497 | print_end_time() { 498 | end=$(date +%s) 499 | time=$(( $end - $start )) 500 | if [[ $time -gt 60 ]]; then 501 | min=$(expr $time / 60) 502 | sec=$(expr $time % 60) 503 | echo -ne " Finished in : ${min} min ${sec} sec" | tee -a $log 504 | else 505 | echo -ne " Finished in : ${time} sec" | tee -a $log 506 | fi 507 | 508 | printf '\n' | tee -a $log 509 | 510 | bj_time=$(curl -s http://cgi.im.qq.com/cgi-bin/cgi_svrtime) 511 | 512 | if [[ $(echo $bj_time | grep "html") ]]; then 513 | bj_time=$(date -u +%Y-%m-%d" "%H:%M:%S -d '+8 hours') 514 | fi 515 | echo " Timestamp : $bj_time GMT+8" | tee -a $log 516 | echo " Results : $log" 517 | } 518 | 519 | get_system_info() { 520 | cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) 521 | cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo ) 522 | freq=$( awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) 523 | corescache=$( awk -F: '/cache size/ {cache=$2} END {print cache}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) 524 | aes=$(cat /proc/cpuinfo | grep aes) 525 | [[ -z "$aes" ]] && aes="Disabled" || aes="Enabled" 526 | virt=$(cat /proc/cpuinfo | grep 'vmx\|svm') 527 | [[ -z "$virt" ]] && virt="Disabled" || virt="Enabled" 528 | tram=$( free -m | awk '/Mem/ {print $2}' ) 529 | uram=$( free -m | awk '/Mem/ {print $3}' ) 530 | bram=$( free -m | awk '/Mem/ {print $6}' ) 531 | swap=$( free -m | awk '/Swap/ {print $2}' ) 532 | uswap=$( free -m | awk '/Swap/ {print $3}' ) 533 | up=$( awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60} {printf("%d days %d hour %d min\n",a,b,c)}' /proc/uptime ) 534 | load=$( w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//' ) 535 | opsy=$( get_opsy ) 536 | arch=$( uname -m ) 537 | lbit=$( getconf LONG_BIT ) 538 | kern=$( uname -r ) 539 | 540 | disk_size1=$( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|overlay|shm|udev|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $2}' ) 541 | disk_size2=$( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|overlay|shm|udev|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $3}' ) 542 | disk_total_size=$( calc_disk ${disk_size1[@]} ) 543 | disk_used_size=$( calc_disk ${disk_size2[@]} ) 544 | 545 | tcpctrl=$( sysctl net.ipv4.tcp_congestion_control | awk -F ' ' '{print $3}' ) 546 | 547 | virt_check 548 | } 549 | 550 | besttrace_test() { 551 | if [ "$2" = "tcp" ] || [ "$2" = "TCP" ]; then 552 | echo -e "\nTraceroute to $4 (TCP Mode, Max $3 Hop)" | tee -a $log 553 | echo -e "============================================================" | tee -a $log 554 | ./besttrace4/besttrace -g cn -T -q 1 -m $3 $1 | tee -a $log 555 | else 556 | echo -e "\nTracecroute to $4 (ICMP Mode, Max $3 Hop)" | tee -a $log 557 | echo -e "============================================================" | tee -a $log 558 | ./besttrace4/besttrace -g cn -q 1 -m $3 $1 | tee -a $log 559 | fi 560 | } 561 | 562 | print_besttrace_test(){ 563 | #besttrace_test "113.108.209.1" "TCP" "30" "China, Guangzhou CT" 564 | #besttrace_test "180.153.28.5" "TCP" "30" "China, Shanghai CT" 565 | #besttrace_test "180.149.128.9" "TCP" "30" "China, Beijing CT" 566 | #besttrace_test "210.21.4.130" "TCP" "30" "China, Guangzhou CU" 567 | #besttrace_test "58.247.8.158" "TCP" "30" "China, Shanghai CU" 568 | #besttrace_test "123.125.99.1" "TCP" "30" "China, Beijing CU" 569 | #besttrace_test "120.196.212.25" "TCP" "30" "China, Guangzhou CM" 570 | #besttrace_test "221.183.55.22" "TCP" "30" "China, Shanghai CM" 571 | #besttrace_test "211.136.25.153" "TCP" "30" "China, Beijing CM" 572 | #besttrace_test "211.167.230.100" "TCP" "30" "China, Beijing Dr.Peng Network IDC Network" 573 | besttrace_test "101.95.206.10" "TCP" "30" "上海电信" 574 | besttrace_test "58.32.0.1" "TCP" "30" "上海CN2" 575 | besttrace_test "139.226.227.38" "TCP" "30" "上海联通" 576 | besttrace_test "210.13.66.238" "TCP" "30" "上海联通9929" 577 | besttrace_test "221.183.55.22" "TCP" "30" "上海移动" 578 | besttrace_test "101.4.117.213" "TCP" "30" "北京教育网" 579 | } 580 | 581 | #geekbench4() { 582 | # echo -e "Geekbench v4 CPU Benchmark:" | tee -a $log 583 | # GEEKBENCH_TEST=$(./geekbench/geekbench4 2>/dev/null | grep "https://browser") 584 | # GEEKBENCH_URL=$(echo -e $GEEKBENCH_TEST | head -1) 585 | # GEEKBENCH_URL_CLAIM=$(echo $GEEKBENCH_URL | awk '{ print $2 }') 586 | # GEEKBENCH_URL=$(echo $GEEKBENCH_URL | awk '{ print $1 }') 587 | # sleep 20 588 | # GEEKBENCH_SCORES=$(curl -s $GEEKBENCH_URL | grep "span class='score'") 589 | # GEEKBENCH_SCORES_SINGLE=$(echo $GEEKBENCH_SCORES | awk -v FS="(>|<)" '{ print $3 }') 590 | # GEEKBENCH_SCORES_MULTI=$(echo $GEEKBENCH_SCORES | awk -v FS="(>|<)" '{ print $7 }') 591 | # SINGLE_FONT_COLOR=$YELLOW 592 | # MULTI_FONT_COLOR=$YELLOW 593 | # if [[ $GEEKBENCH_SCORES_SINGLE -le 1700 ]]; then 594 | # grank="(Poor)" 595 | # SINGLE_FONT_COLOR=$RED 596 | # elif [[ $GEEKBENCH_SCORES_SINGLE -ge 1700 && $GEEKBENCH_SCORES_SINGLE -le 2500 ]]; then 597 | # grank="(Fair)" 598 | # elif [[ $GEEKBENCH_SCORES_SINGLE -ge 2500 && $GEEKBENCH_SCORES_SINGLE -le 3500 ]]; then 599 | # grank="(Good)" 600 | # SINGLE_FONT_COLOR=$GREEN 601 | # elif [[ $GEEKBENCH_SCORES_SINGLE -ge 3500 && $GEEKBENCH_SCORES_SINGLE -le 4500 ]]; then 602 | # grank="(Very Good)" 603 | # SINGLE_FONT_COLOR=$GREEN 604 | # elif [[ $GEEKBENCH_SCORES_SINGLE -ge 4500 && $GEEKBENCH_SCORES_SINGLE -le 6000 ]]; then 605 | # grank="(Excellent)" 606 | # SINGLE_FONT_COLOR=$GREEN 607 | # else 608 | # grank="(The beast)" 609 | # fi 610 | # 611 | # if [[ $GEEKBENCH_SCORES_MULTI -le 1700 ]]; then 612 | # MULTI_FONT_COLOR=$RED 613 | # elif [[ $GEEKBENCH_SCORES_MULTI -ge 2500 && $GEEKBENCH_SCORES_MULTI -le 3500 ]]; then 614 | # MULTI_FONT_COLOR=$GREEN 615 | # elif [[ $GEEKBENCH_SCORES_MULTI -ge 3500 && $GEEKBENCH_SCORES_MULTI -le 4500 ]]; then 616 | # MULTI_FONT_COLOR=$GREEN 617 | # elif [[ $GEEKBENCH_SCORES_MULTI -ge 4500 && $GEEKBENCH_SCORES_MULTI -le 6000 ]]; then 618 | # MULTI_FONT_COLOR=$GREEN 619 | # fi 620 | # 621 | # echo -e " Single Core : ${SINGLE_FONT_COLOR}$GEEKBENCH_SCORES_SINGLE $grank${PLAIN}" | tee -a $log 622 | # echo -e " Multi Core : ${MULTI_FONT_COLOR}$GEEKBENCH_SCORES_MULTI${PLAIN}" | tee -a $log 623 | # [ ! -z "$GEEKBENCH_URL_CLAIM" ] && echo -e "$GEEKBENCH_URL_CLAIM" >> geekbench_claim.url 2> /dev/null 624 | # 625 | # rm -rf geekbench 626 | #} 627 | 628 | function UnlockNetflixTest() { 629 | echo -n -e " Netflix : ->\c"; 630 | local result1=$(curl --user-agent "${BrowserUA}" -fsL --write-out %{http_code} --output /dev/null --max-time 10 "https://www.netflix.com/title/81215567" 2>&1) 631 | 632 | if [[ "$result1" == "404" ]];then 633 | echo -n -e "\r Netflix : ${YELLOW}Originals Only${PLAIN}\n" | tee -a $log 634 | elif [[ "$result1" == "403" ]];then 635 | echo -n -e "\r Netflix : ${RED}No${PLAIN}\n" | tee -a $log 636 | elif [[ "$result1" == "200" ]];then 637 | local region=`tr [:lower:] [:upper:] <<< $(curl --user-agent "${BrowserUA}" -fs --max-time 10 --write-out %{redirect_url} --output /dev/null "https://www.netflix.com/title/80018499" | cut -d '/' -f4 | cut -d '-' -f1)` ; 638 | if [[ ! -n "$region" ]];then 639 | region="US"; 640 | fi 641 | echo -n -e "\r Netflix : ${GREEN}Yes (Region: ${region})${PLAIN}\n" | tee -a $log 642 | elif [[ "$result1" == "000" ]];then 643 | echo -n -e "\r Netflix : ${RED}Network connection failed${PLAIN}\n" | tee -a $log 644 | fi 645 | } 646 | 647 | function UnlockYouTubePremiumTest() { 648 | echo -n -e " YouTube Premium : ->\c"; 649 | local tmpresult=$(curl -sS -H "Accept-Language: en" "https://www.youtube.com/premium" 2>&1 ) 650 | local region=$(curl --user-agent "${BrowserUA}" -sL --max-time 10 "https://www.youtube.com/premium" | grep "countryCode" | sed 's/.*"countryCode"//' | cut -f2 -d'"') 651 | if [ -n "$region" ]; then 652 | sleep 0 653 | else 654 | isCN=$(echo $tmpresult | grep 'www.google.cn') 655 | if [ -n "$isCN" ]; then 656 | region=CN 657 | else 658 | region=US 659 | fi 660 | fi 661 | 662 | if [[ "$tmpresult" == "curl"* ]];then 663 | echo -n -e "\r YouTube Premium : ${RED}Network connection failed${PLAIN}\n" | tee -a $log 664 | return; 665 | fi 666 | 667 | local result=$(echo $tmpresult | grep 'Premium is not available in your country') 668 | if [ -n "$result" ]; then 669 | echo -n -e "\r YouTube Premium : ${RED}No${PLAIN} ${PLAIN}${GREEN} (Region: $region)${PLAIN} \n" | tee -a $log 670 | return; 671 | 672 | fi 673 | local result=$(echo $tmpresult | grep 'YouTube and YouTube Music ad-free') 674 | if [ -n "$result" ]; then 675 | echo -n -e "\r YouTube Premium : ${GREEN}Yes (Region: $region)${PLAIN}\n" | tee -a $log 676 | return; 677 | else 678 | echo -n -e "\r YouTube Premium : ${RED}Failed${PLAIN}\n" | tee -a $log 679 | fi 680 | } 681 | 682 | function YouTubeCDNTest() { 683 | echo -n -e " YouTube CDN : ->\c"; 684 | local tmpresult=$(curl -sS --max-time 10 https://redirector.googlevideo.com/report_mapping 2>&1) 685 | 686 | if [[ "$tmpresult" == "curl"* ]];then 687 | echo -n -e "\r YouTube Region : ${RED}Network connection failed${PLAIN}\n" | tee -a $log 688 | return; 689 | fi 690 | 691 | iata=$(echo $tmpresult | grep router | cut -f2 -d'"' | cut -f2 -d"." | sed 's/.\{2\}$//' | tr [:lower:] [:upper:]) 692 | checkfailed=$(echo $tmpresult | grep "=>") 693 | if [ -z "$iata" ] && [ -n "$checkfailed" ];then 694 | CDN_ISP=$(echo $checkfailed | awk '{print $3}' | cut -f1 -d"-" | tr [:lower:] [:upper:]) 695 | echo -n -e "\r YouTube CDN : ${YELLOW}Associated with $CDN_ISP${PLAIN}\n" | tee -a $log 696 | return; 697 | elif [ -n "$iata" ];then 698 | curl $useNIC -s --max-time 10 "https://www.iata.org/AirportCodesSearch/Search?currentBlock=314384¤tPage=12572&airport.search=${iata}" > ~/iata.txt 699 | local line=$(cat ~/iata.txt | grep -n ""$iata | awk '{print $1}' | cut -f1 -d":") 700 | local nline=$(expr $line - 2) 701 | local location=$(cat ~/iata.txt | awk NR==${nline} | sed 's/.*//' | cut -f1 -d"<") 702 | echo -n -e "\r YouTube CDN : ${GREEN}$location${PLAIN}\n" | tee -a $log 703 | rm ~/iata.txt 704 | return; 705 | else 706 | echo -n -e "\r YouTube CDN : ${RED}Undetectable${PLAIN}\n" | tee -a $log 707 | rm ~/iata.txt 708 | return; 709 | fi 710 | 711 | } 712 | 713 | function UnlockBilibiliTest() { 714 | echo -n -e " BiliBili China Only : ->\c"; 715 | 716 | #Test Mainland 717 | randsession="$(cat /dev/urandom | head -n 32 | md5sum | head -c 32)"; 718 | result=$(curl --user-agent "${BrowserUA}" -fsSL --max-time 10 "https://api.bilibili.com/pgc/player/web/playurl?avid=82846771&qn=0&type=&otype=json&ep_id=307247&fourk=1&fnver=0&fnval=16&session=${randsession}&module=bangumi" 2>&1); 719 | if [[ "$result" != "curl"* ]]; then 720 | result="$(echo "${result}" | python -m json.tool 2> /dev/null | grep '"code"' | head -1 | awk '{print $2}' | cut -d ',' -f1)"; 721 | if [ "${result}" = "0" ]; then 722 | echo -n -e "\r BiliBili China Only : ${GREEN}Yes (Region: Mainland)${PLAIN}\n" | tee -a $log 723 | return; 724 | fi 725 | else 726 | echo -n -e "\r BiliBili China Only : ${RED}Network connection failed${PLAIN}\n" | tee -a $log 727 | return; 728 | fi 729 | 730 | #Test Hongkong/Macau/Taiwan 731 | randsession="$(cat /dev/urandom | head -n 32 | md5sum | head -c 32)"; 732 | result=$(curl --user-agent "${BrowserUA}" -fsSL --max-time 10 "https://api.bilibili.com/pgc/player/web/playurl?avid=18281381&cid=29892777&qn=0&type=&otype=json&ep_id=183799&fourk=1&fnver=0&fnval=16&session=${randsession}&module=bangumi" 2>&1); 733 | if [[ "$result" != "curl"* ]]; then 734 | result="$(echo "${result}" | python -m json.tool 2> /dev/null | grep '"code"' | head -1 | awk '{print $2}' | cut -d ',' -f1)"; 735 | if [ "${result}" = "0" ]; then 736 | echo -n -e "\r BiliBili China Only : ${GREEN}Yes (Region: Hongkong/Macau/Taiwan)${PLAIN}\n" | tee -a $log 737 | return; 738 | fi 739 | else 740 | echo -n -e "\r BiliBili China Only : ${RED}Network connection failed${PLAIN}\n" | tee -a $log 741 | return; 742 | fi 743 | 744 | #Test Taiwan 745 | randsession="$(cat /dev/urandom | head -n 32 | md5sum | head -c 32)"; 746 | result=$(curl --user-agent "${BrowserUA}" -fsSL --max-time 10 "https://api.bilibili.com/pgc/player/web/playurl?avid=50762638&cid=100279344&qn=0&type=&otype=json&ep_id=268176&fourk=1&fnver=0&fnval=16&session=${randsession}&module=bangumi" 2>&1); 747 | if [[ "$result" != "curl"* ]]; then 748 | result="$(echo "${result}" | python -m json.tool 2> /dev/null | grep '"code"' | head -1 | awk '{print $2}' | cut -d ',' -f1)"; 749 | if [ "${result}" = "0" ]; then 750 | echo -n -e "\r BiliBili China Only : ${GREEN}Yes (Region: Taiwan)${PLAIN}\n" | tee -a $log 751 | return; 752 | fi 753 | else 754 | echo -n -e "\r BiliBili China Only : ${RED}Network connection failed${PLAIN}\n" | tee -a $log 755 | return; 756 | fi 757 | echo -n -e "\r BiliBili China Only : ${RED}No${PLAIN}\n" | tee -a $log 758 | } 759 | 760 | 761 | function StreamingMediaUnlockTest(){ 762 | echo -e "Streaming Media Unlock:" | tee -a $log 763 | UnlockNetflixTest 764 | UnlockYouTubePremiumTest 765 | YouTubeCDNTest 766 | UnlockBilibiliTest 767 | } 768 | 769 | print_intro() { 770 | printf ' Superbench.sh -- https://vpsxb.net/448\n' | tee -a $log 771 | printf " Mode : ${GREEN}%s${PLAIN} Version : ${GREEN}%s${PLAIN}\n" $mode_name 1.3.2 | tee -a $log 772 | printf ' Usage : bash <(wget --no-check-certificate -O- https://down.vpsxb.net/superbench.sh)\n' | tee -a $log 773 | } 774 | 775 | sharetest() { 776 | echo " Share result:" | tee -a $log 777 | echo " · $result_speed" | tee -a $log 778 | log_preupload 779 | case $1 in 780 | 'ubuntu') 781 | share_link="https://paste.ubuntu.com"$( curl -v --data-urlencode "content@$log_up" -d "poster=superbench.sh" -d "syntax=text" "https://paste.ubuntu.com" 2>&1 | \ 782 | grep "Location" | awk '{print $3}' );; 783 | 'haste' ) 784 | share_link=$( curl -X POST -s -d "$(cat $log)" https://hastebin.com/documents | awk -F '"' '{print "https://hastebin.com/"$4}' );; 785 | 'clbin' ) 786 | share_link=$( curl -sF 'clbin=<-' https://clbin.com < $log );; 787 | 'ptpb' ) 788 | share_link=$( curl -sF c=@- https://ptpb.pw/?u=1 < $log );; 789 | esac 790 | 791 | echo " · $share_link" | tee -a $log 792 | next 793 | echo "" 794 | rm -f $log_up 795 | 796 | } 797 | 798 | log_preupload() { 799 | log_up="$HOME/superbench_upload.log" 800 | true > $log_up 801 | $(cat superbench.log 2>&1 | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" > $log_up) 802 | } 803 | 804 | cleanup() { 805 | rm -f test_file_* 806 | rm -rf speedtest* 807 | rm -f fast_com* 808 | rm -f tools.py 809 | rm -f ip_json.json 810 | rm -rf besttrace4* 811 | # rm -rf geekbench* 812 | # rm -rf Geekbench* 813 | } 814 | 815 | bench_all(){ 816 | mode_name="Standard" 817 | about; 818 | benchinit; 819 | clear 820 | next; 821 | print_intro; 822 | next; 823 | get_system_info; 824 | print_system_info; 825 | ip_info4; 826 | next; 827 | # geekbench4; 828 | # next; 829 | StreamingMediaUnlockTest; 830 | next; 831 | print_io; 832 | next; 833 | print_china_speedtest; 834 | next; 835 | print_global_speedtest; 836 | next; 837 | print_besttrace_test; 838 | next; 839 | print_end_time; 840 | next; 841 | cleanup; 842 | sharetest ubuntu; 843 | } 844 | 845 | fast_bench(){ 846 | mode_name="Fast" 847 | about; 848 | benchinit; 849 | clear 850 | next; 851 | print_intro; 852 | next; 853 | get_system_info; 854 | print_system_info; 855 | ip_info4; 856 | next; 857 | print_io fast; 858 | next; 859 | print_speedtest_fast; 860 | next; 861 | print_end_time; 862 | next; 863 | cleanup; 864 | } 865 | 866 | log="./superbench.log" 867 | true > $log 868 | speedLog="./speedtest.log" 869 | true > $speedLog 870 | 871 | case $1 in 872 | 'info'|'-i'|'--i'|'-info'|'--info' ) 873 | about;sleep 3;next;get_system_info;print_system_info;next;; 874 | 'version'|'-v'|'--v'|'-version'|'--version') 875 | next;about;next;; 876 | 'io'|'-io'|'--io'|'-drivespeed'|'--drivespeed' ) 877 | next;print_io;next;; 878 | 'speed'|'-speed'|'--speed'|'-speedtest'|'--speedtest'|'-speedcheck'|'--speedcheck' ) 879 | about;benchinit;next;print_speedtest_fast;next;cleanup;; 880 | 'ip'|'-ip'|'--ip'|'geoip'|'-geoip'|'--geoip' ) 881 | about;benchinit;next;ip_info4;next;cleanup;; 882 | 'bench'|'-a'|'--a'|'-all'|'--all'|'-bench'|'--bench' ) 883 | bench_all;; 884 | 'besttrace'|'-b'|'--b'|'--besttrace' ) 885 | print_besttrace_test;; 886 | 'about'|'-about'|'--about' ) 887 | about;; 888 | 'fast'|'-f'|'--f'|'-fast'|'--fast' ) 889 | fast_bench;; 890 | # 'geekbench'|'geekbench4'|'-g'|'-g4'|'--geekbench'|'--geekbench4' ) 891 | # geekbench4;; 892 | 'share'|'-s'|'--s'|'-share'|'--share' ) 893 | bench_all; 894 | is_share="share" 895 | if [[ $2 == "" ]]; then 896 | sharetest ubuntu; 897 | else 898 | sharetest $2; 899 | fi 900 | ;; 901 | 'debug'|'-d'|'--d'|'-debug'|'--debug' ) 902 | get_ip_whois_org_name;; 903 | *) 904 | bench_all;; 905 | esac 906 | 907 | if [[ ! $is_share == "share" ]]; then 908 | case $2 in 909 | 'share'|'-s'|'--s'|'-share'|'--share' ) 910 | if [[ $3 == '' ]]; then 911 | sharetest ubuntu; 912 | else 913 | sharetest $3; 914 | fi 915 | ;; 916 | esac 917 | fi -------------------------------------------------------------------------------- /dependencies/tcping: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # @Author: zhangnq 3 | # @Blog: https://zhangnq.com/ 4 | # @Tool: http://tool.sijitao.net/software/tcping 5 | 6 | import socket,sys 7 | import time 8 | import argparse 9 | from argparse import RawTextHelpFormatter 10 | 11 | VERSION = '1.0.1' 12 | 13 | ping_cnt = 0 14 | ping_success_cnt = 0 15 | ping_fail_cnt = 0 16 | ping_resp_min = 0 17 | ping_resp_max = 0 18 | ping_resp_avg = 0 19 | ping_resp_total = 0 20 | 21 | class MyParser(argparse.ArgumentParser): 22 | def error(self, message): 23 | sys.stderr.write('error: %s\n' % message) 24 | self.print_help() 25 | sys.exit(2) 26 | 27 | # get ip from hostname 28 | def host2ip(host): 29 | try: 30 | return socket.gethostbyname(host) 31 | except Exception: 32 | return False 33 | 34 | # probing tcp port 35 | def tcp(ip, port, timeout=2): 36 | sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 37 | sk.settimeout(timeout) 38 | try: 39 | t1 = time.time() 40 | sk.connect((ip, port)) 41 | t2 = time.time() 42 | sk.close() 43 | return True, int(round((t2-t1)*1000)) 44 | except Exception: 45 | sk.close() 46 | return False, timeout*1000 47 | 48 | def format_tcp_result(results): 49 | if results[0]: 50 | return "Probing {}:{}/tcp - Port is open - time={}ms".format(ip, port, results[1]) 51 | else: 52 | return "Probing {}:{}/tcp - No response - time={}ms".format(ip, port, results[1]) 53 | 54 | def statistic_tcp_result(results): 55 | global ping_cnt 56 | global ping_success_cnt 57 | global ping_fail_cnt 58 | global ping_resp_min 59 | global ping_resp_max 60 | global ping_resp_avg 61 | global ping_resp_total 62 | # total count 63 | ping_cnt += 1 64 | if results[0]: 65 | # success count 66 | ping_success_cnt += 1 67 | # min ping response time 68 | if ping_resp_min == 0: 69 | ping_resp_min = results[1] 70 | elif results[1] < ping_resp_min: 71 | ping_resp_min = results[1] 72 | # max ping respose time 73 | if results[1] > ping_resp_max: 74 | ping_resp_max = results[1] 75 | # average ping response time 76 | ping_resp_avg = round((ping_resp_total + results[1]) / float(ping_success_cnt), 3) 77 | ping_resp_total += results[1] 78 | else: 79 | # fail count 80 | ping_fail_cnt += 1 81 | 82 | return ping_cnt, ping_success_cnt, ping_fail_cnt, ping_resp_min, ping_resp_max, ping_resp_avg 83 | 84 | if __name__ == "__main__": 85 | desc = '''-------------------------------------------------------------------------- 86 | tcping for linux by zhangnq 87 | Please see http://tool.sijitao.net/software/tcping for more introductions. 88 | --------------------------------------------------------------------------''' 89 | 90 | example_text = '''examples: 91 | tcping zhangnq.com 92 | tcping 114.114.114.114 -t -p 53 93 | tcping zhangnq.com -n 10 -p 443 -i 5 -w 1 94 | \n 95 | ''' 96 | 97 | parser=MyParser(description=desc, formatter_class=RawTextHelpFormatter, epilog=example_text) 98 | parser.add_argument("destination", type=str, help="a DNS name, an IP address") 99 | parser.add_argument("-p", dest="port", type=int, default=80, help="a numeric TCP port, 1-65535. If not specified, defaults to 80.") 100 | parser.add_argument("-t", dest="is_continuously", action='store_true', help="ping continuously until stopped via control-c.") 101 | parser.add_argument("-n", dest="number", type=int, default=4, help="send count pings and then stop, default 4.") 102 | parser.add_argument("-i", dest="interval", type=int, default=1, help="wait seconds between pings, default 1.") 103 | parser.add_argument("-w", dest="wait", type=int, default=2, help="wait seconds for a response, default 2.") 104 | parser.add_argument("-v", "--version", action='version', version=VERSION, help="print version and exit.") 105 | args=parser.parse_args() 106 | 107 | ip = host2ip(args.destination) 108 | port = args.port 109 | if not ip: 110 | print("ERROR: Could not find host - %s, aborting" % args.destination) 111 | sys.exit(1) 112 | 113 | try: 114 | # continuously 115 | if args.is_continuously: 116 | print("") 117 | print("** Pinging continuously. Press control-c to stop **") 118 | print("") 119 | while True: 120 | results = tcp(ip, port, args.wait) 121 | # print format result 122 | print(format_tcp_result(results)) 123 | # start statistic 124 | statistic_tcp_result(results) 125 | 126 | time.sleep(args.interval) 127 | else: 128 | print("") 129 | for i in range(args.number): 130 | results = tcp(ip, port, args.wait) 131 | # print format result 132 | print(format_tcp_result(results)) 133 | # start statistic 134 | statistic_tcp_result(results) 135 | 136 | time.sleep(args.interval) 137 | except KeyboardInterrupt: 138 | print("Control-C") 139 | finally: 140 | format_statistic_results = ''' 141 | Ping statistics for {}, port {}: 142 | Probes: send = {}, success = {}, fail = {} ({}% fail) 143 | Approximate trip times: 144 | Minimum = {}ms, Maximum = {}ms, Average = {}ms 145 | '''.format(ip, port, ping_cnt, ping_success_cnt, ping_fail_cnt,round(ping_fail_cnt/float(ping_cnt)*100,2), ping_resp_min, ping_resp_max, ping_resp_avg) 146 | print(format_statistic_results) 147 | -------------------------------------------------------------------------------- /dependencies/tcping.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | if ! type tcping >/dev/null 2>&1; then 3 | wget https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/tcping -O /usr/bin/tcping 4 | chmod +x /usr/bin/tcping 5 | fi -------------------------------------------------------------------------------- /dependencies/tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | 4 | import time,urllib2,json,sys 5 | import shlex 6 | import datetime 7 | import subprocess 8 | 9 | reload(sys) 10 | sys.setdefaultencoding('utf-8') 11 | 12 | def GetIpipInfo(para): 13 | f = open("ip_json.json",'r') 14 | ijson = json.load(f) 15 | jjson = ijson['location'] 16 | print jjson[para.encode('utf-8')] 17 | 18 | def GetGeoioInfo(para): 19 | ip_api = urllib2.urlopen(r'http://ip-api.com/json') 20 | ijson = json.loads(ip_api.read()) 21 | print ijson[para.encode('utf-8')] 22 | 23 | def GetDiskInfo(para): 24 | temp = ExecShell("df -h -P|grep '/'|grep -v tmpfs")[0]; 25 | temp1 = temp.split('\n'); 26 | diskInfo = []; 27 | n = 0 28 | cuts = ['/mnt/cdrom','/boot','/boot/efi','/dev','/dev/shm','/run/lock','/run','/run/shm','/run/user']; 29 | for tmp in temp1: 30 | n += 1 31 | disk = tmp.split(); 32 | if len(disk) < 5: continue; 33 | if disk[1].find('M') != -1: continue; 34 | if disk[1].find('K') != -1: continue; 35 | if len(disk[5].split('/')) > 4: continue; 36 | if disk[5] in cuts: continue; 37 | arr = {} 38 | diskInfo = [disk[1],disk[2],disk[3],disk[4],disk[5]]; 39 | 40 | print(diskInfo[int(para)]); 41 | 42 | def ExecShell(cmdstring, cwd=None, timeout=None, shell=True): 43 | 44 | if shell: 45 | cmdstring_list = cmdstring 46 | else: 47 | cmdstring_list = shlex.split(cmdstring) 48 | if timeout: 49 | end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout) 50 | 51 | sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,shell=shell,bufsize=4096,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 52 | 53 | while sub.poll() is None: 54 | time.sleep(0.1) 55 | if timeout: 56 | if end_time <= datetime.datetime.now(): 57 | raise Exception("Timeout:%s"%cmdstring) 58 | 59 | return sub.communicate() 60 | 61 | if __name__ == "__main__": 62 | type = sys.argv[1]; 63 | if type == 'disk': 64 | GetDiskInfo(sys.argv[2]) 65 | elif type == 'geoip': 66 | GetGeoioInfo(sys.argv[2]) 67 | elif type == 'ipip': 68 | GetIpipInfo(sys.argv[2]) 69 | else: 70 | print 'ERROR: Parameter error' 71 | -------------------------------------------------------------------------------- /dependencies/xd.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" 3 | Info="${Green_font_prefix}[信息]${Font_color_suffix}" 4 | Error="${Red_font_prefix}[错误]${Font_color_suffix}" 5 | Tip="${Green_font_prefix}[注意]${Font_color_suffix}" 6 | 7 | function check_sys() 8 | { 9 | if [[ -f /etc/redhat-release ]]; then 10 | release="centos" 11 | elif cat /etc/issue | grep -q -E -i "debian"; then 12 | release="debian" 13 | elif cat /etc/issue | grep -q -E -i "ubuntu"; then 14 | release="ubuntu" 15 | elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat"; then 16 | release="centos" 17 | elif cat /proc/version | grep -q -E -i "debian"; then 18 | release="debian" 19 | elif cat /proc/version | grep -q -E -i "ubuntu"; then 20 | release="ubuntu" 21 | elif cat /proc/version | grep -q -E -i "centos|red hat|redhat"; then 22 | release="centos" 23 | fi 24 | bit=$(uname -m) 25 | if test "$bit" != "x86_64"; then 26 | bit='arm64' 27 | else bit="amd64" 28 | fi 29 | } 30 | function Installation_dependency(){ 31 | if [[ ${release} == "centos" ]]; then 32 | yum -y update && yum -y upgrade 33 | yum install -y wget 34 | yum -y install lsof 35 | yum -y install curl 36 | else 37 | apt-get -y update && apt-get -y upgrade 38 | apt-get install -y wget 39 | apt-get install -y lsof 40 | apt-get -y install curl 41 | fi 42 | if ! type docker >/dev/null 2>&1; then 43 | curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 44 | systemctl start docker 45 | systemctl enable docker 46 | fi 47 | } 48 | function check_root() 49 | { 50 | [[ $EUID != 0 ]] && echo -e "${Error} 当前非ROOT账号(或没有ROOT权限),无法继续操作,请更换ROOT账号或使用 ${Green_background_prefix}sudo su${Font_color_suffix} 命令获取临时ROOT权限(执行后可能会提示输入当前账号的密码)。" && exit 1 51 | } 52 | 53 | function install(){ 54 | num=1 55 | check_sys 56 | Installation_dependency 57 | rm -rf /etc/xdzz 58 | isInstall=1 59 | if [ -f /etc/xdzz/xd.mv.db ];then 60 | docker stop xiandan 61 | echo '已存在数据库,先帮你把数据备份至/etc/xdzz/back.xd.mv.db' 62 | cp -f /etc/xdzz/xd.mv.db /etc/xdzz/back.xd.mv.db 63 | fi 64 | wget -P /etc/xdzz http://sh.xdmb.xyz/xiandan/xd.mv.db 65 | wget -P /etc/xdzz http://sh.xdmb.xyz/xiandan/xd.trace.db 66 | read_port 67 | } 68 | 69 | function install_bot(){ 70 | check_sys 71 | Installation_dependency 72 | `rm -rf /etc/xdzz/bot_config` 73 | `mkdir /etc/xdzz/bot_config` 74 | echo -e "{}" > /etc/xdzz/bot_config/db.json 75 | echo -e "${Green_font_prefix}请输入访问面板地址" 76 | echo -e "${Green_font_prefix}-----------------------------------" 77 | read -p "请输入(默认:http://127.0.0.1:2080): " url 78 | echo -e "${Green_font_prefix}请输入BOT_TOKEN" 79 | echo -e "${Green_font_prefix}-----------------------------------" 80 | read -p "请输入(自行联系@BotFather获取): " botToken 81 | echo -e "${Green_font_prefix}请输入闲蛋ApiToken" 82 | echo -e "${Green_font_prefix}-----------------------------------" 83 | read -p "请输入(请前往面板系统设置页查看): " apiToken 84 | if [[ ! -n $url ]];then 85 | url="http://127.0.0.1:2080" 86 | fi 87 | if [[ ! -n $botToken ]];then 88 | echo -e "${Green_font_prefix}botToken没输入" 89 | exit 0 90 | fi 91 | if [[ ! -n $apiToken ]];then 92 | echo -e "${Green_font_prefix}apiToken没输入" 93 | exit 0 94 | fi 95 | echo -e "{" > /etc/xdzz/bot_config/domain.json 96 | echo -e "\t\"url\": \"${url}\"," >> /etc/xdzz/bot_config/domain.json 97 | echo -e "\t\"botToken\": \"${botToken}\"," >> /etc/xdzz/bot_config/domain.json 98 | echo -e "\t\"apiToken\": \"${apiToken}\"" >> /etc/xdzz/bot_config/domain.json 99 | echo -e "}" >> /etc/xdzz/bot_config/domain.json 100 | cat /etc/xdzz/bot_config/domain.json 101 | update_do_bot 102 | } 103 | 104 | function update(){ 105 | check_sys 106 | if [[ ! -n $port ]];then 107 | portinfo=`docker port xiandan | head -1` 108 | if [[ ! -n "$portinfo" ]];then 109 | read_port 110 | exit 0 111 | else 112 | port=${portinfo#*:} 113 | if [ -f /etc/xdzz/xd.mv.db ];then 114 | docker stop xiandan 115 | echo '先帮你把数据备份至/etc/xdzz/back.xd.mv.db' 116 | cp -f /etc/xdzz/xd.mv.db /etc/xdzz/back.xd.mv.db 117 | fi 118 | update_do 119 | fi 120 | else 121 | if [ -f /etc/xdzz/xd.mv.db ];then 122 | docker stop xiandan 123 | echo '先帮你把数据备份至/etc/xdzz/back.xd.mv.db' 124 | cp -f /etc/xdzz/xd.mv.db /etc/xdzz/back.xd.mv.db 125 | fi 126 | update_do 127 | fi 128 | } 129 | function update_bot(){ 130 | update_do_bot 131 | } 132 | function checkArea (){ 133 | echo -e "请选择面板机器所在区域(是否为国外环境)" 134 | echo "-----------------------------------" 135 | read -p "请输入(1:国外,2:国内, 默认:1): " isChina 136 | if [[ ! -n $isChina ]];then 137 | dns=8.8.8.8 138 | fi 139 | if [[ $isChina == 2 ]];then 140 | echo -e "您选择了国内环境,面板dns为:223.5.5.5" 141 | dns=223.5.5.5 142 | else 143 | echo -e "您选择了国外环境,面板dns为:8.8.8.8" 144 | dns=8.8.8.8 145 | fi 146 | echo $dns > /etc/xdzz/dns 147 | } 148 | 149 | function update_do(){ 150 | dns=`cat /etc/xdzz/dns` 151 | if [[ ! -n $dns ]];then 152 | checkArea 153 | fi 154 | systemctl restart docker 155 | version=`docker -v` 156 | restartTask=`crontab -l | grep xiandan` 157 | if [ "${restartTask}X" == "X" ];then 158 | if ! type crontab >/dev/null 2>&1; then 159 | check_sys 160 | if [[ ${release} == "centos" ]]; then 161 | yum install -y vixie-cron 162 | yum install -y crontabs 163 | else 164 | apt-get install -y cron 165 | fi 166 | service cron start 167 | fi 168 | restartTime=3 169 | crontab -l > conf 170 | sed -i '/xiandan/d' conf 171 | echo "0 0 ${restartTime} * * ? docker restart xiandan" >> conf 172 | crontab conf 173 | rm -f conf 174 | fi 175 | if ! type docker >/dev/null 2>&1; then 176 | wget -qO- https://get.docker.com/ | sh 177 | systemctl start docker 178 | fi 179 | if [[ ! -n "$vNum" ]];then 180 | vNum='latest' 181 | fi 182 | docker rm -f xiandan 183 | echo "dns为${dns}" 184 | echo "平台架构为${bit}" 185 | if [[ ${bit} == "arm64" ]]; then 186 | docker pull docker.xdmb.xyz/xiandan/release/arm:${vNum} 187 | docker run --platform linux/${bit} --log-opt max-size=10m --dns=${dns} --log-driver json-file --restart=always --name=xiandan -v /etc/xdzz:/xiandan -p ${port}:8080 -d docker.xdmb.xyz/xiandan/release/arm:${vNum} 188 | else 189 | docker pull docker.xdmb.xyz/xiandan/release:${vNum} 190 | docker run --platform linux/${bit} --log-opt max-size=10m --dns=${dns} --log-driver json-file --restart=always --name=xiandan -v /etc/xdzz:/xiandan -p ${port}:8080 -d docker.xdmb.xyz/xiandan/release:${vNum} 191 | fi 192 | ip=`curl -4 ip.sb` 193 | echo -e "${Green_font_prefix}闲蛋面板已安装成功!请等待1-2分钟后访问面板入口。${Font_color_suffix}" 194 | echo -e "${Green_font_prefix}访问入口为 $ip:${port} ${Font_color_suffix}" 195 | } 196 | 197 | function update_do_bot { 198 | check_sys 199 | docker rm -f xd-bot 200 | docker pull docker.xdmb.xyz/xiandan/bot:latest 201 | docker run --platform linux/${bit} --name xd-bot --network host --restart=always -v /etc/xdzz/bot_config:/usr/src/app/bot_config -d docker.xdmb.xyz/xiandan/bot:latest 202 | exit 0 203 | } 204 | 205 | function uninstall(){ 206 | rm -rf /etc/xdzz 207 | docker rm -f xiandan 208 | echo -e "${Green_font_prefix}闲蛋已成功卸载${Font_color_suffix}" 209 | } 210 | 211 | function uninstall_bot(){ 212 | rm -rf /etc/xdzz/bot_config 213 | docker rm -f xd-bot 214 | echo -e "${Green_font_prefix}闲蛋BOT已成功卸载${Font_color_suffix}" 215 | } 216 | 217 | function start(){ 218 | portinfo=`docker ps -a |grep xiandan` 219 | if [[ ! -n "$portinfo" ]];then 220 | echo -e "${Green_font_prefix}面板未安装,请安装面板!${Font_color_suffix}" 221 | else 222 | docker start xiandan 223 | echo -e "${Green_font_prefix}已启动${Font_color_suffix}" 224 | fi 225 | } 226 | function start_bot(){ 227 | portinfo=`docker ps -a |grep xd-bot` 228 | if [[ ! -n "$portinfo" ]];then 229 | echo -e "${Green_font_prefix}BOT未安装,请安装!${Font_color_suffix}" 230 | else 231 | docker start xd-bot 232 | echo -e "${Green_font_prefix}已启动${Font_color_suffix}" 233 | fi 234 | } 235 | function stop() 236 | { 237 | portinfo=`docker ps -a |grep xiandan` 238 | if [[ ! -n "$portinfo" ]];then 239 | echo -e "${Green_font_prefix}面板未安装,请安装面板!${Font_color_suffix}" 240 | else 241 | docker stop xiandan 242 | echo -e "${Green_font_prefix}已停止${Font_color_suffix}" 243 | fi 244 | } 245 | function stop_bot() { 246 | portinfo=`docker ps -a |grep xd-bot` 247 | if [[ ! -n "$portinfo" ]];then 248 | echo -e "${Green_font_prefix}BOT未安装,请安装!${Font_color_suffix}" 249 | else 250 | docker stop xd-bot 251 | echo -e "${Green_font_prefix}已停止${Font_color_suffix}" 252 | fi 253 | } 254 | function restart(){ 255 | portinfo=`docker ps -a |grep xiandan` 256 | if [[ ! -n "$portinfo" ]];then 257 | echo -e "${Green_font_prefix}面板未安装,请安装面板!${Font_color_suffix}" 258 | else 259 | docker restart xiandan 260 | echo -e "${Green_font_prefix}已重启${Font_color_suffix}" 261 | fi 262 | } 263 | 264 | function restart_bot(){ 265 | portinfo=`docker ps -a |grep xd-bot` 266 | if [[ ! -n "$portinfo" ]];then 267 | echo -e "${Green_font_prefix}BOT未安装,请安装!${Font_color_suffix}" 268 | else 269 | docker restart xd-bot 270 | echo -e "${Green_font_prefix}已重启${Font_color_suffix}" 271 | fi 272 | } 273 | 274 | function restore(){ 275 | rm -rf /etc/xdzz 276 | wget -P /etc/xdzz http://sh.xdmb.xyz/xiandan/xd.mv.db 277 | wget -P /etc/xdzz http://sh.xdmb.xyz/xiandan/xd.trace.db 278 | restart 279 | } 280 | function reset(){ 281 | str=`docker ps | grep xiandan` 282 | if [[ ! -n "$str" ]];then 283 | echo -e "${Green_font_prefix}面板未运行${Font_color_suffix}" 284 | exit 0 285 | fi 286 | bash <(wget --no-check-certificate -qO- 'https://sh.xdmb.xyz/xiandan/reset.sh') 287 | echo -e "${Green_font_prefix}超级管理员已重置为admin / admin${Font_color_suffix}" 288 | } 289 | function read_port(){ 290 | echo -e "请输入面板映射端口(面板访问端口)" 291 | echo "-----------------------------------" 292 | read -p "请输入(1-65535, 默认:80): " port 293 | if [[ ! -n $port ]];then 294 | port=80 295 | fi 296 | if [ "$port" -gt 0 ] 2>/dev/null;then 297 | if [[ $port -lt 0 || $port -gt 65535 ]];then 298 | echo -e "端口号不正确" 299 | read_port 300 | exit 0 301 | fi 302 | isUsed=`lsof -i:${port}` 303 | if [ -n "$isUsed" ];then 304 | echo -e "端口被占用" 305 | read_port 306 | exit 0 307 | fi 308 | update 309 | else 310 | read_port 311 | exit 0 312 | fi 313 | } 314 | function rollback() { 315 | echo -e "请输入特定版本号" 316 | echo "-----------------------------------" 317 | read -p "请输入一个可用的版本号: " vNum 318 | update 319 | } 320 | function autoRestart() { 321 | if ! type crontab >/dev/null 2>&1; then 322 | echo '安装crontab'; 323 | check_sys 324 | if [[ ${release} == "centos" ]]; then 325 | yum install -y vixie-cron 326 | yum install -y crontabs 327 | else 328 | apt-get install -y cron 329 | fi 330 | service cron start 331 | fi 332 | read -p "请输入(0-23, 默认:3): " restartTime 333 | if [[ ! -n $restartTime ]];then 334 | restartTime=3 335 | fi 336 | if [[ $restartTime -lt 0 || $restartTime -gt 23 ]];then 337 | echo -e "请输入正确数字" 338 | exit 0 339 | fi 340 | crontab -l > conf 341 | sed -i '/xiandan/d' conf 342 | echo "0 0 ${restartTime} * * ? docker restart xiandan" >> conf 343 | crontab conf 344 | rm -f conf 345 | echo -e "定时任务设置成功!每天${restartTime}点重启面板" 346 | } 347 | function auto() { 348 | check_root 349 | echo && echo -e "${Green_font_prefix} 闲蛋面板 一键脚本 350 | ${Green_font_prefix} ----------- Noob_Cfy ----------- 351 | ${Green_font_prefix}1. 安装 闲蛋面板 352 | ${Green_font_prefix}2. 更新 闲蛋面板 353 | ${Green_font_prefix}3. 卸载 闲蛋面板 354 | ———————————— 355 | ${Green_font_prefix}4. 启动 闲蛋面板 356 | ${Green_font_prefix}5. 停止 闲蛋面板 357 | ${Green_font_prefix}6. 重启 闲蛋面板 358 | ———————————— 359 | ${Green_font_prefix}7. 数据库还原 360 | ${Green_font_prefix}8. 管理员用户名密码重置 361 | ${Green_font_prefix}9. 安装特定版本 362 | ${Green_font_prefix}10. 设置自动重启 363 | ———————————— 364 | ${Green_font_prefix}11. 安装 TG_BOT 365 | ${Green_font_prefix}12. 更新 TG_BOT 366 | ${Green_font_prefix}13. 卸载 TG_BOT 367 | ———————————— 368 | ${Green_font_prefix}14. 启动 TG_BOT 369 | ${Green_font_prefix}15. 停止 TG_BOT 370 | ${Green_font_prefix}16. 重启 TG_BOT 371 | ———————————— 372 | ${Green_font_prefix}0. 退出脚本 373 | ———————————— ${Font_color_suffix}" && echo 374 | read -e -p " 请输入数字 [1-10]:" num 375 | case "$num" in 376 | 1) 377 | install 378 | ;; 379 | 2) 380 | update 381 | ;; 382 | 3) 383 | uninstall 384 | ;; 385 | 4) 386 | start 387 | ;; 388 | 5) 389 | stop 390 | ;; 391 | 6) 392 | restart 393 | ;; 394 | 7) 395 | restore 396 | ;; 397 | 8) 398 | reset 399 | ;; 400 | 9) 401 | rollback 402 | ;; 403 | 10) 404 | autoRestart 405 | ;; 406 | 11) 407 | install_bot 408 | ;; 409 | 12) 410 | update_bot 411 | ;; 412 | 13) 413 | uninstall_bot 414 | ;; 415 | 14) 416 | start_bot 417 | ;; 418 | 15) 419 | stop_bot 420 | ;; 421 | 16) 422 | restart_bot 423 | ;; 424 | 0) 425 | exit 0 426 | ;; 427 | *) 428 | echo "请输入正确数字 [1-10]" 429 | ;; 430 | esac 431 | } 432 | 433 | if [ $# -gt 0 ] ; then 434 | if [ $1 == "install" ]; then 435 | install 436 | elif [ $1 == "start" ]; then 437 | start 438 | elif [ $1 == "stop" ]; then 439 | stop 440 | elif [ $1 == "update" ]; then 441 | update 442 | elif [ $1 == "uninstall" ]; then 443 | uninstall 444 | fi 445 | else 446 | auto; 447 | fi -------------------------------------------------------------------------------- /shbox.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 3 | export PATH 4 | Green_font="\033[32m" && Red_font="\033[31m" && Font_suffix="\033[0m" 5 | Info="${Green_font}[Info]${Font_suffix}" 6 | Error="${Red_font}[Error]${Font_suffix}" 7 | echo -e "${Green_font} 8 | #====================================== 9 | # Project: shbox 10 | # Version: 0.0.3 11 | # 推荐机场: 垃圾场加速器 12 | # 注册地址: https://lajic.eu/index.php#/register?code=OAM8uBQl 13 | #====================================== 14 | ${Font_suffix}" 15 | 16 | check_root(){ 17 | [[ "`id -u`" != "0" ]] && echo -e "${Error} must be root user !" && exit 1 18 | } 19 | 20 | first(){ 21 | 22 | apt update -y 23 | apt install -y git tmux screen nano vim curl net-tools wget sudo proxychains iperf3 lsof conntrack openssl unzip lsb-release jq ca-certificates bash-completion iptables netcat-openbsd && update-ca-certificates 24 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/tcping.sh) 25 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/bashrc.sh) 26 | git clone https://ghproxy.com/https://github.com/iiiiiii1/doubi.git 27 | git clone https://ghproxy.com/https://github.com/hulisang/Port-forwarding.git 28 | git clone https://ghproxy.com/https://github.com/vpsxb/EasyRealM.git 29 | git clone https://ghproxy.com/https://github.com/seal0207/EasyRealM.git 30 | bash <(curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/P3TERX/script/master/speedtest-cli.sh) 31 | apt install python python3-pip -y 32 | 33 | } 34 | 35 | doc(){ 36 | 37 | wget -qO- get.docker.com | bash 38 | 39 | } 40 | 41 | proxy(){ 42 | select_proxy 43 | set_proxy 44 | } 45 | 46 | select_proxy(){ 47 | echo -e "${Info} 选择需要安装魔法: \n1.multi-v2ray\n2.x-ui\n3.docker版x-ui\n4.docker版v2ray(需自行修改配置文件)\n5.docker版xray(需自行修改配置文件)" 48 | read -p "输入数字以选择:" kxsw 49 | 50 | while [[ ! "${kxsw}" =~ ^[1-5]$ ]] 51 | do 52 | echo -e "${Error} 无效输入" 53 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" kxsw 54 | done 55 | } 56 | 57 | set_proxy(){ 58 | [[ "${kxsw}" == "1" ]] && multi-v2ray 59 | [[ "${kxsw}" == "2" ]] && x-ui 60 | [[ "${kxsw}" == "3" ]] && x-ui-docker 61 | [[ "${kxsw}" == "4" ]] && v2ray-docker 62 | [[ "${kxsw}" == "5" ]] && xray-docker 63 | } 64 | 65 | multi-v2ray(){ 66 | 67 | source <(curl -fsSL https://raw.githubusercontent.com/Jrohy/multi-v2ray/master/v2ray.sh) --zh 68 | 69 | } 70 | 71 | x-ui(){ 72 | 73 | bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh) 74 | 75 | } 76 | 77 | x-ui-docker(){ 78 | 79 | docker run -itd --network=host -v /root/x-ui/db/:/etc/x-ui/ -v /root/x-ui/cert/:/root/cert/ --name x-ui --restart=unless-stopped enwaiax/x-ui:latest 80 | 81 | } 82 | 83 | v2ray-docker(){ 84 | 85 | mkdir -p /root/v2ray 86 | wget -O /root/v2ray/config.json https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/config-v2ray.json 87 | docker run -d --network host --name v2ray --restart=always -v /root/v2ray:/etc/v2ray teddysun/v2ray 88 | 89 | } 90 | 91 | xray-docker(){ 92 | 93 | mkdir -p /root/xray 94 | wget -O /root/xray/config.json https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/config-xray.json 95 | docker run -d --network host --name xray --restart=always -v /root/xray:/etc/xray teddysun/xray 96 | 97 | } 98 | 99 | hc(){ 100 | 101 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/jcnf.sh) 102 | 103 | } 104 | 105 | ihc(){ 106 | 107 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/ijcnf.sh) 108 | 109 | } 110 | 111 | tcpx(){ 112 | 113 | bash <(curl -fsSL https://git.io/JYxKU) 114 | 115 | } 116 | 117 | ddxt(){ 118 | 119 | bash <(curl -fsSL https://raw.githubusercontent.com/hiCasper/Shell/master/AutoReinstall.sh) 120 | 121 | } 122 | 123 | nfcheck(){ 124 | 125 | bash <(curl -fsSL https://raw.githubusercontent.com/lmc999/RegionRestrictionCheck/main/check.sh) 126 | 127 | } 128 | 129 | yabs(){ 130 | 131 | bash <(curl -fsSL yabs.sh) 132 | 133 | } 134 | 135 | lb(){ 136 | 137 | curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/LemonBench.sh | bash -s fast 138 | 139 | } 140 | 141 | superbench(){ 142 | 143 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/superbench.sh) 144 | 145 | } 146 | 147 | speed(){ 148 | 149 | curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/superbench.sh | bash -s speed 150 | 151 | } 152 | 153 | io(){ 154 | 155 | curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/superbench.sh | bash -s io 156 | 157 | } 158 | 159 | ipcheck(){ 160 | 161 | curl ip.p3terx.com -4 162 | curl ip.p3terx.com -6 163 | 164 | } 165 | 166 | tz(){ 167 | 168 | bash <(curl -fsSL https://raw.githubusercontent.com/cokemine/ServerStatus-Hotaru/master/status.sh) 169 | 170 | } 171 | 172 | jg(){ 173 | 174 | bash <(curl -fsSL https://raw.githubusercontent.com/Aurora-Admin-Panel/deploy/main/install.sh) 175 | 176 | } 177 | 178 | xd(){ 179 | 180 | bash <(curl -fsSL https://sh.xdmb.xyz/xiandan/xd.sh) 181 | 182 | } 183 | 184 | lnmps(){ 185 | select_alternative 186 | set_alternative 187 | } 188 | 189 | select_alternative(){ 190 | echo -e "${Info} 选择需要安装的lnmp: \n1.宝塔\n2.LNMP\n3.oneinstack\n4.aapanel" 191 | read -p "输入数字以选择:" lnmp 192 | 193 | while [[ ! "${lnmp}" =~ ^[1-4]$ ]] 194 | do 195 | echo -e "${Error} 无效输入" 196 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" lnmp 197 | done 198 | } 199 | 200 | set_alternative(){ 201 | [[ "${lnmp}" == "1" ]] && bt 202 | [[ "${lnmp}" == "2" ]] && lnmp 203 | [[ "${lnmp}" == "3" ]] && oneinstack 204 | [[ "${lnmp}" == "4" ]] && aapanel 205 | } 206 | 207 | bt(){ 208 | 209 | bash <(curl -fsSL http://download.bt.cn/install/install-ubuntu_6.0.sh) 210 | 211 | } 212 | 213 | aapanel(){ 214 | 215 | wget -O install.sh http://www.aapanel.com/script/install-ubuntu_6.0_en.sh && bash install.sh aapanel 216 | 217 | } 218 | 219 | lnmp(){ 220 | 221 | apt update -y && apt-get -y install wget screen #for Debian/Ubuntu 222 | wget http://soft.vpser.net/lnmp/lnmp1.9beta.tar.gz -cO lnmp1.9beta.tar.gz && tar zxf lnmp1.9beta.tar.gz 223 | rm zxf lnmp1.9beta.tar.gz -rf && cd lnmp1.9 224 | screen ./install.sh 225 | 226 | } 227 | 228 | oneinstack(){ 229 | 230 | apt update -y && apt-get -y install wget screen #for Debian/Ubuntu 231 | wget http://mirrors.linuxeye.com/oneinstack-full.tar.gz -cO oneinstack-full.tar.gz 232 | tar xzf oneinstack-full.tar.gz && rm oneinstack-full.tar.gz -rf 233 | cd oneinstack #如果需要修改目录(安装、数据存储、Nginx日志),请修改options.conf文件 234 | screen ./install.sh 235 | 236 | } 237 | 238 | update_debian(){ 239 | 240 | bash <(curl -sSL https://raw.githubusercontent.com/wikihost-opensource/linux-toolkit/main/system-upgrade/debian.sh) 241 | 242 | } 243 | 244 | check_root 245 | 246 | echo -e "${Info} 选择你要使用的功能: " 247 | echo -e "1.首次运行\n2.安装docker\n3.安装bbr\n4.魔法上网\n5.回程路由(TCP)\n6.回程路由(ICMP)\n7.流媒体测试\n8.superbench\n9.yabs\n10.LemonBench\n11.IO测试\n12.全网测速\n13.探针安装\n14.本地IP\n15.极光面板\n16.闲蛋面板\n17.DD系统\n18.建站环境\n19.升级Debian(自动执行谨慎操作)" 248 | read -p "输入数字以选择:" function 249 | 250 | while [[ ! "${function}" =~ ^([1-9]|1[0-9])$ ]] 251 | do 252 | echo -e "${Error} 缺少或无效输入" 253 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" function 254 | done 255 | 256 | if [[ "${function}" == "1" ]]; then 257 | first 258 | elif [[ "${function}" == "2" ]]; then 259 | doc 260 | elif [[ "${function}" == "3" ]]; then 261 | tcpx 262 | elif [[ "${function}" == "4" ]]; then 263 | proxy 264 | elif [[ "${function}" == "5" ]]; then 265 | hc 266 | elif [[ "${function}" == "6" ]]; then 267 | ihc 268 | elif [[ "${function}" == "7" ]]; then 269 | nfcheck 270 | elif [[ "${function}" == "8" ]]; then 271 | superbench 272 | elif [[ "${function}" == "9" ]]; then 273 | yabs 274 | elif [[ "${function}" == "10" ]]; then 275 | lb 276 | elif [[ "${function}" == "11" ]]; then 277 | io 278 | elif [[ "${function}" == "12" ]]; then 279 | speed 280 | elif [[ "${function}" == "13" ]]; then 281 | tz 282 | elif [[ "${function}" == "14" ]]; then 283 | ipcheck 284 | elif [[ "${function}" == "15" ]]; then 285 | jg 286 | elif [[ "${function}" == "16" ]]; then 287 | xd 288 | elif [[ "${function}" == "17" ]]; then 289 | ddxt 290 | elif [[ "${function}" == "18" ]]; then 291 | lnmps 292 | elif [[ "${function}" == "19" ]]; then 293 | update_debian 294 | else 295 | echo -e "${Info} 请重新选择" && read -p "输入数字选择:" function 296 | fi 297 | -------------------------------------------------------------------------------- /shbox.sh.old: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 3 | export PATH 4 | Green_font="\033[32m" && Red_font="\033[31m" && Font_suffix="\033[0m" 5 | Info="${Green_font}[Info]${Font_suffix}" 6 | Error="${Red_font}[Error]${Font_suffix}" 7 | echo -e "${Green_font} 8 | #====================================== 9 | # Project: shbox 10 | # Version: 0.0.1 11 | # Blog: https://vpsxb.net/1642/ 12 | # usage: bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/shbox.sh) 13 | #====================================== 14 | ${Font_suffix}" 15 | 16 | check_root(){ 17 | [[ "`id -u`" != "0" ]] && echo -e "${Error} must be root user !" && exit 1 18 | } 19 | 20 | first(){ 21 | 22 | apt update -y 23 | apt install git tmux nano vim curl net-tools wget sudo proxychains iperf3 lsof conntrack openssl unzip lsb-release jq ca-certificates python iptables -y && update-ca-certificates 24 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/tcping.sh) 25 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/bashrc.sh) 26 | git clone https://github.com/ToyoDAdoubi/doubi.git 27 | git clone https://github.com/hulisang/Port-forwarding.git 28 | git clone https://github.com/KANIKIG/Multi-EasyGost.git 29 | git clone https://github.com/seal0207/EasyRealM.git 30 | bash <(curl -fsSL git.io/speedtest-cli.sh) 31 | 32 | } 33 | 34 | doc(){ 35 | 36 | wget -qO- get.docker.com | bash 37 | 38 | } 39 | 40 | multi-v2ray(){ 41 | 42 | source <(curl -fsSL https://raw.githubusercontent.com/Jrohy/multi-v2ray/master/v2ray.sh) --zh 43 | 44 | } 45 | 46 | x-ui(){ 47 | 48 | bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh) 49 | 50 | } 51 | 52 | x-ui-docker(){ 53 | 54 | docker run -itd --network=host -v /root/x-ui/db/:/etc/x-ui/ -v /root/x-ui/cert/:/root/cert/ --name x-ui --restart=unless-stopped enwaiax/x-ui:latest 55 | 56 | } 57 | 58 | hc(){ 59 | 60 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/jcnf.sh) 61 | 62 | } 63 | 64 | tcpx(){ 65 | 66 | bash <(curl -fsSL https://git.io/JYxKU) 67 | 68 | } 69 | 70 | ddxt(){ 71 | 72 | bash <(curl -fsSL https://raw.githubusercontent.com/hiCasper/Shell/master/AutoReinstall.sh) 73 | 74 | } 75 | 76 | nfcheck(){ 77 | 78 | bash <(curl -fsSL https://raw.githubusercontent.com/lmc999/RegionRestrictionCheck/main/check.sh) 79 | 80 | } 81 | 82 | yabs(){ 83 | 84 | bash <(curl -fsSL yabs.sh) 85 | 86 | } 87 | 88 | lb(){ 89 | 90 | curl -fsSL http://ilemonra.in/LemonBenchIntl | bash -s fast 91 | 92 | } 93 | 94 | superbench(){ 95 | 96 | bash <(curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/superbench.sh) 97 | 98 | } 99 | 100 | speed(){ 101 | 102 | curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/superbench.sh | bash -s speed 103 | 104 | } 105 | 106 | io(){ 107 | 108 | curl -fsSL https://raw.githubusercontent.com/jamespan2012/shbox/main/dependencies/superbench.sh | bash -s io 109 | 110 | } 111 | 112 | ipcheck(){ 113 | 114 | curl ip.p3terx.com -4 115 | curl ip.p3terx.com -6 116 | 117 | } 118 | 119 | tz(){ 120 | 121 | bash <(curl -fsSL https://raw.githubusercontent.com/cokemine/ServerStatus-Hotaru/master/status.sh) 122 | 123 | } 124 | 125 | jg(){ 126 | 127 | bash <(curl -fsSL https://raw.githubusercontent.com/Aurora-Admin-Panel/deploy/main/install.sh) 128 | 129 | } 130 | 131 | xd(){ 132 | 133 | bash <(curl -fsSL https://sh.xdmb.xyz/xiandan/xd.sh) 134 | 135 | } 136 | 137 | check_root 138 | 139 | echo -e "${Info} 选择你要使用的功能: " 140 | echo -e "1.首次运行\n2.安装docker\n3.安装bbr\n4.回程路由\n5.安装multi-v2ray\n6.安装x-ui\n7.安装docker版x-ui\n8.流媒体测试\n9.superbench\n10.yabs\n11.LemonBench\n12.IO测试\n13.全网测速\n14.探针安装\n15.本地IP\n16.极光面板\n17.闲蛋面板\n18.DD系统" 141 | read -p "输入数字以选择:" function 142 | 143 | while [[ ! "${function}" =~ ^([1-9]|1[0-8])$ ]] 144 | do 145 | echo -e "${Error} 缺少或无效输入" 146 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" function 147 | done 148 | 149 | if [[ "${function}" == "1" ]]; then 150 | first 151 | elif [[ "${function}" == "2" ]]; then 152 | doc 153 | elif [[ "${function}" == "3" ]]; then 154 | tcpx 155 | elif [[ "${function}" == "4" ]]; then 156 | hc 157 | elif [[ "${function}" == "5" ]]; then 158 | multi-v2ray 159 | elif [[ "${function}" == "6" ]]; then 160 | x-ui 161 | elif [[ "${function}" == "7" ]]; then 162 | x-ui-docker 163 | elif [[ "${function}" == "8" ]]; then 164 | nfcheck 165 | elif [[ "${function}" == "9" ]]; then 166 | superbench 167 | elif [[ "${function}" == "10" ]]; then 168 | yabs 169 | elif [[ "${function}" == "11" ]]; then 170 | lb 171 | elif [[ "${function}" == "12" ]]; then 172 | io 173 | elif [[ "${function}" == "13" ]]; then 174 | speed 175 | elif [[ "${function}" == "14" ]]; then 176 | tz 177 | elif [[ "${function}" == "15" ]]; then 178 | ipcheck 179 | elif [[ "${function}" == "16" ]]; then 180 | jg 181 | elif [[ "${function}" == "17" ]]; then 182 | xd 183 | elif [[ "${function}" == "18" ]]; then 184 | ddxt 185 | else 186 | echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" function 187 | fi 188 | --------------------------------------------------------------------------------