mirror of
				https://github.com/oneclickvirt/ecs.git
				synced 2025-10-31 10:56:37 +08:00 
			
		
		
		
	Compare commits
	
		
			42 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 110e6d34f9 | ||
|   | 4d18497dd3 | ||
|   | c676cd83cb | ||
|   | 58e1de4487 | ||
|   | 89eecd2acc | ||
|   | 194dee49fd | ||
|   | 1e88513b8e | ||
|   | f84023d18b | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 2cfd5af3c0 | ||
|   | ed66e2804a | ||
|   | 174bf303af | ||
|   | b75f42ffe5 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 56b71ac53f | ||
|   | 1045d3fab8 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 7bd2b59d58 | ||
|   | cc1da7ea7c | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 1a002a1681 | ||
|   | ee2b55e7eb | ||
|   | a55cebf94b | ||
|   | 0571a8df13 | ||
|   | f29a2829f3 | ||
|   | 33b8e0396f | ||
|   | c259073d1b | ||
|   | 07ebc8cab5 | ||
|   | 1824051e53 | ||
|   | 9f93a2e59d | ||
|   | 8cd09182da | ||
|   | 9bb776d411 | ||
|   | 12f2da9da2 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 7aa70ac1fd | ||
|   | 04ce926582 | ||
|   | 73eb38eed1 | ||
|   | 9bc8a934b1 | ||
|   | 7b729e073b | ||
|   | 111126ae90 | ||
|   | 9397f789be | ||
|   | 5a1dda6483 | ||
|   | e322c717c0 | ||
|   | 778b33142b | ||
|   | aa9f361380 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 3236c60359 | ||
|   | 73b0f30ddc | 
							
								
								
									
										14
									
								
								.back/OldFunction.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.back/OldFunction.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | // clearScreen 清屏 | ||||||
|  | func clearScreen() { | ||||||
|  | 	var cmd *exec.Cmd | ||||||
|  | 	switch runtime.GOOS { | ||||||
|  | 	case "windows": | ||||||
|  | 		cmd = exec.Command("cmd", "/c", "cls") | ||||||
|  | 	case "darwin": | ||||||
|  | 		cmd = exec.Command("clear") | ||||||
|  | 	default: | ||||||
|  | 		cmd = exec.Command("clear") | ||||||
|  | 	} | ||||||
|  | 	cmd.Stdout = os.Stdout | ||||||
|  | 	_ = cmd.Run() | ||||||
|  | } | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| package backtrace |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/oneclickvirt/backtrace/bk" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func BackTrace(enableIpv6 bool) { |  | ||||||
| 	backtrace.BackTrace(enableIpv6) |  | ||||||
| } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| package backtrace |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| //func TestGeneratePrefixMap(t *testing.T) { |  | ||||||
| //	prefix := "223.119.8.0/21" |  | ||||||
| //	prefixList := GeneratePrefixList(prefix) |  | ||||||
| //	if prefixList != nil { |  | ||||||
| //		// 打印生成的IP地址前缀列表 |  | ||||||
| //		for _, ip := range prefixList { |  | ||||||
| //			fmt.Println(ip) |  | ||||||
| //		} |  | ||||||
| //	} |  | ||||||
| //} |  | ||||||
|  |  | ||||||
| // 本包仅测试,无实际使用 |  | ||||||
| func TestBackTrace(t *testing.T) { |  | ||||||
| 	BackTrace(false) |  | ||||||
| } |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| package ntrace |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/oneclickvirt/nt3/nt" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func TraceRoute3(language, location, checkType string) { |  | ||||||
| 	nt.TraceRoute(language, location, checkType) |  | ||||||
| } |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| package ntrace |  | ||||||
|  |  | ||||||
| import "testing" |  | ||||||
|  |  | ||||||
| // https://github.com/nxtrace/NTrace-core/blob/main/fast_trace/fast_trace.go |  | ||||||
| // 本包仅测试无实际使用 |  | ||||||
| func TestTraceRoute(t *testing.T) { |  | ||||||
| 	TraceRoute3("en", "GZ", "ipv4") |  | ||||||
| } |  | ||||||
							
								
								
									
										17
									
								
								.github/workflows/build_docker.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/build_docker.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -1,33 +1,30 @@ | |||||||
| name: Build and Push Docker Image | name: Build and Push Docker Image | ||||||
|  |  | ||||||
| on: | on: | ||||||
|   workflow_run: |   workflow_run: | ||||||
|     workflows: ["Build and Release"] |     workflows: ["Build and Release"] | ||||||
|     types: |     types: | ||||||
|       - completed |       - completed | ||||||
|   workflow_dispatch: |   workflow_dispatch: | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   build: |   build: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|  |     permissions: | ||||||
|  |       contents: read | ||||||
|  |       packages: write | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout repository |       - name: Checkout repository | ||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|  |  | ||||||
|       - name: Set up QEMU |       - name: Set up QEMU | ||||||
|         uses: docker/setup-qemu-action@v2 |         uses: docker/setup-qemu-action@v2 | ||||||
|         with: |         with: | ||||||
|           platforms: all |           platforms: all | ||||||
|  |  | ||||||
|       - name: Set up Docker Buildx |       - name: Set up Docker Buildx | ||||||
|         uses: docker/setup-buildx-action@v2 |         uses: docker/setup-buildx-action@v2 | ||||||
|  |  | ||||||
|       - name: Log in to Docker Hub |       - name: Log in to Docker Hub | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v2 | ||||||
|         with: |         with: | ||||||
|           username: ${{ secrets.DOCKER_USERNAME }} |           username: ${{ secrets.DOCKER_USERNAME }} | ||||||
|           password: ${{ secrets.DOCKER_PASSWORD }} |           password: ${{ secrets.DOCKER_PASSWORD }} | ||||||
|  |  | ||||||
|       # - name: Login to CNB Registry |       # - name: Login to CNB Registry | ||||||
|       #   uses: docker/login-action@v2 |       #   uses: docker/login-action@v2 | ||||||
|       #   with: |       #   with: | ||||||
| @@ -42,6 +39,13 @@ jobs: | |||||||
|           username: ${{ secrets.ALIYUN_USERNAME }} |           username: ${{ secrets.ALIYUN_USERNAME }} | ||||||
|           password: ${{ secrets.ALIYUN_PASSWORD }} |           password: ${{ secrets.ALIYUN_PASSWORD }} | ||||||
|        |        | ||||||
|  |       - name: Log in to GitHub Container Registry | ||||||
|  |         uses: docker/login-action@v2 | ||||||
|  |         with: | ||||||
|  |           registry: ghcr.io | ||||||
|  |           username: ${{ github.actor }} | ||||||
|  |           password: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |        | ||||||
|       - name: Build and push Docker images |       - name: Build and push Docker images | ||||||
|         uses: docker/build-push-action@v4 |         uses: docker/build-push-action@v4 | ||||||
|         with: |         with: | ||||||
| @@ -54,3 +58,4 @@ jobs: | |||||||
|           tags: | |           tags: | | ||||||
|             ${{ secrets.DOCKER_USERNAME }}/goecs:latest |             ${{ secrets.DOCKER_USERNAME }}/goecs:latest | ||||||
|             crpi-8tmognxgyb86bm61.cn-guangzhou.personal.cr.aliyuncs.com/oneclickvirt/ecs:latest |             crpi-8tmognxgyb86bm61.cn-guangzhou.personal.cr.aliyuncs.com/oneclickvirt/ecs:latest | ||||||
|  |             ghcr.io/${{ github.repository_owner }}/goecs:latest | ||||||
|   | |||||||
							
								
								
									
										108
									
								
								.github/workflows/build_public.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								.github/workflows/build_public.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | |||||||
