diff --git a/install.sh b/install.sh index bc03a2d..01a76b8 100755 --- a/install.sh +++ b/install.sh @@ -81,7 +81,6 @@ detect_fastest_mirror() { # Ubuntu/Debian 镜像源列表 UBUNTU_MIRRORS=( "mirrors.tuna.tsinghua.edu.cn" - "mirrors.ustc.edu.cn" "mirrors.huaweicloud.com" "mirrors.163.com" "archive.ubuntu.com" @@ -90,7 +89,6 @@ detect_fastest_mirror() { # CentOS/RHEL 镜像源列表 CENTOS_MIRRORS=( "mirrors.tuna.tsinghua.edu.cn" - "mirrors.ustc.edu.cn" "mirrors.huaweicloud.com" ) @@ -826,71 +824,73 @@ build_from_source() { sudo bash -c "cd '$SOURCE_DIR' && $GO_PATH_ENV && go env -w GOSUMDB=off" 2>/dev/null || true sudo bash -c "cd '$SOURCE_DIR' && $GO_PATH_ENV && go env -w GOPRIVATE=*" 2>/dev/null || true - # 使用后台进程显示实时进度 + # 使用命名管道来实时监控输出 + PIPE_FILE="/tmp/go_download_pipe_$$" + mkfifo "$PIPE_FILE" 2>/dev/null || true + + # 后台进程显示实时进度 ( DOWNLOADED_COUNT=0 - LAST_UPDATE_TIME=$(date +%s) LAST_COUNT=0 LAST_PACKAGE="" + PACKAGES=() - while [ ! -f "${DOWNLOAD_PROGRESS_LOG}.done" ]; do - sleep 1 - - # 统计已下载的包数量(从日志中统计) - if [ -f "$DOWNLOAD_LOG" ]; then - CURRENT_COUNT=$(grep -c "go: downloading" "$DOWNLOAD_LOG" 2>/dev/null || echo "0") - else - CURRENT_COUNT=0 + # 从管道读取输出并实时显示 + while IFS= read -r line || [ -n "$line" ]; do + # 检查是否结束 + if [ -f "${DOWNLOAD_PROGRESS_LOG}.done" ]; then + break fi - if [ "$CURRENT_COUNT" -gt "$LAST_COUNT" ]; then - DOWNLOADED_COUNT=$CURRENT_COUNT + # 检测下载消息 + if echo "$line" | grep -q "go: downloading"; then + DOWNLOADED_COUNT=$((DOWNLOADED_COUNT + 1)) CURRENT_TIME=$(date +%s) ELAPSED=$((CURRENT_TIME - DOWNLOAD_START_TIME)) - # 计算速度(每秒下载的包数) - if [ "$ELAPSED" -gt 0 ]; then - SPEED=$(echo "scale=2; $DOWNLOADED_COUNT / $ELAPSED" | bc 2>/dev/null || echo "0") - echo -ne "\r${BLUE}进度: 已下载 ${GREEN}${DOWNLOADED_COUNT}${NC} 个包 | 耗时: ${ELAPSED}秒 | 速度: ${GREEN}${SPEED}${NC} 包/秒" - fi - - LAST_COUNT=$CURRENT_COUNT - LAST_UPDATE_TIME=$CURRENT_TIME - fi - - # 显示当前正在下载的包 - if [ -f "$DOWNLOAD_LOG" ]; then - CURRENT_PACKAGE=$(grep "go: downloading" "$DOWNLOAD_LOG" 2>/dev/null | tail -1 | sed 's/go: downloading //' | cut -d' ' -f1) - if [ -n "$CURRENT_PACKAGE" ] && [ "$CURRENT_PACKAGE" != "$LAST_PACKAGE" ]; then - echo "" - echo -e "${BLUE} → 正在下载: ${GREEN}${CURRENT_PACKAGE}${NC}" - LAST_PACKAGE=$CURRENT_PACKAGE + # 提取包名 + PACKAGE_NAME=$(echo "$line" | sed 's/go: downloading //' | cut -d' ' -f1) + if [ -n "$PACKAGE_NAME" ] && [ "$PACKAGE_NAME" != "$LAST_PACKAGE" ]; then + PACKAGES+=("$PACKAGE_NAME") + LAST_PACKAGE=$PACKAGE_NAME + + # 计算速度 + if [ "$ELAPSED" -gt 0 ]; then + SPEED=$(echo "scale=2; $DOWNLOADED_COUNT / $ELAPSED" | bc 2>/dev/null || echo "0") + else + SPEED="0" + fi + + # 显示进度(使用 \r 在同一行更新) + echo -ne "\r${BLUE}进度: 已下载 ${GREEN}${DOWNLOADED_COUNT}${NC} 个包 | 耗时: ${ELAPSED}秒 | 速度: ${GREEN}${SPEED}${NC} 包/秒 | 当前: ${GREEN}${PACKAGE_NAME}${NC} " fi fi + done < "$PIPE_FILE" & + + # 等待主进程结束 + while [ ! -f "${DOWNLOAD_PROGRESS_LOG}.done" ]; do + sleep 0.5 done ) & PROGRESS_PID=$! - # 使用 -json 格式下载,便于解析进度(同时输出到终端和文件) - if sudo bash -c "cd '$SOURCE_DIR' && $GO_ENV && timeout 600 go mod download -json" 2>&1 | tee "$DOWNLOAD_LOG"; then + # 使用 -x 标志下载,显示详细输出,同时写入日志和管道 + if sudo bash -c "cd '$SOURCE_DIR' && $GO_ENV && timeout 600 go mod download -x" 2>&1 | tee "$DOWNLOAD_LOG" "$PIPE_FILE"; then # 停止进度显示进程 touch "${DOWNLOAD_PROGRESS_LOG}.done" - sleep 1 + sleep 2 kill "$PROGRESS_PID" 2>/dev/null || true wait "$PROGRESS_PID" 2>/dev/null || true + # 清理管道文件 + rm -f "$PIPE_FILE" 2>/dev/null || true + DOWNLOAD_END_TIME=$(date +%s) DOWNLOAD_DURATION=$((DOWNLOAD_END_TIME - DOWNLOAD_START_TIME)) - # 统计下载信息(从 JSON 输出中解析) - TOTAL_PACKAGES=$(grep -c '"Path":' "$DOWNLOAD_LOG" 2>/dev/null || echo "0") - SUCCESS_COUNT=$(grep -c '"Version":' "$DOWNLOAD_LOG" 2>/dev/null || echo "0") - - # 如果没有 JSON 格式,尝试从普通输出统计 - if [ "$TOTAL_PACKAGES" = "0" ]; then - TOTAL_PACKAGES=$(grep -c "go: downloading" "$DOWNLOAD_LOG" 2>/dev/null || echo "0") - SUCCESS_COUNT=$TOTAL_PACKAGES - fi + # 统计下载信息(从输出中统计) + TOTAL_PACKAGES=$(grep -c "go: downloading" "$DOWNLOAD_LOG" 2>/dev/null || echo "0") + SUCCESS_COUNT=$(grep -c "go: downloading" "$DOWNLOAD_LOG" 2>/dev/null || echo "0") echo "" echo -e "${GREEN}✓ 依赖下载完成${NC}" @@ -906,16 +906,19 @@ build_from_source() { # 显示最后下载的几个包 echo -e "${BLUE}最后下载的包:${NC}" - grep '"Path":' "$DOWNLOAD_LOG" | tail -10 | sed 's/.*"Path": "\([^"]*\)".*/ ✓ \1/' | while IFS= read -r line; do + grep "go: downloading" "$DOWNLOAD_LOG" 2>/dev/null | tail -10 | sed 's/go: downloading \([^ ]*\).*/ ✓ \1/' | while IFS= read -r line; do echo "$line" done || true else # 停止进度显示进程 touch "${DOWNLOAD_PROGRESS_LOG}.done" - sleep 1 + sleep 2 kill "$PROGRESS_PID" 2>/dev/null || true wait "$PROGRESS_PID" 2>/dev/null || true + # 清理管道文件 + rm -f "$PIPE_FILE" 2>/dev/null || true + DOWNLOAD_EXIT_CODE=$? DOWNLOAD_END_TIME=$(date +%s) DOWNLOAD_DURATION=$((DOWNLOAD_END_TIME - DOWNLOAD_START_TIME)) @@ -974,8 +977,55 @@ build_from_source() { ) & PROGRESS_PID2=$! + # 重新创建管道 + rm -f "$PIPE_FILE" 2>/dev/null || true + mkfifo "$PIPE_FILE" 2>/dev/null || true + + # 重新启动进度显示 + ( + DOWNLOADED_COUNT=0 + LAST_COUNT=0 + LAST_PACKAGE="" + + while IFS= read -r line || [ -n "$line" ]; do + if [ -f "${DOWNLOAD_PROGRESS_LOG}.done2" ]; then + break + fi + + if echo "$line" | grep -q "go: downloading"; then + DOWNLOADED_COUNT=$((DOWNLOADED_COUNT + 1)) + CURRENT_TIME=$(date +%s) + ELAPSED=$((CURRENT_TIME - DOWNLOAD_START_TIME)) + + PACKAGE_NAME=$(echo "$line" | sed 's/go: downloading //' | cut -d' ' -f1) + if [ -n "$PACKAGE_NAME" ] && [ "$PACKAGE_NAME" != "$LAST_PACKAGE" ]; then + LAST_PACKAGE=$PACKAGE_NAME + + if [ "$ELAPSED" -gt 0 ]; then + SPEED=$(echo "scale=2; $DOWNLOADED_COUNT / $ELAPSED" | bc 2>/dev/null || echo "0") + else + SPEED="0" + fi + + echo -ne "\r${BLUE}进度: 已下载 ${GREEN}${DOWNLOADED_COUNT}${NC} 个包 | 耗时: ${ELAPSED}秒 | 速度: ${GREEN}${SPEED}${NC} 包/秒 | 当前: ${GREEN}${PACKAGE_NAME}${NC} " + fi + fi + done < "$PIPE_FILE" & + + while [ ! -f "${DOWNLOAD_PROGRESS_LOG}.done2" ]; do + sleep 0.5 + done + ) & + PROGRESS_PID2=$! + DOWNLOAD_START_TIME=$(date +%s) - if sudo bash -c "cd '$SOURCE_DIR' && $GO_ENV && timeout 600 go mod download -json" > "$DOWNLOAD_LOG" 2>&1; then + if sudo bash -c "cd '$SOURCE_DIR' && $GO_ENV && timeout 600 go mod download -x" 2>&1 | tee "$DOWNLOAD_LOG" "$PIPE_FILE"; then + # 停止进度显示进程 + touch "${DOWNLOAD_PROGRESS_LOG}.done2" + sleep 2 + kill "$PROGRESS_PID2" 2>/dev/null || true + wait "$PROGRESS_PID2" 2>/dev/null || true + rm -f "$PIPE_FILE" 2>/dev/null || true # 停止进度显示进程 touch "$DOWNLOAD_PROGRESS_LOG.done2" sleep 1