|  | name: Public Build | ||||||
|  | on: | ||||||
|  |   workflow_run: | ||||||
|  |     workflows: ["Build and Release"] | ||||||
|  |     types: | ||||||
|  |       - completed | ||||||
|  |   workflow_dispatch: | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |      | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v4 | ||||||
|  |       with: | ||||||
|  |         fetch-depth: 0 | ||||||
|  |     - name: Set up Go | ||||||
|  |       uses: actions/setup-go@v5 | ||||||
|  |       with: | ||||||
|  |         go-version: '1.24.5' | ||||||
|  |          | ||||||
|  |     - name: Update master branch README files | ||||||
|  |       run: | | ||||||
|  |         git config --global user.name 'GitHub Actions' | ||||||
|  |         git config --global user.email 'actions@github.com' | ||||||
|  |          | ||||||
|  |         if [ -f "go.mod" ]; then | ||||||
|  |           GO_VERSION=$(grep "^go " go.mod | head -n 1 | awk '{print $2}') | ||||||
|  |           echo "提取到的 Go 版本: $GO_VERSION" | ||||||
|  |           if [ -n "$GO_VERSION" ] && [[ "$GO_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then | ||||||
|  |             echo "版本验证成功,开始替换..." | ||||||
|  |             if [ -f "README.md" ]; then | ||||||
|  |               sed -i "s/选择 go [0-9]\+\.[0-9]\+\.[0-9]\+ 的版本进行安装/选择 go $GO_VERSION 的版本进行安装/g" README.md | ||||||
|  |               sed -i 's|但二进制文件编译至 \[securityCheck\].*)|但已开源|g' README.md | ||||||
|  |               sed -i 's|security.*Enable/Disable security test (default true)|security        Enable/Disable security test (default false)|g' README.md | ||||||
|  |               echo "已更新 README.md" | ||||||
|  |             fi | ||||||
|  |             if [ -f "README_EN.md" ]; then | ||||||
|  |               sed -i "s/Select go [0-9]\+\.[0-9]\+\.[0-9]\+ version to install/Select go $GO_VERSION version to install/g" README_EN.md | ||||||
|  |               sed -i 's|but binary files compiled in \[securityCheck\].*)|but open sourced|g' README_EN.md | ||||||
|  |               sed -i 's|security.*Enable/Disable security test (default true)|security        Enable/Disable security test (default false)|g' README_EN.md | ||||||
|  |               echo "已更新 README_EN.md" | ||||||
|  |             fi | ||||||
|  |             git add README.md README_EN.md | ||||||
|  |             git commit -m "Auto update README files" || echo "No changes to commit" | ||||||
|  |             git push origin ${{ github.ref_name }} | ||||||
|  |           else | ||||||
|  |             echo "错误:未能提取到有效的 Go 版本号或版本号格式不正确" | ||||||
|  |             exit 1 | ||||||
|  |           fi | ||||||
|  |         else | ||||||
|  |           echo "错误:未找到 go.mod 文件" | ||||||
|  |           exit 1 | ||||||
|  |         fi | ||||||
|  |          | ||||||
|  |     - name: Create public branch | ||||||
|  |       run: | | ||||||
|  |         git checkout -b public || git checkout public | ||||||
|  |         git merge ${{ github.ref_name }} --no-edit || true | ||||||
|  |          | ||||||
|  |     - name: Remove security package references | ||||||
|  |       run: | | ||||||
|  |         find . -type f -name "*.go" -exec sed -i 's|"github.com/oneclickvirt/security/network"|"github.com/oneclickvirt/basics/network"|g' {} + | ||||||
|  |         sed -i '/SecurityUploadToken/d' utils/utils.go | ||||||
|  |         sed -i 's|"github.com/oneclickvirt/security/network"|"github.com/oneclickvirt/basics/network"|g' utils/utils.go | ||||||
|  |         sed -i '/^import/,/^)/{/^)/a\'$'\n''const token = "OvwKx5qgJtf7PZgCKbtyojSU.MTcwMTUxNzY1MTgwMw"'$'\n''}' utils/utils.go | ||||||
|  |         sed -i '/github.com\/oneclickvirt\/security/d' go.mod | ||||||
|  |         sed -i 's|var securityFlag = flag.Bool("security", true,|var securityFlag = flag.Bool("security", false,|g' goecs.go | ||||||
|  |         sed -i 's|VPS融合怪测试|VPS融合怪测试(非官方编译)|g' utils/utils.go | ||||||
|  |         sed -i 's|VPS Fusion Monster Test|VPS Fusion Monster Test (Unofficial)|g' utils/utils.go | ||||||
|  |         go mod tidy | ||||||
|  |         sed -i 's|但二进制文件编译至 \[securityCheck\].*)|但已开源|g' README.md | ||||||
|  |         sed -i 's|but binary files compiled in \[securityCheck\].*)|but open sourced|g' README_EN.md | ||||||
|  |         sed -i 's|security.*Enable/Disable security test (default true)|security        Enable/Disable security test (default false)|g' README.md | ||||||
|  |         sed -i 's|security.*Enable/Disable security test (default true)|security        Enable/Disable security test (default false)|g' README_EN.md | ||||||
|  |     - name: Update Go version in README files | ||||||
|  |       run: | | ||||||
|  |         if [ -f "go.mod" ]; then | ||||||
|  |           GO_VERSION=$(grep "^go " go.mod | head -n 1 | awk '{print $2}') | ||||||
|  |           echo "提取到的 Go 版本: $GO_VERSION" | ||||||
|  |           if [ -n "$GO_VERSION" ] && [[ "$GO_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then | ||||||
|  |             echo "版本验证成功,开始替换..." | ||||||
|  |             if [ -f "README.md" ]; then | ||||||
|  |               sed -i "s/选择 go [0-9]\+\.[0-9]\+\.[0-9]\+ 的版本进行安装/选择 go $GO_VERSION 的版本进行安装/g" README.md | ||||||
|  |               echo "已更新 README.md" | ||||||
|  |             fi | ||||||
|  |             if [ -f "README_EN.md" ]; then | ||||||
|  |               sed -i "s/Select go [0-9]\+\.[0-9]\+\.[0-9]\+ version to install/Select go $GO_VERSION version to install/g" README_EN.md | ||||||
|  |               echo "已更新 README_EN.md" | ||||||
|  |             fi | ||||||
|  |           else | ||||||
|  |             echo "错误:未能提取到有效的 Go 版本号或版本号格式不正确" | ||||||
|  |             exit 1 | ||||||
|  |           fi | ||||||
|  |         else | ||||||
|  |           echo "错误:未找到 go.mod 文件" | ||||||
|  |           exit 1 | ||||||
|  |         fi | ||||||
|  |     - name: Build and Test | ||||||
|  |       run: | | ||||||
|  |         go build -o maintest | ||||||
|  |         ./maintest -menu=false -l en -security=false -upload=false || exit 1 | ||||||
|  |         rm -rf maintest | ||||||
|  |          | ||||||
|  |     - name: Commit and push changes | ||||||
|  |       run: | | ||||||
|  |         git add . | ||||||
|  |         git commit -m "Auto update public version (no security package)" || echo "No changes to commit" | ||||||
|  |         git push -f origin public | ||||||
							
								
								
									
										55
									
								
								.github/workflows/public_build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								.github/workflows/public_build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,55 +0,0 @@ | |||||||
| name: Public Build |  | ||||||
|  |  | ||||||
| on: |  | ||||||
|   workflow_run: |  | ||||||
|     workflows: ["Build and Release"] |  | ||||||
|     types: |  | ||||||
|       - completed |  | ||||||
|   workflow_dispatch: |  | ||||||
|  |  | ||||||
| jobs: |  | ||||||
|   build: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|      |  | ||||||
|     steps: |  | ||||||
|     - uses: actions/checkout@v4 |  | ||||||
|       with: |  | ||||||
|         fetch-depth: 0 |  | ||||||
|  |  | ||||||
|     - name: Set up Go |  | ||||||
|       uses: actions/setup-go@v5 |  | ||||||
|       with: |  | ||||||
|         go-version: '1.24.5' |  | ||||||
|          |  | ||||||
|     - name: Create public branch |  | ||||||
|       run: | |  | ||||||
|         git config --global user.name 'GitHub Actions' |  | ||||||
|         git config --global user.email 'actions@github.com' |  | ||||||
|         git checkout -b public || git checkout public |  | ||||||
|         git merge ${{ github.ref_name }} --no-edit || true |  | ||||||
|          |  | ||||||
|     - name: Remove security package references |  | ||||||
|       run: | |  | ||||||
|         find . -type f -name "*.go" -exec sed -i 's|"github.com/oneclickvirt/security/network"|"github.com/oneclickvirt/basics/network"|g' {} + |  | ||||||
|         sed -i '/SecurityUploadToken/d' utils/utils.go |  | ||||||
|         sed -i 's|"github.com/oneclickvirt/security/network"|"github.com/oneclickvirt/basics/network"|g' utils/utils.go |  | ||||||
|         sed -i '/^import/,/^)/{/^)/a\'$'\n''const token = "OvwKx5qgJtf7PZgCKbtyojSU.MTcwMTUxNzY1MTgwMw"'$'\n''}' utils/utils.go |  | ||||||
|         sed -i '/github.com\/oneclickvirt\/security/d' go.mod |  | ||||||
|         sed -i 's|var securityFlag = flag.Bool("security", true,|var securityFlag = flag.Bool("security", false,|g' goecs.go |  | ||||||
|         go mod tidy |  | ||||||
|         sed -i 's|但二进制文件编译至 \[securityCheck\].*)|但已开源|g' README.md |  | ||||||
|         sed -i 's|but binary files compiled in \[securityCheck\].*)|but open sourced|g' README_EN.md |  | ||||||
|         sed -i 's|security.*Enable/Disable security test (default true)|security        Enable/Disable security test (default false)|g' README.md |  | ||||||
|         sed -i 's|security.*Enable/Disable security test (default true)|security        Enable/Disable security test (default false)|g' README_EN.md |  | ||||||
|  |  | ||||||
|     - name: Build and Test |  | ||||||
|       run: | |  | ||||||
|         go build -o maintest |  | ||||||
|         ./maintest -menu=false -l en -security=false -upload=false || exit 1 |  | ||||||
|         rm -rf maintest |  | ||||||
|          |  | ||||||
|     - name: Commit and push changes |  | ||||||
|       run: | |  | ||||||
|         git add . |  | ||||||
|         git commit -m "Auto update public version (no security package)" || echo "No changes to commit" |  | ||||||
|         git push -f origin public |  | ||||||
							
								
								
									
										29
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								README.md
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | |||||||
|  |  | ||||||
| [](https://app.fossa.com/projects/git%2Bgithub.com%2Foneclickvirt%2Fecs?ref=badge_shield) | [](https://app.fossa.com/projects/git%2Bgithub.com%2Foneclickvirt%2Fecs?ref=badge_shield) | ||||||
|  |  | ||||||
| [](https://hits.spiritlhl.net) | [](https://hits.spiritlhl.net) [](https://github.com/oneclickvirt/ecs/releases) | ||||||
|  |  | ||||||
| 融合怪测评项目 - GO版本 | 融合怪测评项目 - GO版本 | ||||||
|  |  | ||||||
| @@ -47,15 +47,14 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS | |||||||
| |----------------|---------------------------| | |----------------|---------------------------| | ||||||
| | Android(arm64) | 存在权限问题未修复,非安卓系统的ARM架构无问题      | | | Android(arm64) | 存在权限问题未修复,非安卓系统的ARM架构无问题      | | ||||||
| | OpenBSD/NetBSD | 部分Goalng的官方库未支持本系统(尤其是net相关项目)  | | | OpenBSD/NetBSD | 部分Goalng的官方库未支持本系统(尤其是net相关项目)  | | ||||||
| | Windows虚拟机   | 无Admin权限的mbw测试性能不准确(内存测试) | |  | ||||||
| | Windows物理机(非Admin下)   | 无Admin权限的mbw测试性能不准确(内存测试) | |  | ||||||
| --- | --- | ||||||
|  |  | ||||||
| ## **功能** | ## **功能** | ||||||
|  |  | ||||||
| - 系统基础信息查询,IP基础信息并发查询:[basics](https://github.com/oneclickvirt/basics)、[gostun](https://github.com/oneclickvirt/gostun) | - 系统基础信息查询,IP基础信息并发查询:[basics](https://github.com/oneclickvirt/basics)、[gostun](https://github.com/oneclickvirt/gostun) | ||||||
| - CPU 测试:[cputest](https://github.com/oneclickvirt/cputest),支持 sysbench(lua/golang版本)、geekbench、winsat | - CPU 测试:[cputest](https://github.com/oneclickvirt/cputest),支持 sysbench(lua/golang版本)、geekbench、winsat | ||||||
| - 内存测试:[memorytest](https://github.com/oneclickvirt/memorytest),支持 sysbench、dd | - 内存测试:[memorytest](https://github.com/oneclickvirt/memorytest),支持 sysbench、dd、winsat、mbw、stream | ||||||
| - 硬盘测试:[disktest](https://github.com/oneclickvirt/disktest),支持 dd、fio、winsat | - 硬盘测试:[disktest](https://github.com/oneclickvirt/disktest),支持 dd、fio、winsat | ||||||
| - 流媒体解锁信息并发查询:[netflix-verify](https://github.com/sjlleo/netflix-verify) 等逻辑,开发至 [CommonMediaTests](https://github.com/oneclickvirt/CommonMediaTests) | - 流媒体解锁信息并发查询:[netflix-verify](https://github.com/sjlleo/netflix-verify) 等逻辑,开发至 [CommonMediaTests](https://github.com/oneclickvirt/CommonMediaTests) | ||||||
| - 常见流媒体测试并发查询:[UnlockTests](https://github.com/oneclickvirt/UnlockTests),逻辑借鉴 [RegionRestrictionCheck](https://github.com/lmc999/RegionRestrictionCheck) 等 | - 常见流媒体测试并发查询:[UnlockTests](https://github.com/oneclickvirt/UnlockTests),逻辑借鉴 [RegionRestrictionCheck](https://github.com/lmc999/RegionRestrictionCheck) 等 | ||||||
| @@ -65,7 +64,7 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS | |||||||
| - 三网路由测试:基于 [NTrace-core](https://github.com/nxtrace/NTrace-core),二次开发至 [nt3](https://github.com/oneclickvirt/nt3) | - 三网路由测试:基于 [NTrace-core](https://github.com/nxtrace/NTrace-core),二次开发至 [nt3](https://github.com/oneclickvirt/nt3) | ||||||
| - 网速测试:基于 [speedtest.net](https://github.com/spiritLHLS/speedtest.net-CN-ID) 和 [speedtest.cn](https://github.com/spiritLHLS/speedtest.cn-CN-ID) 数据,开发至 [oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest) | - 网速测试:基于 [speedtest.net](https://github.com/spiritLHLS/speedtest.net-CN-ID) 和 [speedtest.cn](https://github.com/spiritLHLS/speedtest.cn-CN-ID) 数据,开发至 [oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest) | ||||||
| - 三网 Ping 值测试:借鉴 [ecsspeed](https://github.com/spiritLHLS/ecsspeed),二次开发至 [pingtest](https://github.com/oneclickvirt/pingtest) | - 三网 Ping 值测试:借鉴 [ecsspeed](https://github.com/spiritLHLS/ecsspeed),二次开发至 [pingtest](https://github.com/oneclickvirt/pingtest) | ||||||
| - 支持root或admin环境下测试,支持非root或非admin环境下测试,支持离线环境下进行测试,**暂未**支持无DNS环境下进行测试 | - 支持root或admin环境下测试,支持非root或非admin环境下测试,支持离线环境下进行测试,**暂未**支持无DNS的在线环境下进行测试 | ||||||
|  |  | ||||||
| **本项目初次使用建议查看说明:[跳转](https://github.com/oneclickvirt/ecs/blob/master/README_NEW_USER.md)** | **本项目初次使用建议查看说明:[跳转](https://github.com/oneclickvirt/ecs/blob/master/README_NEW_USER.md)** | ||||||
|  |  | ||||||
| @@ -82,25 +81,25 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS | |||||||
| - **国际用户无加速:** | - **国际用户无加速:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs |   export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| - **国际/国内使用 CDN 加速:** | - **国际/国内使用 CDN 加速:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs |   export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| - **国内用户使用 CNB 加速:** | - **国内用户使用 CNB 加速:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs |   export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| - **短链接:** | - **短链接:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs |   export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| #### **详细说明** | #### **详细说明** | ||||||
| @@ -243,6 +242,8 @@ Usage: goecs [options] | |||||||
| 1. 下载带 exe 文件的压缩包:[Releases](https://github.com/oneclickvirt/ecs/releases) | 1. 下载带 exe 文件的压缩包:[Releases](https://github.com/oneclickvirt/ecs/releases) | ||||||
| 2. 解压后,右键以管理员模式运行。 | 2. 解压后,右键以管理员模式运行。 | ||||||
|  |  | ||||||
|  | PS:如果是虚拟机环境,不以管理员模式运行也行,因为虚拟机无原生的测试工具,将自动启用替代方法测试。 | ||||||
|  |  | ||||||
| --- | --- | ||||||
|  |  | ||||||
| ### **Docker** | ### **Docker** | ||||||
| @@ -302,11 +303,11 @@ cd ecs | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| 2. 安装 Go 环境(如已安装可跳过) | 2. 安装 Go 环境(如已安装可跳过) | ||||||
|  |  | ||||||
|  | 选择 go 1.24.5 的版本进行安装 | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| # 下载并安装 Go | curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/spiritLHLS/one-click-installation-script/main/install_scripts/go.sh -o go.sh && chmod +x go.sh && bash go.sh  | ||||||
| wget https://go.dev/dl/go1.23.4.linux-amd64.tar.gz |  | ||||||
| rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz |  | ||||||
| export PATH=$PATH:/usr/local/go/bin |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| 3. 编译 | 3. 编译 | ||||||
| @@ -374,7 +375,7 @@ GOOS=darwin GOARCH=amd64 go build -o goecs_darwin | |||||||
|  |  | ||||||
| ## 致谢 | ## 致谢 | ||||||
|  |  | ||||||
| 感谢 [he.net](https://he.net) [bgp.tools](https://bgp.tools) [ipinfo.io](https://ipinfo.io) [maxmind.com](https://www.maxmind.com/en/home) [cloudflare.com](https://www.cloudflare.com/) [ip.sb](https://ip.sb) [scamalytics.com](https://scamalytics.com) [abuseipdb.com](https://www.abuseipdb.com/) [ip2location.com](https://ip2location.com/) [ip-api.com](https://ip-api.com) [ipregistry.co](https://ipregistry.co/) [ipdata.co](https://ipdata.co/) [ipgeolocation.io](https://ipgeolocation.io) [ipwhois.io](https://ipwhois.io) [ipapi.com](https://ipapi.com/) [ipapi.is](https://ipapi.is/) [ipqualityscore.com](https://www.ipqualityscore.com/) [bigdatacloud.com](https://www.bigdatacloud.com/) [dkly.net](https://data.dkly.net) [virustotal.com](https://www.virustotal.com/) 等网站提供的API进行检测,感谢互联网各网站提供的查询资源 | 感谢 [he.net](https://he.net) [bgp.tools](https://bgp.tools) [ipinfo.io](https://ipinfo.io) [maxmind.com](https://www.maxmind.com/en/home) [cloudflare.com](https://www.cloudflare.com/) [ip.sb](https://ip.sb) [scamalytics.com](https://scamalytics.com) [abuseipdb.com](https://www.abuseipdb.com/) [ip2location.com](https://ip2location.com/) [ip-api.com](https://ip-api.com) [ipregistry.co](https://ipregistry.co/) [ipdata.co](https://ipdata.co/) [ipgeolocation.io](https://ipgeolocation.io) [ipwhois.io](https://ipwhois.io) [ipapi.com](https://ipapi.com/) [ipapi.is](https://ipapi.is/) [ipqualityscore.com](https://www.ipqualityscore.com/) [bigdatacloud.com](https://www.bigdatacloud.com/) [dkly.net](https://data.dkly.net) [virustotal.com](https://www.virustotal.com/) [ipfighter.com](https://ipfighter.com/) [getipintel.net](http://check.getipintel.net/) [fraudlogix.com](https://fraudlogix.com) 等网站提供的API进行检测,感谢互联网各网站提供的查询资源 | ||||||
|  |  | ||||||
| 感谢 | 感谢 | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								README_EN.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README_EN.md
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | |||||||
|  |  | ||||||
| [](https://app.fossa.com/projects/git%2Bgithub.com%2Foneclickvirt%2Fecs?ref=badge_shield) | [](https://app.fossa.com/projects/git%2Bgithub.com%2Foneclickvirt%2Fecs?ref=badge_shield) | ||||||
|  |  | ||||||
| [](https://hits.spiritlhl.net) | [](https://hits.spiritlhl.net) [](https://github.com/oneclickvirt/ecs/releases) | ||||||
|  |  | ||||||
| Fusion Monster Evaluation Project - GO Version | Fusion Monster Evaluation Project - GO Version | ||||||
|  |  | ||||||
| @@ -47,8 +47,6 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https: | |||||||
| |--------|-------------------------------------------------------------------------------------------------| | |--------|-------------------------------------------------------------------------------------------------| | ||||||
| | Android(arm64) | Permission issues that are not fixed, no problems with ARM architecture for non-Android systems    | | | Android(arm64) | Permission issues that are not fixed, no problems with ARM architecture for non-Android systems    | | ||||||
| | OpenBSD/NetBSD | Some of Goalng's official libraries do not support this system (especially net-related items) | | | OpenBSD/NetBSD | Some of Goalng's official libraries do not support this system (especially net-related items) | | ||||||
| | Windows(Virtual Machines) | Inaccurate mbw test performance without Admin rights (memory tests) |  |  | ||||||
| | Windows(Physical Machines)(not under Admin) | Inaccurate mbw test performance without Admin rights (memory tests) | |  | ||||||
|  |  | ||||||
| --- | --- | ||||||
|  |  | ||||||
| @@ -56,7 +54,7 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https: | |||||||
|  |  | ||||||
| - System basic information query and concurrent IP basic information query: Self-developed [basics](https://github.com/oneclickvirt/basics), [gostun](https://github.com/oneclickvirt/gostun) | - System basic information query and concurrent IP basic information query: Self-developed [basics](https://github.com/oneclickvirt/basics), [gostun](https://github.com/oneclickvirt/gostun) | ||||||
| - CPU test: Self-developed [cputest](https://github.com/oneclickvirt/cputest) supporting sysbench(lua/golang version), geekbench, winsat | - CPU test: Self-developed [cputest](https://github.com/oneclickvirt/cputest) supporting sysbench(lua/golang version), geekbench, winsat | ||||||
| - Memory test: Self-developed [memorytest](https://github.com/oneclickvirt/memorytest) supporting sysbench, dd | - Memory test: Self-developed [memorytest](https://github.com/oneclickvirt/memorytest) supporting sysbench, dd, winsat, mbw, stream | ||||||
| - Disk test: Self-developed [disktest](https://github.com/oneclickvirt/disktest) supporting dd, fio, winsat | - Disk test: Self-developed [disktest](https://github.com/oneclickvirt/disktest) supporting dd, fio, winsat | ||||||
| - Streaming media unlock information concurrent query: Modified from [netflix-verify](https://github.com/sjlleo/netflix-verify) and more to [CommonMediaTests](https://github.com/oneclickvirt/CommonMediaTests) | - Streaming media unlock information concurrent query: Modified from [netflix-verify](https://github.com/sjlleo/netflix-verify) and more to [CommonMediaTests](https://github.com/oneclickvirt/CommonMediaTests) | ||||||
| - Common streaming media tests concurrent query: Self-developed to [UnlockTests](https://github.com/oneclickvirt/UnlockTests), logic modified from [RegionRestrictionCheck](https://github.com/lmc999/RegionRestrictionCheck) and others | - Common streaming media tests concurrent query: Self-developed to [UnlockTests](https://github.com/oneclickvirt/UnlockTests), logic modified from [RegionRestrictionCheck](https://github.com/lmc999/RegionRestrictionCheck) and others | ||||||
| @@ -66,7 +64,7 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https: | |||||||
| - Three-network route test: Modified from [NTrace-core](https://github.com/nxtrace/NTrace-core) to [nt3](https://github.com/oneclickvirt/nt3) | - Three-network route test: Modified from [NTrace-core](https://github.com/nxtrace/NTrace-core) to [nt3](https://github.com/oneclickvirt/nt3) | ||||||
| - Speed test: Based on data from [speedtest.net](https://github.com/spiritLHLS/speedtest.net-CN-ID) and [speedtest.cn](https://github.com/spiritLHLS/speedtest.cn-CN-ID), developed to [oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest) | - Speed test: Based on data from [speedtest.net](https://github.com/spiritLHLS/speedtest.net-CN-ID) and [speedtest.cn](https://github.com/spiritLHLS/speedtest.cn-CN-ID), developed to [oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest) | ||||||
| - Three-network Ping test: Modified from [ecsspeed](https://github.com/spiritLHLS/ecsspeed) to [pingtest](https://github.com/oneclickvirt/pingtest) | - Three-network Ping test: Modified from [ecsspeed](https://github.com/spiritLHLS/ecsspeed) to [pingtest](https://github.com/oneclickvirt/pingtest) | ||||||
| - Support root or admin environment testing, support non-root or non-admin environment testing, support offline environment for testing, not support no DNS environment for testing | - Support root or admin environment testing, support non-root or non-admin environment testing, support offline environment for testing, **not yet** support no DNS online environment for testing | ||||||
|  |  | ||||||
| **For first-time users of this project, it is recommended to check the instructions: [Jump to](https://github.com/oneclickvirt/ecs/blob/master/README_NEW_USER.md)** | **For first-time users of this project, it is recommended to check the instructions: [Jump to](https://github.com/oneclickvirt/ecs/blob/master/README_NEW_USER.md)** | ||||||
|  |  | ||||||
| @@ -83,19 +81,19 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https: | |||||||
| - **International users without acceleration:** | - **International users without acceleration:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs -l en |   export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| - **International/domestic users with CDN acceleration:** | - **International/domestic users with CDN acceleration:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs -l en |   export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| - **Domestic users with CNB acceleration:** | - **Domestic users with CNB acceleration:** | ||||||
|  |  | ||||||
|   ```bash |   ```bash | ||||||
|   export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs -l en |   export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
| - **Short Link:** | - **Short Link:** | ||||||
| @@ -243,6 +241,8 @@ Usage: goecs [options] | |||||||
| 1. Download the compressed file with the .exe file: [Releases](https://github.com/oneclickvirt/ecs/releases) | 1. Download the compressed file with the .exe file: [Releases](https://github.com/oneclickvirt/ecs/releases) | ||||||
| 2. After unzipping, right-click and run as administrator. | 2. After unzipping, right-click and run as administrator. | ||||||
|  |  | ||||||
|  | PS: If it's a VM environment, it's OK not to run it in administrator mode, because VMs have no native testing tools and will automatically enable alternative methods for testing. | ||||||
|  |  | ||||||
| --- | --- | ||||||
|  |  | ||||||
| ### **Docker** | ### **Docker** | ||||||
| @@ -300,11 +300,11 @@ cd ecs | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| 2. Install Go environment (skip if already installed) | 2. Install Go environment (skip if already installed) | ||||||
|  |  | ||||||
|  | Select go 1.24.5 version to install  | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| # Download and install Go | curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/spiritLHLS/one-click-installation-script/main/install_scripts/go.sh -o go.sh && chmod +x go.sh && bash go.sh  | ||||||
| wget https://go.dev/dl/go1.23.4.linux-amd64.tar.gz |  | ||||||
| rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz |  | ||||||
| export PATH=$PATH:/usr/local/go/bin |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| 3. Compile | 3. Compile | ||||||
| @@ -372,7 +372,7 @@ Note that `goecs` allows you to specify CPU test method via parameters. The defa | |||||||
|  |  | ||||||
| ## Thanks | ## Thanks | ||||||
|  |  | ||||||
| Thank [he.net](https://he.net) [bgp.tools](https://bgp.tools) [ipinfo.io](https://ipinfo.io) [maxmind.com](https://www.maxmind.com/en/home) [cloudflare.com](https://www.cloudflare.com/) [ip.sb](https://ip.sb) [scamalytics.com](https://scamalytics.com) [abuseipdb.com](https://www.abuseipdb.com/) [ip2location.com](https://ip2location.com/) [ip-api.com](https://ip-api.com) [ipregistry.co](https://ipregistry.co/) [ipdata.co](https://ipdata.co/) [ipgeolocation.io](https://ipgeolocation.io) [ipwhois.io](https://ipwhois.io) [ipapi.com](https://ipapi.com/) [ipapi.is](https://ipapi.is/) [ipqualityscore.com](https://www.ipqualityscore.com/) [bigdatacloud.com](https://www.bigdatacloud.com/) [dkly.net](https://data.dkly.net) [virustotal.com](https://www.virustotal.com/) and others for providing APIs for testing, and thanks to various websites on the Internet for providing query resources. | Thank [he.net](https://he.net) [bgp.tools](https://bgp.tools) [ipinfo.io](https://ipinfo.io) [maxmind.com](https://www.maxmind.com/en/home) [cloudflare.com](https://www.cloudflare.com/) [ip.sb](https://ip.sb) [scamalytics.com](https://scamalytics.com) [abuseipdb.com](https://www.abuseipdb.com/) [ip2location.com](https://ip2location.com/) [ip-api.com](https://ip-api.com) [ipregistry.co](https://ipregistry.co/) [ipdata.co](https://ipdata.co/) [ipgeolocation.io](https://ipgeolocation.io) [ipwhois.io](https://ipwhois.io) [ipapi.com](https://ipapi.com/) [ipapi.is](https://ipapi.is/) [ipqualityscore.com](https://www.ipqualityscore.com/) [bigdatacloud.com](https://www.bigdatacloud.com/) [dkly.net](https://data.dkly.net) [virustotal.com](https://www.virustotal.com/) [ipfighter.com](https://ipfighter.com/) [getipintel.net](http://check.getipintel.net/) [fraudlogix.com](https://fraudlogix.com) and others for providing APIs for testing, and thanks to various websites on the Internet for providing query resources. | ||||||
|  |  | ||||||
| Thank | Thank | ||||||
|  |  | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								go.mod
									
									
									
									
									
								
							| @@ -5,18 +5,18 @@ go 1.24.5 | |||||||
| require ( | require ( | ||||||
| 	github.com/imroc/req/v3 v3.54.0 | 	github.com/imroc/req/v3 v3.54.0 | ||||||
| 	github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 | 	github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 | ||||||
| 	github.com/oneclickvirt/UnlockTests v0.0.28-20250727155204 | 	github.com/oneclickvirt/UnlockTests v0.0.28-20250924054500 | ||||||
| 	github.com/oneclickvirt/backtrace v0.0.7-20250811023541 | 	github.com/oneclickvirt/backtrace v0.0.7-20250811023541 | ||||||
| 	github.com/oneclickvirt/basics v0.0.15-20250805084236 | 	github.com/oneclickvirt/basics v0.0.15-20250812130523 | ||||||
| 	github.com/oneclickvirt/cputest v0.0.12-20250720122317 | 	github.com/oneclickvirt/cputest v0.0.12-20250720122317 | ||||||
| 	github.com/oneclickvirt/defaultset v0.0.2-20240624082446 | 	github.com/oneclickvirt/defaultset v0.0.2-20240624082446 | ||||||
| 	github.com/oneclickvirt/disktest v0.0.10-20250808140407 | 	github.com/oneclickvirt/disktest v0.0.10-20250924030424 | ||||||
| 	github.com/oneclickvirt/gostun v0.0.5-20250727155022 | 	github.com/oneclickvirt/gostun v0.0.5-20250727155022 | ||||||
| 	github.com/oneclickvirt/memorytest v0.0.9-20250808065154 | 	github.com/oneclickvirt/memorytest v0.0.10-20250924154648 | ||||||
| 	github.com/oneclickvirt/nt3 v0.0.8-20250811123903 | 	github.com/oneclickvirt/nt3 v0.0.8-20250811123903 | ||||||
| 	github.com/oneclickvirt/pingtest v0.0.8-20250728015259 | 	github.com/oneclickvirt/pingtest v0.0.8-20250728015259 | ||||||
| 	github.com/oneclickvirt/portchecker v0.0.3-20250728015900 | 	github.com/oneclickvirt/portchecker v0.0.3-20250728015900 | ||||||
| 	github.com/oneclickvirt/security v0.0.6-20250805090112 | 	github.com/oneclickvirt/security v0.0.6-20251028123803 | ||||||
| 	github.com/oneclickvirt/speedtest v0.0.10-20250728015734 | 	github.com/oneclickvirt/speedtest v0.0.10-20250728015734 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -61,6 +61,7 @@ require ( | |||||||
| 	github.com/oneclickvirt/dd v0.0.2-20250808062818 // indirect | 	github.com/oneclickvirt/dd v0.0.2-20250808062818 // indirect | ||||||
| 	github.com/oneclickvirt/fio v0.0.2-20250808045755 // indirect | 	github.com/oneclickvirt/fio v0.0.2-20250808045755 // indirect | ||||||
| 	github.com/oneclickvirt/mbw v0.0.1-20250808061222 // indirect | 	github.com/oneclickvirt/mbw v0.0.1-20250808061222 // indirect | ||||||
|  | 	github.com/oneclickvirt/stream v0.0.2-20250924154001 // indirect | ||||||
| 	github.com/oschwald/maxminddb-golang v1.13.1 // indirect | 	github.com/oschwald/maxminddb-golang v1.13.1 // indirect | ||||||
| 	github.com/pelletier/go-toml/v2 v2.2.4 // indirect | 	github.com/pelletier/go-toml/v2 v2.2.4 // indirect | ||||||
| 	github.com/pion/dtls/v2 v2.2.7 // indirect | 	github.com/pion/dtls/v2 v2.2.7 // indirect | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								go.sum
									
									
									
									
									
								
							| @@ -96,38 +96,40 @@ github.com/nxtrace/NTrace-core v1.4.2 h1:dSRP18Bn3VGf5CZBzKt8gQWW9mDkq62Np9TCF9R | |||||||
| github.com/nxtrace/NTrace-core v1.4.2/go.mod h1:wIDOlccuYzY3wBqU89pv2KGHT41i3JA0eRqJU/x9eX4= | github.com/nxtrace/NTrace-core v1.4.2/go.mod h1:wIDOlccuYzY3wBqU89pv2KGHT41i3JA0eRqJU/x9eX4= | ||||||
| github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 h1:Zef93z9UiZQwRAKnnZYALmpBKvvuVaq34MEsuWwk6nc= | github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 h1:Zef93z9UiZQwRAKnnZYALmpBKvvuVaq34MEsuWwk6nc= | ||||||
| github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841/go.mod h1:DAmFPRjFV5p9fEzUUSml5jJGn2f1NZJQCzTxITHDjc4= | github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841/go.mod h1:DAmFPRjFV5p9fEzUUSml5jJGn2f1NZJQCzTxITHDjc4= | ||||||
| github.com/oneclickvirt/UnlockTests v0.0.28-20250727155204 h1:apFaEbHGKflYMZzK17nXzEai4GG873mTd+d9hCO/KdY= | github.com/oneclickvirt/UnlockTests v0.0.28-20250924054500 h1:ERFoRBYhTPWJBYhEVFWr3hm6KtSTUHuWD21jK7DhKZw= | ||||||
| github.com/oneclickvirt/UnlockTests v0.0.28-20250727155204/go.mod h1:oOa6wj/qECtRMxwBO6D7o0L0F0Q/5sQ747OCnFQqoGE= | github.com/oneclickvirt/UnlockTests v0.0.28-20250924054500/go.mod h1:oOa6wj/qECtRMxwBO6D7o0L0F0Q/5sQ747OCnFQqoGE= | ||||||
| github.com/oneclickvirt/backtrace v0.0.7-20250811023541 h1:GzkzvUC6U9b6Dkz/Bl4JRPeQ7XBGoW7Qw1aWqzhF+MQ= | github.com/oneclickvirt/backtrace v0.0.7-20250811023541 h1:GzkzvUC6U9b6Dkz/Bl4JRPeQ7XBGoW7Qw1aWqzhF+MQ= | ||||||
| github.com/oneclickvirt/backtrace v0.0.7-20250811023541/go.mod h1:/+KUtOWz48TyiTTbhVTsp3D6b5WY+4pCgvFBYtUGtns= | github.com/oneclickvirt/backtrace v0.0.7-20250811023541/go.mod h1:/+KUtOWz48TyiTTbhVTsp3D6b5WY+4pCgvFBYtUGtns= | ||||||
| github.com/oneclickvirt/basics v0.0.15-20250805084236 h1:guYO6wGooSIOAIutuy/zfJ4sXj525nBITw8cjEPRaK8= | github.com/oneclickvirt/basics v0.0.15-20250812130523 h1:nPNTVq8d9N1rdshkMAbnhZxTb7L2Yt7NlIg6rY10YRQ= | ||||||
| github.com/oneclickvirt/basics v0.0.15-20250805084236/go.mod h1:2PV+1ge01zb0Sqzj2V2I7P0wAdFSLF1XgAiumchJJbg= | github.com/oneclickvirt/basics v0.0.15-20250812130523/go.mod h1:2PV+1ge01zb0Sqzj2V2I7P0wAdFSLF1XgAiumchJJbg= | ||||||
| github.com/oneclickvirt/cputest v0.0.12-20250720122317 h1:toiwAK1hZE5b8klu2mOQ7J4sv5yV9lpPKwgPahfRYBQ= | github.com/oneclickvirt/cputest v0.0.12-20250720122317 h1:toiwAK1hZE5b8klu2mOQ7J4sv5yV9lpPKwgPahfRYBQ= | ||||||
| github.com/oneclickvirt/cputest v0.0.12-20250720122317/go.mod h1:vjlH8tkPFft1tlLOpeNskXVvurxkHaJ3+dgFxQGLXY4= | github.com/oneclickvirt/cputest v0.0.12-20250720122317/go.mod h1:vjlH8tkPFft1tlLOpeNskXVvurxkHaJ3+dgFxQGLXY4= | ||||||
| github.com/oneclickvirt/dd v0.0.2-20250808062818 h1:0KHrKkdpL5oBE1OHsrRd2siRw4/2k6f9LBaP7T4JpOc= | github.com/oneclickvirt/dd v0.0.2-20250808062818 h1:0KHrKkdpL5oBE1OHsrRd2siRw4/2k6f9LBaP7T4JpOc= | ||||||
| github.com/oneclickvirt/dd v0.0.2-20250808062818/go.mod h1:tImu9sPTkLWo2tf1dEN1xQzrylWKauj9hbU8PHfyAeU= | github.com/oneclickvirt/dd v0.0.2-20250808062818/go.mod h1:tImu9sPTkLWo2tf1dEN1xQzrylWKauj9hbU8PHfyAeU= | ||||||
| github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc= | github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc= | ||||||
| github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E= | github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E= | ||||||
| github.com/oneclickvirt/disktest v0.0.10-20250808140407 h1:oUfi5zF3htUTB1ZJuClmK0o74ufP7icbu8LYCnxEOxE= | github.com/oneclickvirt/disktest v0.0.10-20250924030424 h1:56Aq2xygO/vA/co5vJ7/MQTNijIDl8eYbVk8uCWN4mI= | ||||||
| github.com/oneclickvirt/disktest v0.0.10-20250808140407/go.mod h1:Vp3iMVBD4ccReDJz5n5SlzUdq0kDuVhpRklQk21KT+8= | github.com/oneclickvirt/disktest v0.0.10-20250924030424/go.mod h1:Vp3iMVBD4ccReDJz5n5SlzUdq0kDuVhpRklQk21KT+8= | ||||||
| github.com/oneclickvirt/fio v0.0.2-20250808045755 h1:eWihCRWcalJjPIdrF8dMe68ZiPnMkSfHC8ENvElp/xE= | github.com/oneclickvirt/fio v0.0.2-20250808045755 h1:eWihCRWcalJjPIdrF8dMe68ZiPnMkSfHC8ENvElp/xE= | ||||||
| github.com/oneclickvirt/fio v0.0.2-20250808045755/go.mod h1:NIq+XYTey68KNERGIy/oRDlzpwLzBVoHOCiqX8didsE= | github.com/oneclickvirt/fio v0.0.2-20250808045755/go.mod h1:NIq+XYTey68KNERGIy/oRDlzpwLzBVoHOCiqX8didsE= | ||||||
| github.com/oneclickvirt/gostun v0.0.5-20250727155022 h1:/e3gSUrOp1tg/1NTRx+P8B51OGcP26Q6//5EoSIjOvk= | github.com/oneclickvirt/gostun v0.0.5-20250727155022 h1:/e3gSUrOp1tg/1NTRx+P8B51OGcP26Q6//5EoSIjOvk= | ||||||
| github.com/oneclickvirt/gostun v0.0.5-20250727155022/go.mod h1:pfp7MFZJK9n/KTLAVqqFcCAns4xqMykmjI+1UeF/vdE= | github.com/oneclickvirt/gostun v0.0.5-20250727155022/go.mod h1:pfp7MFZJK9n/KTLAVqqFcCAns4xqMykmjI+1UeF/vdE= | ||||||
| github.com/oneclickvirt/mbw v0.0.1-20250808061222 h1:WGXOe6QvHiDRhPVMI0VcctjzW08kGvJf50yq5YeZCtw= | github.com/oneclickvirt/mbw v0.0.1-20250808061222 h1:WGXOe6QvHiDRhPVMI0VcctjzW08kGvJf50yq5YeZCtw= | ||||||
| github.com/oneclickvirt/mbw v0.0.1-20250808061222/go.mod h1:0Vq6NRpyLmGUdfHfL3uDcFsuZhi7KlG+OCs5ky2757Y= | github.com/oneclickvirt/mbw v0.0.1-20250808061222/go.mod h1:0Vq6NRpyLmGUdfHfL3uDcFsuZhi7KlG+OCs5ky2757Y= | ||||||
| github.com/oneclickvirt/memorytest v0.0.9-20250808065154 h1:mjYOvpFz2mpDU9MNjj66oIDcc2r6+zoW8veP616/+4Q= | github.com/oneclickvirt/memorytest v0.0.10-20250924154648 h1:trk6oZ7xs1eVtr+6oIv5IX8LDVtEMG+E6GVzQ810BtU= | ||||||
| github.com/oneclickvirt/memorytest v0.0.9-20250808065154/go.mod h1:DBxiVZX7mWCe0Fy+qu57ENheLo00sLfjKzvxiICrUtU= | github.com/oneclickvirt/memorytest v0.0.10-20250924154648/go.mod h1:4kiHsEWkW9r3/1ZcV5xIweU0smiKP0IRfQj74AUIiVI= | ||||||
| github.com/oneclickvirt/nt3 v0.0.8-20250811123903 h1:ubSPLh/DSrXj+tOgmRABgi2vrVmbmjjSne+NrVFNmNc= | github.com/oneclickvirt/nt3 v0.0.8-20250811123903 h1:ubSPLh/DSrXj+tOgmRABgi2vrVmbmjjSne+NrVFNmNc= | ||||||
| github.com/oneclickvirt/nt3 v0.0.8-20250811123903/go.mod h1:F1v+6xInBKnbUa8gV1M40R1HOzxg+obtduNhx3CTnmA= | github.com/oneclickvirt/nt3 v0.0.8-20250811123903/go.mod h1:F1v+6xInBKnbUa8gV1M40R1HOzxg+obtduNhx3CTnmA= | ||||||
| github.com/oneclickvirt/pingtest v0.0.8-20250728015259 h1:egoxZRZBOWN3JqBwqEsULDyRo2/dpGMeWcmV3U87zig= | github.com/oneclickvirt/pingtest v0.0.8-20250728015259 h1:egoxZRZBOWN3JqBwqEsULDyRo2/dpGMeWcmV3U87zig= | ||||||
| github.com/oneclickvirt/pingtest v0.0.8-20250728015259/go.mod h1:gxwsxxwitNQiGq2OI0ZogYoOLwc8DtuOdSRe6/EvRqs= | github.com/oneclickvirt/pingtest v0.0.8-20250728015259/go.mod h1:gxwsxxwitNQiGq2OI0ZogYoOLwc8DtuOdSRe6/EvRqs= | ||||||
| github.com/oneclickvirt/portchecker v0.0.3-20250728015900 h1:AomzdppSOFB70AJESQhlp0IPbsHTTJGimAWDk2TzCWM= | github.com/oneclickvirt/portchecker v0.0.3-20250728015900 h1:AomzdppSOFB70AJESQhlp0IPbsHTTJGimAWDk2TzCWM= | ||||||
| github.com/oneclickvirt/portchecker v0.0.3-20250728015900/go.mod h1:9sjMDPCd4Z40wkYB0S9gQPGH8YPtnNE1ZJthVIuHUzA= | github.com/oneclickvirt/portchecker v0.0.3-20250728015900/go.mod h1:9sjMDPCd4Z40wkYB0S9gQPGH8YPtnNE1ZJthVIuHUzA= | ||||||
| github.com/oneclickvirt/security v0.0.6-20250805090112 h1:lUNtsnpZ3JNLS4xxjFGGECaxA46yNyxbYjdust9W0M4= | github.com/oneclickvirt/security v0.0.6-20251028123803 h1:iOjLqpyzOR2QDrA7ei00upv1uWGEbf1dH4mRa2xlWIg= | ||||||
| github.com/oneclickvirt/security v0.0.6-20250805090112/go.mod h1:JB6SJWm5pbrngCgSTYLd2m4Hj8mHO6mJua1WgHMZOcE= | github.com/oneclickvirt/security v0.0.6-20251028123803/go.mod h1:RSMooIlb4H/kLrGWNvUyOgdzQKgYKVv+LzWGlsPsLW4= | ||||||
| github.com/oneclickvirt/speedtest v0.0.10-20250728015734 h1:HKO7/JQ74ueXA8Wo8NIvcK9DphbEG/YTfAAVz/akSiY= | github.com/oneclickvirt/speedtest v0.0.10-20250728015734 h1:HKO7/JQ74ueXA8Wo8NIvcK9DphbEG/YTfAAVz/akSiY= | ||||||
| github.com/oneclickvirt/speedtest v0.0.10-20250728015734/go.mod h1:0W8vnMbA3iucXLXFdGfe9Ia6RPS0izRO7jvu/SnH1P8= | github.com/oneclickvirt/speedtest v0.0.10-20250728015734/go.mod h1:0W8vnMbA3iucXLXFdGfe9Ia6RPS0izRO7jvu/SnH1P8= | ||||||
|  | github.com/oneclickvirt/stream v0.0.2-20250924154001 h1:GuJWdiPkoK84+y/+oHKr2Ghl3c/MzS9Z5m1nM+lMmy4= | ||||||
|  | github.com/oneclickvirt/stream v0.0.2-20250924154001/go.mod h1:oWaizaHTC2VQciBC9RfaLbAOf8qeR6n20/gY7QxriDE= | ||||||
| github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE= | github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE= | ||||||
| github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8= | github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8= | ||||||
| github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								goecs.go
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								goecs.go
									
									
									
									
									
								
							| @@ -7,7 +7,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" |  | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| @@ -40,7 +39,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	ecsVersion                                                        = "v0.1.82" | 	ecsVersion                                                        = "v0.1.90" | ||||||
| 	menuMode                                                          bool | 	menuMode                                                          bool | ||||||
| 	onlyChinaTest                                                     bool | 	onlyChinaTest                                                     bool | ||||||
| 	input, choice                                                     string | 	input, choice                                                     string | ||||||
| @@ -140,7 +139,7 @@ func parseFlags() { | |||||||
| 	goecsFlag.BoolVar(&speedTestStatus, "speed", true, "Enable/Disable speed test") | 	goecsFlag.BoolVar(&speedTestStatus, "speed", true, "Enable/Disable speed test") | ||||||
| 	goecsFlag.StringVar(&cpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)") | 	goecsFlag.StringVar(&cpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)") | ||||||
| 	goecsFlag.StringVar(&cpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)") | 	goecsFlag.StringVar(&cpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)") | ||||||
| 	goecsFlag.StringVar(&memoryTestMethod, "memorym", "sysbench", "Set memory test method (supported: sysbench, dd, winsat)") | 	goecsFlag.StringVar(&memoryTestMethod, "memorym", "stream", "Set memory test method (supported: stream, sysbench, dd, winsat, auto)") | ||||||
| 	goecsFlag.StringVar(&diskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)") | 	goecsFlag.StringVar(&diskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)") | ||||||
| 	goecsFlag.StringVar(&diskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root") | 	goecsFlag.StringVar(&diskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root") | ||||||
| 	goecsFlag.BoolVar(&diskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false") | 	goecsFlag.BoolVar(&diskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false") | ||||||
| @@ -247,23 +246,7 @@ Loop: | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // clearScreen 清屏 |  | ||||||
| func clearScreen() { |  | ||||||
| 	var cmd *exec.Cmd |  | ||||||
| 	switch runtime.GOOS { |  | ||||||
| 	case "windows": |  | ||||||
| 		cmd = exec.Command("cmd", "/c", "cls") |  | ||||||
| 	case "darwin": |  | ||||||
| 		cmd = exec.Command("clear") |  | ||||||
| 	default: |  | ||||||
| 		cmd = exec.Command("clear") |  | ||||||
| 	} |  | ||||||
| 	cmd.Stdout = os.Stdout |  | ||||||
| 	_ = cmd.Run() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func printMenuOptions(preCheck utils.NetCheckResult) { | func printMenuOptions(preCheck utils.NetCheckResult) { | ||||||
| 	clearScreen() // 清屏 |  | ||||||
| 	var stats *utils.StatsResponse | 	var stats *utils.StatsResponse | ||||||
| 	var statsErr error | 	var statsErr error | ||||||
| 	var githubInfo *utils.GitHubRelease | 	var githubInfo *utils.GitHubRelease | ||||||
| @@ -546,7 +529,7 @@ func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *str | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3, wg4 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) { | func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) { | ||||||
| 	*output = runBasicTests(preCheck, basicInfo, securityInfo, *output, tempOutput, outputMutex) | 	*output = runBasicTests(preCheck, basicInfo, securityInfo, *output, tempOutput, outputMutex) | ||||||
| 	*output = runCPUTest(*output, tempOutput, outputMutex) | 	*output = runCPUTest(*output, tempOutput, outputMutex) | ||||||
| 	*output = runMemoryTest(*output, tempOutput, outputMutex) | 	*output = runMemoryTest(*output, tempOutput, outputMutex) | ||||||
| @@ -554,7 +537,6 @@ func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3, wg4 *sync.Wai | |||||||
| 	if onlyIpInfoCheckStatus && !basicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | 	if onlyIpInfoCheckStatus && !basicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | ||||||
| 		*output = runIpInfoCheck(*output, tempOutput, outputMutex) | 		*output = runIpInfoCheck(*output, tempOutput, outputMutex) | ||||||
| 	} | 	} | ||||||
| 	var backtraceInfo string |  | ||||||
| 	if utTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !onlyChinaTest { | 	if utTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !onlyChinaTest { | ||||||
| 		wg1.Add(1) | 		wg1.Add(1) | ||||||
| 		go func() { | 		go func() { | ||||||
| @@ -576,24 +558,13 @@ func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3, wg4 *sync.Wai | |||||||
| 			*ptInfo = pt.PingTest() | 			*ptInfo = pt.PingTest() | ||||||
| 		}() | 		}() | ||||||
| 	} | 	} | ||||||
| 	if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { |  | ||||||
| 		if backtraceStatus && !onlyChinaTest { |  | ||||||
| 			wg4.Add(1) |  | ||||||
| 			go func() { |  | ||||||
| 				defer wg4.Done() |  | ||||||
| 				backtraceInfo = utils.PrintAndCapture(func() { |  | ||||||
| 					upstreams.UpstreamsCheck() |  | ||||||
| 				}, "", "") |  | ||||||
| 			}() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | 	if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | ||||||
| 		*output = runStreamingTests(wg1, mediaInfo, *output, tempOutput, outputMutex) | 		*output = runStreamingTests(wg1, mediaInfo, *output, tempOutput, outputMutex) | ||||||
| 		*output = runSecurityTests(*securityInfo, *output, tempOutput, outputMutex) | 		*output = runSecurityTests(*securityInfo, *output, tempOutput, outputMutex) | ||||||
| 		*output = runEmailTests(wg2, emailInfo, *output, tempOutput, outputMutex) | 		*output = runEmailTests(wg2, emailInfo, *output, tempOutput, outputMutex) | ||||||
| 	} | 	} | ||||||
| 	if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | 	if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | ||||||
| 		*output = runNetworkTests(wg3, wg4, ptInfo, &backtraceInfo, *output, tempOutput, outputMutex) | 		*output = runNetworkTests(wg3, ptInfo, *output, tempOutput, outputMutex) | ||||||
| 	} | 	} | ||||||
| 	if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | 	if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { | ||||||
| 		*output = runSpeedTests(*output, tempOutput, outputMutex) | 		*output = runSpeedTests(*output, tempOutput, outputMutex) | ||||||
| @@ -805,16 +776,13 @@ func runEmailTests(wg2 *sync.WaitGroup, emailInfo *string, output, tempOutput st | |||||||
| 	}, tempOutput, output) | 	}, tempOutput, output) | ||||||
| } | } | ||||||
|  |  | ||||||
| func runNetworkTests(wg3, wg4 *sync.WaitGroup, ptInfo, backtraceInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string { | func runNetworkTests(wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string { | ||||||
| 	outputMutex.Lock() | 	outputMutex.Lock() | ||||||
| 	defer outputMutex.Unlock() | 	defer outputMutex.Unlock() | ||||||
| 	return utils.PrintAndCapture(func() { | 	return utils.PrintAndCapture(func() { | ||||||
| 		if backtraceStatus && !onlyChinaTest && *backtraceInfo != "" { | 		if backtraceStatus && !onlyChinaTest { | ||||||
| 			if wg4 != nil { |  | ||||||
| 				wg4.Wait() |  | ||||||
| 			} |  | ||||||
| 			utils.PrintCenteredTitle("上游及回程线路检测", width) | 			utils.PrintCenteredTitle("上游及回程线路检测", width) | ||||||
| 			fmt.Print(*backtraceInfo) | 			upstreams.UpstreamsCheck() // 不能在重定向的同时外部并发,此处仅可以顺序执行 | ||||||
| 		} | 		} | ||||||
| 		if nt3Status && !onlyChinaTest { | 		if nt3Status && !onlyChinaTest { | ||||||
| 			utils.PrintCenteredTitle("三网回程路由检测", width) | 			utils.PrintCenteredTitle("三网回程路由检测", width) | ||||||
| @@ -889,8 +857,10 @@ func handleUploadResults(output string) { | |||||||
| 	if httpURL != "" || httpsURL != "" { | 	if httpURL != "" || httpsURL != "" { | ||||||
| 		if language == "en" { | 		if language == "en" { | ||||||
| 			fmt.Printf("Upload successfully!\nHttp URL:  %s\nHttps URL: %s\n", httpURL, httpsURL) | 			fmt.Printf("Upload successfully!\nHttp URL:  %s\nHttps URL: %s\n", httpURL, httpsURL) | ||||||
|  | 			fmt.Println("Each Test Benchmark: https://bash.spiritlhl.net/ecsguide") | ||||||
| 		} else { | 		} else { | ||||||
| 			fmt.Printf("上传成功!\nHttp URL:  %s\nHttps URL: %s\n", httpURL, httpsURL) | 			fmt.Printf("上传成功!\nHttp URL:  %s\nHttps URL: %s\n", httpURL, httpsURL) | ||||||
|  | 			fmt.Println("每项测试基准见: https://bash.spiritlhl.net/ecsguide") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -917,7 +887,7 @@ func main() { | |||||||
| 		enabelUpload = false | 		enabelUpload = false | ||||||
| 	} | 	} | ||||||
| 	var ( | 	var ( | ||||||
| 		wg1, wg2, wg3, wg4                                    sync.WaitGroup | 		wg1, wg2, wg3                                         sync.WaitGroup | ||||||
| 		basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo string | 		basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo string | ||||||
| 		output, tempOutput                                    string | 		output, tempOutput                                    string | ||||||
| 		outputMutex                                           sync.Mutex | 		outputMutex                                           sync.Mutex | ||||||
| @@ -929,7 +899,7 @@ func main() { | |||||||
| 	go handleSignalInterrupt(sig, &startTime, &output, tempOutput, uploadDone, &outputMutex) | 	go handleSignalInterrupt(sig, &startTime, &output, tempOutput, uploadDone, &outputMutex) | ||||||
| 	switch language { | 	switch language { | ||||||
| 	case "zh": | 	case "zh": | ||||||
| 		runChineseTests(preCheck, &wg1, &wg2, &wg3, &wg4, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, &output, tempOutput, startTime, &outputMutex) | 		runChineseTests(preCheck, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, &output, tempOutput, startTime, &outputMutex) | ||||||
| 	case "en": | 	case "en": | ||||||
| 		runEnglishTests(preCheck, &wg1, &wg2, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &output, tempOutput, startTime, &outputMutex) | 		runEnglishTests(preCheck, &wg1, &wg2, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &output, tempOutput, startTime, &outputMutex) | ||||||
| 	default: | 	default: | ||||||
|   | |||||||
							
								
								
									
										347
									
								
								goecs.sh
									
									
									
									
									
								
							
							
						
						
									
										347
									
								
								goecs.sh
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| #!/bin/bash | #!/bin/sh | ||||||
| # From https://github.com/oneclickvirt/ecs | # From https://github.com/oneclickvirt/ecs | ||||||
| # 2025.06.29 | # 2025.10.08 | ||||||
|  |  | ||||||
| # curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh | # curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh | ||||||
| # 或 | # 或 | ||||||
| @@ -20,22 +20,27 @@ cd /root >/dev/null 2>&1 | |||||||
| if [ ! -d "/usr/bin/" ]; then | if [ ! -d "/usr/bin/" ]; then | ||||||
|     mkdir -p "/usr/bin/" |     mkdir -p "/usr/bin/" | ||||||
| fi | fi | ||||||
| _red() { echo -e "\033[31m\033[01m$@\033[0m"; } | _red() { printf "\033[31m\033[01m%s\033[0m\n" "$*"; } | ||||||
| _green() { echo -e "\033[32m\033[01m$@\033[0m"; } | _green() { printf "\033[32m\033[01m%s\033[0m\n" "$*"; } | ||||||
| _yellow() { echo -e "\033[33m\033[01m$@\033[0m"; } | _yellow() { printf "\033[33m\033[01m%s\033[0m\n" "$*"; } | ||||||
| _blue() { echo -e "\033[36m\033[01m$@\033[0m"; } | _blue() { printf "\033[36m\033[01m%s\033[0m\n" "$*"; } | ||||||
| reading() { read -rp "$(_green "$1")" "$2"; } | reading() {  | ||||||
|  |     printf "\033[32m\033[01m%s\033[0m" "$1" | ||||||
|  |     read "$2" | ||||||
|  | } | ||||||
|  |  | ||||||
| check_cdn() { | check_cdn() { | ||||||
|     local o_url=$1 |     local o_url="$1" | ||||||
|     for cdn_url in "${cdn_urls[@]}"; do |     local cdn_url | ||||||
|         if curl -sL -k "$cdn_url$o_url" --max-time 6 | grep -q "success" >/dev/null 2>&1; then |     for cdn_url in $cdn_urls; do | ||||||
|             export cdn_success_url="$cdn_url" |         if curl -4 -sL -k "$cdn_url$o_url" --max-time 6 | grep -q "success" >/dev/null 2>&1; then | ||||||
|             return |             cdn_success_url="$cdn_url" | ||||||
|  |             return 0 | ||||||
|         fi |         fi | ||||||
|         sleep 0.5 |         sleep 0.5 | ||||||
|     done |     done | ||||||
|     export cdn_success_url="" |     cdn_success_url="" | ||||||
|  |     return 1 | ||||||
| } | } | ||||||
|  |  | ||||||
| check_cdn_file() { | check_cdn_file() { | ||||||
| @@ -50,9 +55,9 @@ check_cdn_file() { | |||||||
| download_file() { | download_file() { | ||||||
|     local url="$1" |     local url="$1" | ||||||
|     local output="$2" |     local output="$2" | ||||||
|     if ! wget -O "$output" "$url"; then |     if ! wget -O "$output" "$url" 2>/dev/null; then | ||||||
|         _yellow "wget failed, trying curl..." |         _yellow "wget failed, trying curl..." | ||||||
|         if ! curl -L -o "$output" "$url"; then |         if ! curl -L -o "$output" "$url" 2>/dev/null; then | ||||||
|             _red "Both wget and curl failed. Unable to download the file." |             _red "Both wget and curl failed. Unable to download the file." | ||||||
|             return 1 |             return 1 | ||||||
|         fi |         fi | ||||||
| @@ -62,8 +67,7 @@ download_file() { | |||||||
|  |  | ||||||
| check_china() { | check_china() { | ||||||
|     _yellow "正在检测IP所在区域......" |     _yellow "正在检测IP所在区域......" | ||||||
|     if [[ -z "${CN}" ]]; then |     if [ -z "${CN}" ]; then | ||||||
|         # 首先尝试通过 ipapi.co 检测 |  | ||||||
|         if curl -m 6 -s https://ipapi.co/json | grep -q 'China'; then |         if curl -m 6 -s https://ipapi.co/json | grep -q 'China'; then | ||||||
|             _yellow "根据ipapi.co提供的信息,当前IP可能在中国" |             _yellow "根据ipapi.co提供的信息,当前IP可能在中国" | ||||||
|             if [ "$noninteractive" != "true" ]; then |             if [ "$noninteractive" != "true" ]; then | ||||||
| @@ -94,28 +98,33 @@ check_china() { | |||||||
|  |  | ||||||
| get_memory_size() { | get_memory_size() { | ||||||
|     if [ -f /proc/meminfo ]; then |     if [ -f /proc/meminfo ]; then | ||||||
|         local mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') |         local mem_kb | ||||||
|  |         mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') | ||||||
|         echo $((mem_kb / 1024)) # Convert to MB |         echo $((mem_kb / 1024)) # Convert to MB | ||||||
|         return |         return 0 | ||||||
|     fi |     fi | ||||||
|     if command -v free >/dev/null 2>&1; then |     if command -v free >/dev/null 2>&1; then | ||||||
|         local mem_kb=$(free -m | awk '/^Mem:/ {print $2}') |         local mem_kb | ||||||
|  |         mem_kb=$(free -m | awk '/^Mem:/ {print $2}') | ||||||
|         echo "$mem_kb" # Already in MB |         echo "$mem_kb" # Already in MB | ||||||
|         return |         return 0 | ||||||
|     fi |     fi | ||||||
|     if command -v sysctl >/dev/null 2>&1; then |     if command -v sysctl >/dev/null 2>&1; then | ||||||
|         local mem_bytes=$(sysctl -n hw.memsize 2>/dev/null || sysctl -n hw.physmem 2>/dev/null) |         local mem_bytes | ||||||
|  |         mem_bytes=$(sysctl -n hw.memsize 2>/dev/null || sysctl -n hw.physmem 2>/dev/null) | ||||||
|         if [ -n "$mem_bytes" ]; then |         if [ -n "$mem_bytes" ]; then | ||||||
|             echo $((mem_bytes / 1024 / 1024)) # Convert to MB |             echo $((mem_bytes / 1024 / 1024)) # Convert to MB | ||||||
|             return |             return 0 | ||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
|  |     echo 0 | ||||||
|  |     return 1 | ||||||
| } | } | ||||||
|  |  | ||||||
| cleanup_epel() { | cleanup_epel() { | ||||||
|     _yellow "Cleaning up EPEL repositories..." |     _yellow "Cleaning up EPEL repositories..." | ||||||
|     rm -f /etc/yum.repos.d/*epel* |     rm -f /etc/yum.repos.d/*epel* | ||||||
|     yum clean all |     yum clean all >/dev/null 2>&1 | ||||||
| } | } | ||||||
|  |  | ||||||
| goecs_check() { | goecs_check() { | ||||||
| @@ -143,7 +152,7 @@ goecs_check() { | |||||||
|     os=$(uname -s 2>/dev/null || echo "Unknown") |     os=$(uname -s 2>/dev/null || echo "Unknown") | ||||||
|     arch=$(uname -m 2>/dev/null || echo "Unknown") |     arch=$(uname -m 2>/dev/null || echo "Unknown") | ||||||
|     check_china |     check_china | ||||||
|     ECS_VERSION="0.1.79" |     ECS_VERSION="0.1.89" | ||||||
|     for api in \ |     for api in \ | ||||||
|         "https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \ |         "https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \ | ||||||
|         "https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \ |         "https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \ | ||||||
| @@ -155,23 +164,24 @@ goecs_check() { | |||||||
|         sleep 1 |         sleep 1 | ||||||
|     done |     done | ||||||
|     if [ -z "$ECS_VERSION" ]; then |     if [ -z "$ECS_VERSION" ]; then | ||||||
|         _yellow "Unable to get version info, using default version 0.1.79" |         _yellow "Unable to get version info, using default version 0.1.89" | ||||||
|         ECS_VERSION="0.1.79" |         ECS_VERSION="0.1.89" | ||||||
|     fi |     fi | ||||||
|     version_output="" |     version_output="" | ||||||
|     for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do |     for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do | ||||||
|         if [ -x "$(command -v $cmd_path 2>/dev/null)" ]; then |         if command -v "$cmd_path" >/dev/null 2>&1; then | ||||||
|             version_output=$($cmd_path -v command 2>/dev/null) |             version_output=$($cmd_path -v command 2>/dev/null) | ||||||
|             break |             break | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
|     if [ -n "$version_output" ]; then |     if [ -n "$version_output" ]; then | ||||||
|         extracted_version=${version_output//v/} |         extracted_version=${version_output#*v} | ||||||
|  |         extracted_version=${extracted_version#v} | ||||||
|         if [ -n "$extracted_version" ]; then |         if [ -n "$extracted_version" ]; then | ||||||
|             ecs_version=$ECS_VERSION |             ecs_version=$ECS_VERSION | ||||||
|             if [[ "$(echo -e "$extracted_version\n$ecs_version" | sort -V | tail -n 1)" == "$extracted_version" ]]; then |             if [ "$(printf '%s\n%s\n' "$extracted_version" "$ecs_version" | sort -V | tail -n 1)" = "$extracted_version" ]; then | ||||||
|                 _green "goecs version ($extracted_version) is up to date, no upgrade needed" |                 _green "goecs version ($extracted_version) is up to date, no upgrade needed" | ||||||
|                 return |                 return 0 | ||||||
|             else |             else | ||||||
|                 _yellow "goecs version ($extracted_version) < $ecs_version, upgrade needed, starting in 5 seconds" |                 _yellow "goecs version ($extracted_version) < $ecs_version, upgrade needed, starting in 5 seconds" | ||||||
|                 rm -rf /usr/bin/goecs /usr/local/bin/goecs ./goecs |                 rm -rf /usr/bin/goecs /usr/local/bin/goecs ./goecs | ||||||
| @@ -181,11 +191,11 @@ goecs_check() { | |||||||
|         _green "goecs not found, installation needed, starting in 5 seconds" |         _green "goecs not found, installation needed, starting in 5 seconds" | ||||||
|     fi |     fi | ||||||
|     sleep 5 |     sleep 5 | ||||||
|     if [[ "$CN" == true ]]; then |     if [ "$CN" = "true" ]; then | ||||||
|         _yellow "Using China mirror for download..." |         _yellow "Using China mirror for download..." | ||||||
|         base_url="https://cnb.cool/oneclickvirt/ecs/-/git/raw/main" |         base_url="https://cnb.cool/oneclickvirt/ecs/-/git/raw/main" | ||||||
|     else |     else | ||||||
|         cdn_urls=("https://cdn0.spiritlhl.top/" "http://cdn3.spiritlhl.net/" "http://cdn1.spiritlhl.net/" "http://cdn2.spiritlhl.net/") |         cdn_urls="https://cdn0.spiritlhl.top/ http://cdn3.spiritlhl.net/ http://cdn1.spiritlhl.net/ http://cdn2.spiritlhl.net/" | ||||||
|         check_cdn_file |         check_cdn_file | ||||||
|         if [ -n "$cdn_success_url" ]; then |         if [ -n "$cdn_success_url" ]; then | ||||||
|             base_url="${cdn_success_url}https://github.com/oneclickvirt/ecs/releases/download/v${ECS_VERSION}" |             base_url="${cdn_success_url}https://github.com/oneclickvirt/ecs/releases/download/v${ECS_VERSION}" | ||||||
| @@ -301,169 +311,188 @@ InstallSysbench() { | |||||||
|     else |     else | ||||||
|         Var_OSRelease="unknown" # 未知系统分支 |         Var_OSRelease="unknown" # 未知系统分支 | ||||||
|     fi |     fi | ||||||
|     local mem_size=$(get_memory_size) |     local mem_size | ||||||
|  |     mem_size=$(get_memory_size) | ||||||
|     if [ -z "$mem_size" ] || [ "$mem_size" -eq 0 ]; then |     if [ -z "$mem_size" ] || [ "$mem_size" -eq 0 ]; then | ||||||
|         echo "Error: Unable to determine memory size or memory size is zero." |         echo "Error: Unable to determine memory size or memory size is zero." | ||||||
|     elif [ $mem_size -lt 1024 ]; then |     elif [ "$mem_size" -lt 1024 ]; then | ||||||
|         _red "Warning: Your system has less than 1GB RAM (${mem_size}MB)" |         _red "Warning: Your system has less than 1GB RAM (${mem_size}MB)" | ||||||
|         if [ "$noninteractive" != "true" ]; then |         if [ "$noninteractive" != "true" ]; then | ||||||
|             reading "Do you want to continue with EPEL installation? (y/N): " confirm |             reading "Do you want to continue with EPEL installation? (y/N): " confirm | ||||||
|             if [[ ! $confirm =~ ^[Yy]$ ]]; then |             case "$confirm" in | ||||||
|  |                 [Yy]*) | ||||||
|  |                     ;; | ||||||
|  |                 *) | ||||||
|                     _yellow "Skipping EPEL installation" |                     _yellow "Skipping EPEL installation" | ||||||
|                     return 1 |                     return 1 | ||||||
|             fi |                     ;; | ||||||
|  |             esac | ||||||
|         fi |         fi | ||||||
|         case "$Var_OSRelease" in |         case "$Var_OSRelease" in | ||||||
|         ubuntu | debian | astra) |         ubuntu | debian | astra) | ||||||
|             ! apt-get install -y sysbench && apt-get --fix-broken install -y && apt-get install --no-install-recommends -y sysbench ;; |             if ! apt-get install -y sysbench; then | ||||||
|  |                 apt-get --fix-broken install -y | ||||||
|  |                 apt-get install --no-install-recommends -y sysbench | ||||||
|  |             fi | ||||||
|  |             ;; | ||||||
|         centos | rhel | almalinux | redhat | opencloudos) |         centos | rhel | almalinux | redhat | opencloudos) | ||||||
|             (yum -y install epel-release && yum -y install sysbench) || (dnf install epel-release -y && dnf install sysbench -y) ;; |             if ! yum -y install epel-release || ! yum -y install sysbench; then | ||||||
|  |                 if command -v dnf >/dev/null 2>&1; then | ||||||
|  |                     dnf install epel-release -y | ||||||
|  |                     dnf install sysbench -y | ||||||
|  |                 fi | ||||||
|  |             fi | ||||||
|  |             ;; | ||||||
|         fedora) |         fedora) | ||||||
|             dnf -y install sysbench ;; |             dnf -y install sysbench ;; | ||||||
|         arch) |         arch) | ||||||
|             pacman -S --needed --noconfirm sysbench && pacman -S --needed --noconfirm libaio && ldconfig ;; |             pacman -S --needed --noconfirm sysbench | ||||||
|  |             pacman -S --needed --noconfirm libaio | ||||||
|  |             ldconfig | ||||||
|  |             ;; | ||||||
|         freebsd) |         freebsd) | ||||||
|             pkg install -y sysbench ;; |             pkg install -y sysbench ;; | ||||||
|         alpinelinux) |         alpinelinux) | ||||||
|             if [ "$noninteractive" != "true" ]; then |             if [ "$noninteractive" != "true" ]; then | ||||||
|                 reading "Do you want to continue with sysbench installation? (y/N): " confirm |                 reading "Do you want to continue with sysbench installation? (y/N): " confirm | ||||||
|                 if [[ ! $confirm =~ ^[Yy]$ ]]; then |                 case "$confirm" in | ||||||
|  |                     [Yy]*) | ||||||
|  |                         ;; | ||||||
|  |                     *) | ||||||
|                         _yellow "Skipping sysbench installation" |                         _yellow "Skipping sysbench installation" | ||||||
|                         return 1 |                         return 1 | ||||||
|                 fi |                         ;; | ||||||
|  |                 esac | ||||||
|             fi |             fi | ||||||
|             ALPINE_VERSION=$(grep -o '^[0-9]\+\.[0-9]\+' /etc/alpine-release) |             ALPINE_VERSION=$(grep -o '^[0-9]\+\.[0-9]\+' /etc/alpine-release) | ||||||
|             COMMUNITY_REPO="http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community" |             COMMUNITY_REPO="http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community" | ||||||
|             if grep -q "^${COMMUNITY_REPO}" /etc/apk/repositories; then |             if ! grep -q "^${COMMUNITY_REPO}" /etc/apk/repositories; then | ||||||
|                 echo "Community repository is already enabled." |  | ||||||
|             else |  | ||||||
|                 echo "Enabling community repository..." |                 echo "Enabling community repository..." | ||||||
|                 echo "${COMMUNITY_REPO}" >> /etc/apk/repositories |                 echo "${COMMUNITY_REPO}" >> /etc/apk/repositories | ||||||
|                 echo "Community repository has been added." |                 echo "Community repository has been added." | ||||||
|                 echo "Updating apk package index..." |                 echo "Updating apk package index..." | ||||||
|                 apk update && echo "Package index updated successfully." |                 apk update && echo "Package index updated successfully." | ||||||
|  |             else | ||||||
|  |                 echo "Community repository is already enabled." | ||||||
|             fi |             fi | ||||||
|             if apk info sysbench >/dev/null 2>&1; then |             if apk info sysbench >/dev/null 2>&1; then | ||||||
|                 echo -e "${Msg_Info}Sysbench already installed." |                 echo "Sysbench already installed." | ||||||
|             else |             else | ||||||
|                 apk add --no-cache sysbench |                 if ! apk add --no-cache sysbench; then | ||||||
|                 if [ $? -ne 0 ]; then |                     echo "Sysbench Module not found, installing ..." | ||||||
|                     echo -e "${Msg_Warning}Sysbench Module not found, installing ..." && echo -e "${Msg_Warning}SysBench Current not support Alpine Linux, Skipping..." && Var_Skip_SysBench="1" |                     echo "SysBench Current not support Alpine Linux, Skipping..." | ||||||
|  |                     Var_Skip_SysBench="1" | ||||||
|                 else |                 else | ||||||
|                     echo -e "${Msg_Success}Sysbench installed successfully." |                     echo "Sysbench installed successfully." | ||||||
|                 fi |                 fi | ||||||
|             fi ;; |             fi | ||||||
|  |             ;; | ||||||
|         *) |         *) | ||||||
|             _red "Sysbench Install Error: Unknown OS release: $Var_OSRelease" ;; |             _red "Sysbench Install Error: Unknown OS release: $Var_OSRelease" ;; | ||||||
|         esac |         esac | ||||||
|         if [[ $SYSTEM =~ ^(CentOS|RHEL|AlmaLinux)$ ]]; then |         case "$SYSTEM" in | ||||||
|  |             CentOS|RHEL|AlmaLinux) | ||||||
|                 _yellow "Installing EPEL repository..." |                 _yellow "Installing EPEL repository..." | ||||||
|                 if ! yum -y install epel-release; then |                 if ! yum -y install epel-release; then | ||||||
|                     _red "EPEL installation failed!" |                     _red "EPEL installation failed!" | ||||||
|                     cleanup_epel |                     cleanup_epel | ||||||
|                     _yellow "Attempting to continue without EPEL..." |                     _yellow "Attempting to continue without EPEL..." | ||||||
|                 fi |                 fi | ||||||
|         fi |                 ;; | ||||||
|     fi |         esac | ||||||
| } |  | ||||||
|  |  | ||||||
| Check_SysBench() { |  | ||||||
|     if [ ! -f "/usr/bin/sysbench" ] && [ ! -f "/usr/local/bin/sysbench" ]; then |  | ||||||
|         InstallSysbench |  | ||||||
|     fi |  | ||||||
|     # 尝试编译安装 |  | ||||||
|     if [ ! -f "/usr/bin/sysbench" ] && [ ! -f "/usr/local/bin/sysbench" ]; then |  | ||||||
|         echo -e "${Msg_Warning}Sysbench Module install Failure, trying compile modules ..." |  | ||||||
|         Check_Sysbench_InstantBuild |  | ||||||
|     fi |  | ||||||
|     source ~/.bashrc |  | ||||||
|     # 最终检测 |  | ||||||
|     if [ "$(command -v sysbench)" ] || [ -f "/usr/bin/sysbench" ] || [ -f "/usr/local/bin/sysbench" ]; then |  | ||||||
|         _yellow "Install sysbench successfully!" |  | ||||||
|     else |  | ||||||
|         _red "SysBench Moudle install Failure! Try Restart Bench or Manually install it! (/usr/bin/sysbench)" |  | ||||||
|         _blue "Will try to test with geekbench5 instead later." |  | ||||||
|     fi |  | ||||||
|     sleep 3 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| Check_Sysbench_InstantBuild() { |  | ||||||
|     if [ "${Var_OSRelease}" = "centos" ] || [ "${Var_OSRelease}" = "rhel" ] || [ "${Var_OSRelease}" = "almalinux" ] || [ "${Var_OSRelease}" = "ubuntu" ] || [ "${Var_OSRelease}" = "debian" ] || [ "${Var_OSRelease}" = "fedora" ] || [ "${Var_OSRelease}" = "arch" ] || [ "${Var_OSRelease}" = "astra" ]; then |  | ||||||
|         local os_sysbench=${Var_OSRelease} |  | ||||||
|         if [ "$os_sysbench" = "astra" ]; then |  | ||||||
|             os_sysbench="debian" |  | ||||||
|         fi |  | ||||||
|         if [ "$os_sysbench" = "opencloudos" ]; then |  | ||||||
|             os_sysbench="centos" |  | ||||||
|         fi |  | ||||||
|         echo -e "${Msg_Info}Release Detected: ${os_sysbench}" |  | ||||||
|         echo -e "${Msg_Info}Preparing compile enviorment ..." |  | ||||||
|         prepare_compile_env "${os_sysbench}" |  | ||||||
|         echo -e "${Msg_Info}Downloading Source code (Version 1.0.20)..." |  | ||||||
|         mkdir -p /tmp/sysbench_install/src/ |  | ||||||
|         mv /tmp/sysbench-1.0.20 /tmp/sysbench_install/src/ |  | ||||||
|         echo -e "${Msg_Info}Compiling Sysbench Module ..." |  | ||||||
|         cd /tmp/sysbench_install/src/sysbench-1.0.20 |  | ||||||
|         ./autogen.sh && ./configure --without-mysql && make -j8 && make install |  | ||||||
|         echo -e "${Msg_Info}Cleaning up ..." |  | ||||||
|         cd /tmp && rm -rf /tmp/sysbench_install/src/sysbench* |  | ||||||
|     else |  | ||||||
|         echo -e "${Msg_Warning}Unsupported operating system: ${Var_OSRelease}" |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| prepare_compile_env() { |  | ||||||
|     local system="$1" |  | ||||||
|     if [ "${system}" = "centos" ] || [ "${system}" = "rhel" ] || [ "${system}" = "almalinux" ]; then |  | ||||||
|         yum install -y epel-release |  | ||||||
|         yum install -y wget curl make gcc gcc-c++ make automake libtool pkgconfig libaio-devel |  | ||||||
|     elif [ "${system}" = "ubuntu" ] || [ "${system}" = "debian" ]; then |  | ||||||
|         ! apt-get update && apt-get --fix-broken install -y && apt-get update |  | ||||||
|         ! apt-get -y install --no-install-recommends curl wget make automake libtool pkg-config libaio-dev unzip && apt-get --fix-broken install -y && apt-get -y install --no-install-recommends curl wget make automake libtool pkg-config libaio-dev unzip |  | ||||||
|     elif [ "${system}" = "fedora" ]; then |  | ||||||
|         dnf install -y wget curl gcc gcc-c++ make automake libtool pkgconfig libaio-devel |  | ||||||
|     elif [ "${system}" = "arch" ]; then |  | ||||||
|         pacman -S --needed --noconfirm wget curl gcc gcc make automake libtool pkgconfig libaio lib32-libaio |  | ||||||
|     else |  | ||||||
|         echo -e "${Msg_Warning}Unsupported operating system: ${system}" |  | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
|  |  | ||||||
| env_check() { | env_check() { | ||||||
|     REGEX=("debian|astra" "ubuntu" "centos|red hat|kernel|oracle linux|alma|rocky" "'amazon linux'" "fedora" "arch" "freebsd" "alpine" "openbsd" "opencloudos") |     # 检测是否为 macOS 系统 | ||||||
|     RELEASE=("Debian" "Ubuntu" "CentOS" "CentOS" "Fedora" "Arch" "FreeBSD" "Alpine" "OpenBSD" "OpenCloudOS") |     if [ "$(uname -s)" = "Darwin" ]; then | ||||||
|     PACKAGE_UPDATE=("apt-get update" "apt-get update" "yum -y update" "yum -y update" "yum -y update" "pacman -Sy" "pkg update" "apk update" "pkg_add -qu" "yum -y update") |         _green "Detected macOS system" | ||||||
|     PACKAGE_INSTALL=("apt-get -y install" "apt-get -y install" "yum -y install" "yum -y install" "yum -y install" "pacman -Sy --noconfirm --needed" "pkg install -y" "apk add --no-cache" "pkg_add -I" "yum -y install") |         _green "macOS has built-in tools, skipping dependency installation" | ||||||
|     PACKAGE_REMOVE=("apt-get -y remove" "apt-get -y remove" "yum -y remove" "yum -y remove" "yum -y remove" "pacman -Rsc --noconfirm" "pkg delete" "apk del" "pkg_delete -I" "yum -y remove") |         _green "Environment preparation complete." | ||||||
|     PACKAGE_UNINSTALL=("apt-get -y autoremove" "apt-get -y autoremove" "yum -y autoremove" "yum -y autoremove" "yum -y autoremove" "pacman -Rns --noconfirm" "pkg autoremove" "apk autoremove" "pkg_delete -a" "yum -y autoremove") |         _green "Next command is: ./goecs.sh install" | ||||||
|  |         return 0 | ||||||
|  |     fi | ||||||
|  |      | ||||||
|     if [ -f /etc/opencloudos-release ]; then |     if [ -f /etc/opencloudos-release ]; then | ||||||
|         SYS="opencloudos" |         SYS="opencloudos" | ||||||
|     elif [ -s /etc/os-release ]; then |     elif [ -s /etc/os-release ]; then | ||||||
|         SYS="$(grep -i pretty_name /etc/os-release | cut -d \" -f2)" |         SYS="$(grep -i pretty_name /etc/os-release | cut -d \" -f2)" | ||||||
|     elif [ -x "$(type -p hostnamectl)" ]; then |     elif command -v hostnamectl >/dev/null 2>&1; then | ||||||
|         SYS="$(hostnamectl | grep -i system | cut -d : -f2 | xargs)" |         SYS="$(hostnamectl | grep -i system | cut -d : -f2 | sed 's/^ *//')" | ||||||
|     elif [ -x "$(type -p lsb_release)" ]; then |     elif command -v lsb_release >/dev/null 2>&1; then | ||||||
|         SYS="$(lsb_release -sd)" |         SYS="$(lsb_release -sd)" | ||||||
|     elif [ -s /etc/lsb-release ]; then |     elif [ -s /etc/lsb-release ]; then | ||||||
|         SYS="$(grep -i description /etc/lsb-release | cut -d \" -f2)" |         SYS="$(grep -i description /etc/lsb-release | cut -d \" -f2)" | ||||||
|     elif [ -s /etc/redhat-release ]; then |     elif [ -s /etc/redhat-release ]; then | ||||||
|         SYS="$(grep . /etc/redhat-release)" |         SYS="$(cat /etc/redhat-release)" | ||||||
|     elif [ -s /etc/issue ]; then |     elif [ -s /etc/issue ]; then | ||||||
|         SYS="$(grep . /etc/issue | cut -d '\' -f1 | sed '/^[ ]*$/d')" |         SYS="$(head -n1 /etc/issue | cut -d '\' -f1 | sed '/^[ ]*$/d')" | ||||||
|     else |     else | ||||||
|         SYS="$(uname -s)" |         SYS="$(uname -s)" | ||||||
|     fi |     fi | ||||||
|     SYSTEM="" |     SYSTEM="" | ||||||
|     for ((int = 0; int < ${#REGEX[@]}; int++)); do |     sys_lower=$(echo "$SYS" | tr '[:upper:]' '[:lower:]') | ||||||
|         if [[ $(echo "$SYS" | tr '[:upper:]' '[:lower:]') =~ ${REGEX[int]} ]]; then |     if echo "$sys_lower" | grep -E "debian|astra" >/dev/null 2>&1; then | ||||||
|             SYSTEM="${RELEASE[int]}" |         SYSTEM="Debian" | ||||||
|             UPDATE_CMD=${PACKAGE_UPDATE[int]} |         UPDATE_CMD="apt-get update" | ||||||
|             INSTALL_CMD=${PACKAGE_INSTALL[int]} |         INSTALL_CMD="apt-get -y install" | ||||||
|             REMOVE_CMD=${PACKAGE_REMOVE[int]} |         REMOVE_CMD="apt-get -y remove" | ||||||
|             UNINSTALL_CMD=${PACKAGE_UNINSTALL[int]} |         UNINSTALL_CMD="apt-get -y autoremove" | ||||||
|             break |     elif echo "$sys_lower" | grep -E "ubuntu" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="Ubuntu" | ||||||
|  |         UPDATE_CMD="apt-get update" | ||||||
|  |         INSTALL_CMD="apt-get -y install" | ||||||
|  |         REMOVE_CMD="apt-get -y remove" | ||||||
|  |         UNINSTALL_CMD="apt-get -y autoremove" | ||||||
|  |     elif echo "$sys_lower" | grep -E "centos|red hat|kernel|oracle linux|alma|rocky" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="CentOS" | ||||||
|  |         UPDATE_CMD="yum -y update" | ||||||
|  |         INSTALL_CMD="yum -y install" | ||||||
|  |         REMOVE_CMD="yum -y remove" | ||||||
|  |         UNINSTALL_CMD="yum -y autoremove" | ||||||
|  |     elif echo "$sys_lower" | grep -E "amazon linux" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="CentOS" | ||||||
|  |         UPDATE_CMD="yum -y update" | ||||||
|  |         INSTALL_CMD="yum -y install" | ||||||
|  |         REMOVE_CMD="yum -y remove" | ||||||
|  |         UNINSTALL_CMD="yum -y autoremove" | ||||||
|  |     elif echo "$sys_lower" | grep -E "fedora" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="Fedora" | ||||||
|  |         UPDATE_CMD="yum -y update" | ||||||
|  |         INSTALL_CMD="yum -y install" | ||||||
|  |         REMOVE_CMD="yum -y remove" | ||||||
|  |         UNINSTALL_CMD="yum -y autoremove" | ||||||
|  |     elif echo "$sys_lower" | grep -E "arch" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="Arch" | ||||||
|  |         UPDATE_CMD="pacman -Sy" | ||||||
|  |         INSTALL_CMD="pacman -Sy --noconfirm --needed" | ||||||
|  |         REMOVE_CMD="pacman -Rsc --noconfirm" | ||||||
|  |         UNINSTALL_CMD="pacman -Rns --noconfirm" | ||||||
|  |     elif echo "$sys_lower" | grep -E "freebsd" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="FreeBSD" | ||||||
|  |         UPDATE_CMD="pkg update" | ||||||
|  |         INSTALL_CMD="pkg install -y" | ||||||
|  |         REMOVE_CMD="pkg delete" | ||||||
|  |         UNINSTALL_CMD="pkg autoremove" | ||||||
|  |     elif echo "$sys_lower" | grep -E "alpine" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="Alpine" | ||||||
|  |         UPDATE_CMD="apk update" | ||||||
|  |         INSTALL_CMD="apk add --no-cache" | ||||||
|  |         REMOVE_CMD="apk del" | ||||||
|  |         UNINSTALL_CMD="apk autoremove" | ||||||
|  |     elif echo "$sys_lower" | grep -E "openbsd" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="OpenBSD" | ||||||
|  |         UPDATE_CMD="pkg_add -qu" | ||||||
|  |         INSTALL_CMD="pkg_add -I" | ||||||
|  |         REMOVE_CMD="pkg_delete -I" | ||||||
|  |         UNINSTALL_CMD="pkg_delete -a" | ||||||
|  |     elif echo "$sys_lower" | grep -E "opencloudos" >/dev/null 2>&1; then | ||||||
|  |         SYSTEM="OpenCloudOS" | ||||||
|  |         UPDATE_CMD="yum -y update" | ||||||
|  |         INSTALL_CMD="yum -y install" | ||||||
|  |         REMOVE_CMD="yum -y remove" | ||||||
|  |         UNINSTALL_CMD="yum -y autoremove" | ||||||
|     fi |     fi | ||||||
|     done |  | ||||||
|     if [ -z "$SYSTEM" ]; then |     if [ -z "$SYSTEM" ]; then | ||||||
|         _yellow "Unable to recognize system, trying common package managers..." |         _yellow "Unable to recognize system, trying common package managers..." | ||||||
|         if command -v apt-get >/dev/null 2>&1; then |         if command -v apt-get >/dev/null 2>&1; then | ||||||
| @@ -510,7 +539,7 @@ env_check() { | |||||||
|     _green "System information: $SYSTEM" |     _green "System information: $SYSTEM" | ||||||
|     _green "Update command: $UPDATE_CMD" |     _green "Update command: $UPDATE_CMD" | ||||||
|     _green "Install command: $INSTALL_CMD" |     _green "Install command: $INSTALL_CMD" | ||||||
|     cdn_urls=("https://cdn0.spiritlhl.top/" "http://cdn3.spiritlhl.net/" "http://cdn1.spiritlhl.net/" "http://cdn2.spiritlhl.net/") |     cdn_urls="https://cdn0.spiritlhl.top/ http://cdn3.spiritlhl.net/ http://cdn1.spiritlhl.net/ http://cdn2.spiritlhl.net/" | ||||||
|     check_cdn_file |     check_cdn_file | ||||||
|     _yellow "Warning: System update will be performed" |     _yellow "Warning: System update will be performed" | ||||||
|     _yellow "This operation may:" |     _yellow "This operation may:" | ||||||
| @@ -520,15 +549,18 @@ env_check() { | |||||||
|     _yellow "4. Affect subsequent system startups" |     _yellow "4. Affect subsequent system startups" | ||||||
|     if [ "$noninteractive" != "true" ]; then |     if [ "$noninteractive" != "true" ]; then | ||||||
|         reading "Continue with system update? (y/N): " update_confirm |         reading "Continue with system update? (y/N): " update_confirm | ||||||
|         if [[ ! $update_confirm =~ ^[Yy]$ ]]; then |         case "$update_confirm" in | ||||||
|             _yellow "Skipping system update" |             [Yy]*) | ||||||
|             _yellow "Note: Some packages may fail to install" |  | ||||||
|         else |  | ||||||
|                 _green "Updating system package manager..." |                 _green "Updating system package manager..." | ||||||
|                 if ! ${UPDATE_CMD} 2>/dev/null; then |                 if ! ${UPDATE_CMD} 2>/dev/null; then | ||||||
|                     _red "System update failed!" |                     _red "System update failed!" | ||||||
|                 fi |                 fi | ||||||
|         fi |                 ;; | ||||||
|  |             *) | ||||||
|  |                 _yellow "Skipping system update" | ||||||
|  |                 _yellow "Note: Some packages may fail to install" | ||||||
|  |                 ;; | ||||||
|  |         esac | ||||||
|     fi |     fi | ||||||
|     for cmd in sudo wget tar unzip iproute2 systemd-detect-virt dd fio; do |     for cmd in sudo wget tar unzip iproute2 systemd-detect-virt dd fio; do | ||||||
|         if ! command -v "$cmd" >/dev/null 2>&1; then |         if ! command -v "$cmd" >/dev/null 2>&1; then | ||||||
| @@ -538,44 +570,31 @@ env_check() { | |||||||
|     done |     done | ||||||
|     if ! command -v sysbench >/dev/null 2>&1; then |     if ! command -v sysbench >/dev/null 2>&1; then | ||||||
|         _green "Installing sysbench" |         _green "Installing sysbench" | ||||||
|         ${INSTALL_CMD} sysbench |         if ! ${INSTALL_CMD} sysbench; then | ||||||
|         if [ $? -ne 0 ]; then |             _red "Unable to install sysbench through package manager" | ||||||
|             echo "Unable to download sysbench through package manager, attempting compilation..." |             _yellow "Sysbench installation skipped" | ||||||
|             wget -O /tmp/sysbench.zip "${cdn_success_url}https://github.com/akopytov/sysbench/archive/1.0.20.zip" || curl -Lk -o /tmp/sysbench.zip "${cdn_success_url}https://github.com/akopytov/sysbench/archive/1.0.20.zip" |  | ||||||
|             if [ ! -f /tmp/sysbench.zip ]; then |  | ||||||
|                 wget -q -O /tmp/sysbench.zip "https://hub.fgit.cf/akopytov/sysbench/archive/1.0.20.zip" |  | ||||||
|             fi |  | ||||||
|             chmod +x /tmp/sysbench.zip |  | ||||||
|             unzip /tmp/sysbench.zip -d /tmp |  | ||||||
|             Check_SysBench |  | ||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
|     if ! command -v geekbench >/dev/null 2>&1; then |     if ! command -v geekbench >/dev/null 2>&1; then | ||||||
|         _green "Installing geekbench" |         _green "Installing geekbench" | ||||||
|         curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/cputest/main/dgb.sh" -o dgb.sh && chmod +x dgb.sh |         curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/cputest/main/dgb.sh" -o dgb.sh && chmod +x dgb.sh | ||||||
|         bash dgb.sh -v gb5 |         sh dgb.sh -v gb5 | ||||||
|         rm -rf dgb.sh |         rm -rf dgb.sh | ||||||
|     fi |     fi | ||||||
|     if ! command -v speedtest >/dev/null 2>&1; then |     if ! command -v speedtest >/dev/null 2>&1; then | ||||||
|         _green "Installing speedtest" |         _green "Installing speedtest" | ||||||
|         curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/speedtest/main/dspt.sh" -o dspt.sh && chmod +x dspt.sh |         curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/speedtest/main/dspt.sh" -o dspt.sh && chmod +x dspt.sh | ||||||
|         bash dspt.sh |         sh dspt.sh | ||||||
|         rm -rf dspt.sh |         rm -rf dspt.sh | ||||||
|         rm -rf speedtest.tar.gz |         rm -rf speedtest.tar.gz | ||||||
|     fi |     fi | ||||||
|     if ! command -v ping >/dev/null 2>&1; then |     if ! command -v ping >/dev/null 2>&1; then | ||||||
|         _green "Installing ping" |         _green "Installing ping" | ||||||
|         ${INSTALL_CMD} iputils-ping >/dev/null 2>&1 |         ${INSTALL_CMD} iputils-ping >/dev/null 2>&1 || ${INSTALL_CMD} ping >/dev/null 2>&1 | ||||||
|         ${INSTALL_CMD} ping >/dev/null 2>&1 |  | ||||||
|     fi |  | ||||||
|     if [ "$(uname -s)" = "Darwin" ]; then |  | ||||||
|         echo "Detected MacOS, installing sysbench iproute2mac..." |  | ||||||
|         brew install --force sysbench iproute2mac |  | ||||||
|     else |  | ||||||
|         if ! grep -q "^net.ipv4.ping_group_range = 0 2147483647$" /etc/sysctl.conf; then |  | ||||||
|             echo "net.ipv4.ping_group_range = 0 2147483647" >> /etc/sysctl.conf |  | ||||||
|             sysctl -p |  | ||||||
|     fi |     fi | ||||||
|  |     if ! grep -q "^net.ipv4.ping_group_range = 0 2147483647$" /etc/sysctl.conf 2>/dev/null; then | ||||||
|  |         echo "net.ipv4.ping_group_range = 0 2147483647" >> /etc/sysctl.conf 2>/dev/null | ||||||
|  |         sysctl -p >/dev/null 2>&1 | ||||||
|     fi |     fi | ||||||
|     _green "Environment preparation complete." |     _green "Environment preparation complete." | ||||||
|     _green "Next command is: ./goecs.sh install" |     _green "Next command is: ./goecs.sh install" | ||||||
| @@ -592,6 +611,7 @@ show_help() { | |||||||
| 可用命令: | 可用命令: | ||||||
|  |  | ||||||
| ./goecs.sh env            检查并安装依赖包 | ./goecs.sh env            检查并安装依赖包 | ||||||
|  |                           注意: macOS系统会自动跳过依赖安装 | ||||||
|                           警告: 此命令会执行系统更新(可选择),可能: |                           警告: 此命令会执行系统更新(可选择),可能: | ||||||
|                           1. 耗时较长 |                           1. 耗时较长 | ||||||
|                           2. 导致网络短暂中断 |                           2. 导致网络短暂中断 | ||||||
| @@ -619,6 +639,7 @@ show_help() { | |||||||
| Available commands: | Available commands: | ||||||
|  |  | ||||||
| ./goecs.sh env             Check and Install dependencies | ./goecs.sh env             Check and Install dependencies | ||||||
|  |                            Note: macOS systems will skip dependency installation | ||||||
|                            Warning: This command performs system update(optional), which may: |                            Warning: This command performs system update(optional), which may: | ||||||
|                            1. Take considerable time |                            1. Take considerable time | ||||||
|                            2. Cause temporary network interruptions |                            2. Cause temporary network interruptions | ||||||
|   | |||||||
							
								
								
									
										163
									
								
								goecs.txt
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								goecs.txt
									
									
									
									
									
								
							| @@ -1,163 +0,0 @@ | |||||||
| -------------------------------------VPS融合怪测试------------------------------------- |  | ||||||
| 版本:v0.1.80 |  | ||||||
| 测评频道: https://t.me/vps_reviews |  | ||||||
| Go项目地址:https://github.com/oneclickvirt/ecs |  | ||||||
| Shell项目地址:https://github.com/spiritLHLS/ecs |  | ||||||
| --------------------------------------系统基础信息-------------------------------------- |  | ||||||
|  CPU 型号            : AMD EPYC 7763 64-Core Processor @ 3240.186 MHz |  | ||||||
|  CPU 数量            : 2 Virtual CPU(s) |  | ||||||
|  CPU 缓存            : L1: 64 KB / L2: 512 KB / L3: 32 MB |  | ||||||
|  AES-NI              : ✔️ Enabled |  | ||||||
|  VM-x/AMD-V/Hyper-V  : ✔️ Enabled |  | ||||||
|  内存                : 3.29 GB / 7.76 GB |  | ||||||
|  气球驱动            : ❌ Undetected |  | ||||||
|  内核页合并          : ❌ Undetected |  | ||||||
|  虚拟内存 Swap       : [ no swap partition or swap file detected ] |  | ||||||
|  硬盘空间 Disk 1     : 11.97 GB / 31.33 GB [38.2%%] /dev/loop4 - /workspaces |  | ||||||
|  硬盘空间 Disk 2     : 11.97 GB / 31.33 GB [41%%] overlay - / |  | ||||||
|  硬盘空间 Disk 3     : 20.86 GB / 28.89 GB [72.2%%] /dev/sdb1 - /usr/sbin/docker-init |  | ||||||
|  启动盘路径          : overlay |  | ||||||
|  系统                : ubuntu 24.04 [x86_64]  |  | ||||||
|  内核                : 6.8.0-1030-azure |  | ||||||
|  系统在线时间        : 0 days, 00 hours, 48 minutes |  | ||||||
|  时区                : UTC |  | ||||||
|  负载                : 1.48 / 1.30 / 1.08 |  | ||||||
|  虚拟化架构          : Docker |  | ||||||
|  NAT类型             : Port Restricted Cone |  | ||||||
|  TCP加速方式         : cubic |  | ||||||
|  IPV4 ASN            : AS8075 Microsoft Corporation |  | ||||||
|  IPV4 Location       : Phoenix / Arizona / US |  | ||||||
|  IPV4 Active IPs     : 1/256 (subnet /24) 171072/1048576 (prefix /12) |  | ||||||
| --------------------------------CPU测试-通过sysbench测试-------------------------------- |  | ||||||
| 1 线程测试(单核)得分: 3270.85 |  | ||||||
| 2 线程测试(多核)得分: 3466.71 |  | ||||||
| 当前检测到系统无root权限 |  | ||||||
| --------------------------------内存测试-通过sysbench测试--------------------------------- |  | ||||||
| 内存复制速度(读+写) (MEMCPY)   :   18470.49 MB/s  |  | ||||||
| 内存复制速度(读+写) (DUMB)     :    9433.93 MB/s  |  | ||||||
| 内存复制速度(读+写) (MCBLOCK)  :   12226.22 MB/s  |  | ||||||
| -----------------------------------硬盘测试-通过fio测试----------------------------------- |  | ||||||
| 测试路径         块大小       读测试(IOPS)            写测试(IOPS)            总和(IOPS)             |  | ||||||
| /tmp              4k        18.36 MB/s(4590)        18.37 MB/s(4592)        36.73 MB/s(9182)        |  | ||||||
| /tmp              64k       100.75 MB/s(1574)       101.28 MB/s(1582)       202.04 MB/s(3156)       |  | ||||||
| /tmp              512k      98.43 MB/s(192)         103.66 MB/s(202)        202.10 MB/s(394)        |  | ||||||
| /tmp              1m        98.01 MB/s(95)          104.54 MB/s(102)        202.55 MB/s(197)        |  | ||||||
| -------------------------------------御三家流媒体解锁------------------------------------- |  | ||||||
| ----------------Netflix----------------- |  | ||||||
| [IPV4] |  | ||||||
| 您的出口IP完整解锁Netflix,支持非自制剧的观看 |  | ||||||
| NF所识别的IP地域信息:美国 |  | ||||||
| [IPV6] |  | ||||||
| 您的网络可能没有正常配置IPv6,或者没有IPv6网络接入 |  | ||||||
| ----------------Youtube----------------- |  | ||||||
| [IPV4] |  | ||||||
| 连接方式: Youtube Video Server |  | ||||||
| 视频缓存节点地域: 美国  费尼克斯(PHX18S05) |  | ||||||
| [IPV6] |  | ||||||
| Youtube在您的出口IP所在的国家不提供服务 |  | ||||||
| ---------------DisneyPlus--------------- |  | ||||||
| [IPV4] |  | ||||||
| 当前IPv4出口所在地区即将开通DisneyPlus |  | ||||||
| [IPV6] |  | ||||||
| DisneyPlus在您的出口IP所在的国家不提供服务 |  | ||||||
| --------------------------------------IP质量检测-------------------------------------- |  | ||||||
| 以下为各数据库编号,输出结果后将自带数据库来源对应的编号 |  | ||||||
| ipinfo数据库  [0] | scamalytics数据库 [1] | virustotal数据库   [2] | abuseipdb数据库   [3] | ip2location数据库    [4] |  | ||||||
| ip-api数据库  [5] | ipwhois数据库     [6] | ipregistry数据库   [7] | ipdata数据库      [8] | db-ip数据库          [9] |  | ||||||
| ipapiis数据库 [A] | ipapicom数据库    [B] | bigdatacloud数据库 [C] | dkly数据库        [D] | ipqualityscore数据库 [E] |  | ||||||
| IPV4: |  | ||||||
| 安全得分: |  | ||||||
| 声誉(越高越好): 0 [2]  |  | ||||||
| 信任得分(越高越好): 4 [8]  |  | ||||||
| VPN得分(越低越好): 87 [8]  |  | ||||||
| 代理得分(越低越好): 100 [8]  |  | ||||||
| 社区投票-无害: 0 [2]  |  | ||||||
| 社区投票-恶意: 0 [2]  |  | ||||||
| 威胁得分(越低越好): 100 [8]  |  | ||||||
| 欺诈得分(越低越好): 7 [1] 0 [E] |  | ||||||
| 滥用得分(越低越好): 0 [3]  |  | ||||||
| ASN滥用得分(越低越好): 0.0002 (Very Low) [A] |  | ||||||
| 公司滥用得分(越低越好): 0.001 (Low) [A]  |  | ||||||
| 黑名单记录统计:(有多少黑名单网站有记录): |  | ||||||
| 无害记录数: 0 [2]  恶意记录数: 0 [2]  可疑记录数: 0 [2]  无记录数: 94 [2]  |  | ||||||
| 安全信息: |  | ||||||
| 使用类型: unknown [C] business [8] hosting [0 7 A] DataCenter/WebHosting/Transit [3] |  | ||||||
| 公司类型: hosting [0 7 A]  |  | ||||||
| 是否云提供商: Yes [7 D]  |  | ||||||
| 是否数据中心: Yes [0 1 5 6 A] No [8 C] |  | ||||||
| 是否移动设备: Yes [E] No [5 A C] |  | ||||||
| 是否代理: No [0 1 4 5 6 7 8 A C D E]  |  | ||||||
| 是否VPN: Yes [A] No [0 1 6 7 C D E] |  | ||||||
| 是否Tor: No [0 1 3 6 7 8 A C D E]  |  | ||||||
| 是否Tor出口: No [1 7 D]  |  | ||||||
| 是否网络爬虫: No [A E]  |  | ||||||
| 是否匿名: No [1 6 7 8 D]  |  | ||||||
| 是否攻击者: No [7 8 D]  |  | ||||||
| 是否滥用者: No [7 8 A C D E]  |  | ||||||
| 是否威胁: No [7 8 C D]  |  | ||||||
| 是否中继: No [0 7 8 C D]  |  | ||||||
| 是否Bogon: No [7 8 A C D]  |  | ||||||
| 是否机器人: No [E]  |  | ||||||
| DNS-黑名单: 315(Total_Check) 0(Clean) 7(Blacklisted) 5(Other)  |  | ||||||
| --------------------------------------邮件端口检测-------------------------------------- |  | ||||||
| Platform  SMTP  SMTPS POP3  POP3S IMAP  IMAPS |  | ||||||
| LocalPort ✘     ✘     ✘     ✘     ✘     ✘     |  | ||||||
| QQ        ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| 163       ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| Sohu      ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| Yandex    ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| Gmail     ✔     ✔     ✘     ✘     ✘     ✘     |  | ||||||
| Outlook   ✔     ✘     ✔     ✘     ✔     ✘     |  | ||||||
| Office365 ✔     ✘     ✔     ✘     ✔     ✘     |  | ||||||
| Yahoo     ✔     ✔     ✘     ✘     ✘     ✘     |  | ||||||
| MailCOM   ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| MailRU    ✔     ✔     ✘     ✘     ✔     ✘     |  | ||||||
| AOL       ✔     ✔     ✘     ✘     ✘     ✘     |  | ||||||
| GMX       ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| Sina      ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| Apple     ✘     ✔     ✘     ✘     ✘     ✘     |  | ||||||
| FastMail  ✘     ✔     ✘     ✘     ✘     ✘     |  | ||||||
| ProtonMail✘     ✘     ✘     ✘     ✘     ✘     |  | ||||||
| MXRoute   ✔     ✘     ✔     ✘     ✔     ✘     |  | ||||||
| Namecrane ✔     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| XYAMail   ✘     ✘     ✘     ✘     ✘     ✘     |  | ||||||
| ZohoMail  ✘     ✔     ✘     ✘     ✘     ✘     |  | ||||||
| Inbox_eu  ✔     ✔     ✔     ✘     ✘     ✘     |  | ||||||
| Free_fr   ✘     ✔     ✔     ✘     ✔     ✘     |  | ||||||
| -------------------------------------三网回程路由检测------------------------------------- |  | ||||||
|       AS174             AS1299            AS2914            AS3320            AS3356       |  | ||||||
|       Cogent           Arelion             NTT               DTAG             Lumen        |  | ||||||
|    Tier1 Global      Tier1 Global      Tier1 Global      Tier1 Global      Tier1 Global    |  | ||||||
|       AS3491            AS5511            AS6453            AS6461            AS6762       |  | ||||||
|        PCCW             Orange             Tata              Zayo            Sparkle       |  | ||||||
|    Tier1 Global      Tier1 Global      Tier1 Global      Tier1 Global      Tier1 Global    |  | ||||||
|       AS6830            AS7018           AS12956           AS38561       |  | ||||||
|      Liberty             AT&T            Telxius      NTT Australia Solu |  | ||||||
|    Tier1 Global      Tier1 Global      Tier1 Global         Direct       |  | ||||||
| 北京电信v4 219.141.140.10  检测不到回程路由节点的IP地址 |  | ||||||
| 北京联通v4 202.106.195.68  检测不到回程路由节点的IP地址 |  | ||||||
| 北京移动v4 221.179.155.161 检测不到回程路由节点的IP地址 |  | ||||||
| 上海电信v4 202.96.209.133  检测不到回程路由节点的IP地址 |  | ||||||
| 上海联通v4 210.22.97.1     检测不到回程路由节点的IP地址 |  | ||||||
| 上海移动v4 211.136.112.200 检测不到回程路由节点的IP地址 |  | ||||||
| 广州电信v4 58.60.188.222   检测不到回程路由节点的IP地址 |  | ||||||
| 广州联通v4 210.21.196.6    检测不到回程路由节点的IP地址 |  | ||||||
| 广州移动v4 120.196.165.24  检测不到回程路由节点的IP地址 |  | ||||||
| 成都电信v4 61.139.2.69     检测不到回程路由节点的IP地址 |  | ||||||
| 成都联通v4 119.6.6.6       检测不到回程路由节点的IP地址 |  | ||||||
| 成都移动v4 211.137.96.205  检测不到回程路由节点的IP地址 |  | ||||||
| 准确线路自行查看详细路由,本测试结果仅作参考 |  | ||||||
| 同一目标地址多个线路时,检测可能已越过汇聚层,除第一个线路外,后续信息可能无效 |  | ||||||
| --------------------------------------就近节点测速-------------------------------------- |  | ||||||
| 位置            上传速度        下载速度        延迟            丢包率           |  | ||||||
| Speedtest.net   6055.91 Mbps    7818.00 Mbps    1.681117ms      0.00% (Sent: 402/Dup: 0/Max: 401) |  | ||||||
| 洛杉矶          4894.61 Mbps    5487.50 Mbps    9.737482ms      N/A              |  | ||||||
| 法兰克福        318.88 Mbps     771.78 Mbps     136.733082ms    N/A              |  | ||||||
| 联通上海5G      152.10 Mbps     0.09 Mbps       191.466132ms    N/A              |  | ||||||
| 电信Suzhou5G    322.77 Mbps     628.40 Mbps     193.44033ms     N/A              |  | ||||||
| 电信Zhenjiang5G 1.73 Mbps       442.39 Mbps     241.704896ms    N/A              |  | ||||||
| 移动Suzhou      151.14 Mbps     0.71 Mbps       203.451132ms    N/A              |  | ||||||
| ---------------------------------------------------------------------------------- |  | ||||||
| 花费          : 8 分 3 秒 |  | ||||||
| 时间          : Mon Aug 11 13:16:04 UTC 2025 |  | ||||||
| ---------------------------------------------------------------------------------- |  | ||||||
| @@ -8,27 +8,78 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func MemoryTest(language, testMethod string) (realTestMethod, res string) { | func MemoryTest(language, testMethod string) (realTestMethod, res string) { | ||||||
|  | 	testMethod = strings.ToLower(testMethod) | ||||||
|  | 	if testMethod == "" { | ||||||
|  | 		testMethod = "auto" | ||||||
|  | 	} | ||||||
| 	if runtime.GOOS == "windows" { | 	if runtime.GOOS == "windows" { | ||||||
| 		if testMethod != "winsat" && testMethod != "" { | 		switch testMethod { | ||||||
|  | 		case "stream": | ||||||
|  | 			res = memory.WinsatTest(language) | ||||||
|  | 			realTestMethod = "winsat" | ||||||
|  | 		case "dd": | ||||||
|  | 			res = memory.WindowsDDTest(language) | ||||||
|  | 			if res == "" || strings.TrimSpace(res) == "" { | ||||||
|  | 				res += memory.WinsatTest(language) | ||||||
|  | 				realTestMethod = "winsat" | ||||||
|  | 			} else { | ||||||
|  | 				realTestMethod = "dd" | ||||||
|  | 			} | ||||||
|  | 		case "sysbench": | ||||||
|  | 			res = memory.WinsatTest(language) | ||||||
|  | 			realTestMethod = "winsat" | ||||||
|  | 		case "auto", "winsat": | ||||||
|  | 			res = memory.WinsatTest(language) | ||||||
|  | 			realTestMethod = "winsat" | ||||||
|  | 		default: | ||||||
|  | 			res = memory.WinsatTest(language) | ||||||
| 			realTestMethod = "winsat" | 			realTestMethod = "winsat" | ||||||
| 		} | 		} | ||||||
| 		res += memory.WinsatTest(language) |  | ||||||
| 	} else { | 	} else { | ||||||
| 		switch testMethod { | 		switch testMethod { | ||||||
|  | 		case "stream": | ||||||
|  | 			res = memory.StreamTest(language) | ||||||
|  | 			if res == "" || strings.TrimSpace(res) == "" { | ||||||
|  | 				res += memory.DDTest(language) | ||||||
|  | 				realTestMethod = "dd" | ||||||
|  | 			} else { | ||||||
|  | 				realTestMethod = "stream" | ||||||
|  | 			} | ||||||
|  | 		case "dd": | ||||||
|  | 			res = memory.DDTest(language) | ||||||
|  | 			realTestMethod = "dd" | ||||||
| 		case "sysbench": | 		case "sysbench": | ||||||
| 			res = memory.SysBenchTest(language) | 			res = memory.SysBenchTest(language) | ||||||
| 			if res == "" { | 			if res == "" || strings.TrimSpace(res) == "" { | ||||||
| 				res += memory.DDTest(language) | 				res += memory.DDTest(language) | ||||||
| 				realTestMethod = "dd" | 				realTestMethod = "dd" | ||||||
| 			} else { | 			} else { | ||||||
| 				realTestMethod = "sysbench" | 				realTestMethod = "sysbench" | ||||||
| 			} | 			} | ||||||
| 		case "dd": | 		case "auto": | ||||||
|  | 			res = memory.StreamTest(language) | ||||||
|  | 			if res == "" || strings.TrimSpace(res) == "" { | ||||||
|  | 				res = memory.DDTest(language) | ||||||
|  | 				if res == "" || strings.TrimSpace(res) == "" { | ||||||
|  | 					res = memory.SysBenchTest(language) | ||||||
|  | 					if res == "" || strings.TrimSpace(res) == "" { | ||||||
|  | 						realTestMethod = "" | ||||||
|  | 					} else { | ||||||
|  | 						realTestMethod = "sysbench" | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					realTestMethod = "dd" | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				realTestMethod = "stream" | ||||||
|  | 			} | ||||||
|  | 		case "winsat": | ||||||
|  | 			// winsat 仅 Windows 支持,非 Windows fallback 到 dd | ||||||
| 			res = memory.DDTest(language) | 			res = memory.DDTest(language) | ||||||
| 			realTestMethod = "dd" | 			realTestMethod = "dd" | ||||||
| 		default: | 		default: | ||||||
| 			res += memory.DDTest(language) | 			res = "Unsupported test method" | ||||||
| 			realTestMethod = "dd" | 			realTestMethod = "" | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if !strings.Contains(res, "\n") && res != "" { | 	if !strings.Contains(res, "\n") && res != "" { | ||||||
|   | |||||||
| @@ -6,6 +6,6 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func Test(t *testing.T) { | func Test(t *testing.T) { | ||||||
| 	_, res := MemoryTest("zh", "sysbench") | 	_, res := MemoryTest("zh", "stream") | ||||||
| 	fmt.Print(res) | 	fmt.Print(res) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -56,13 +56,13 @@ func PrintHead(language string, width int, ecsVersion string) { | |||||||
| 	if language == "zh" { | 	if language == "zh" { | ||||||
| 		PrintCenteredTitle("VPS融合怪测试", width) | 		PrintCenteredTitle("VPS融合怪测试", width) | ||||||
| 		fmt.Printf("版本:%s\n", ecsVersion) | 		fmt.Printf("版本:%s\n", ecsVersion) | ||||||
| 		fmt.Println("测评频道: https://t.me/vps_reviews\n" + | 		fmt.Println("测评频道: https://t.me/+UHVoo2U4VyA5NTQ1\n" + | ||||||
| 			"Go项目地址:https://github.com/oneclickvirt/ecs\n" + | 			"Go项目地址:https://github.com/oneclickvirt/ecs\n" + | ||||||
| 			"Shell项目地址:https://github.com/spiritLHLS/ecs") | 			"Shell项目地址:https://github.com/spiritLHLS/ecs") | ||||||
| 	} else { | 	} else { | ||||||
| 		PrintCenteredTitle("VPS Fusion Monster Test", width) | 		PrintCenteredTitle("VPS Fusion Monster Test", width) | ||||||
| 		fmt.Printf("Version: %s\n", ecsVersion) | 		fmt.Printf("Version: %s\n", ecsVersion) | ||||||
| 		fmt.Println("Review Channel: https://t.me/vps_reviews\n" + | 		fmt.Println("Review Channel: https://t.me/+UHVoo2U4VyA5NTQ1\n" + | ||||||
| 			"Go Project: https://github.com/oneclickvirt/ecs\n" + | 			"Go Project: https://github.com/oneclickvirt/ecs\n" + | ||||||
| 			"Shell Project: https://github.com/spiritLHLS/ecs") | 			"Shell Project: https://github.com/spiritLHLS/ecs") | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user