feat: unify environment scripts with start.sh

- Add unified start.sh script with subcommands (all/backend/frontend)
- Add process management (--stop, --status)
- Remove separate start_backend.sh and start_frontend.sh
- Update setup_dev_env.sh with pre-flight checks and --cpu-only/--skip-db options
- Update .env.example to remove sensitive data and add DIFY translation config
- Add .pid/ to .gitignore for process management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-02 12:48:52 +08:00
parent a07aad96b3
commit d7f7166a2d
11 changed files with 875 additions and 360 deletions

View File

@@ -1,31 +1,258 @@
#!/bin/bash
# Tool_OCR WSL Ubuntu 開發環境設置腳本
#
# Usage:
# ./setup_dev_env.sh 完整安裝 (自動偵測 GPU)
# ./setup_dev_env.sh --cpu-only 強制使用 CPU 版本
# ./setup_dev_env.sh --skip-db 跳過數據庫初始化
# ./setup_dev_env.sh --help 顯示幫助
set -e # 遇到錯誤時停止
echo "================================"
echo "Tool_OCR 開發環境設置"
echo "================================"
echo ""
# 顏色定義
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 檢查是否為 root
if [ "$EUID" -eq 0 ]; then
echo -e "${RED}請不要使用 sudo 運行此腳本${NC}"
echo "腳本會在需要時提示輸入 sudo 密碼"
exit 1
fi
# 配置變數
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MIN_DISK_GB=10
MIN_MEMORY_GB=4
MIN_PYTHON_VERSION="3.10"
FORCE_CPU=false
SKIP_DB=false
echo -e "${YELLOW}[1/8] 更新系統套件列表...${NC}"
# ===== 幫助信息 =====
show_help() {
echo "Tool_OCR 開發環境設置腳本"
echo ""
echo "Usage: ./setup_dev_env.sh [options]"
echo ""
echo "Options:"
echo " --cpu-only 強制使用 CPU 版本的 PaddlePaddle (跳過 GPU 偵測)"
echo " --skip-db 跳過數據庫初始化步驟"
echo " --help 顯示此幫助信息"
echo ""
echo "Examples:"
echo " ./setup_dev_env.sh # 完整安裝"
echo " ./setup_dev_env.sh --cpu-only # 不使用 GPU"
echo ""
}
# 解析參數
while [[ $# -gt 0 ]]; do
case $1 in
--cpu-only)
FORCE_CPU=true
shift
;;
--skip-db)
SKIP_DB=true
shift
;;
--help|-h)
show_help
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
show_help
exit 1
;;
esac
done
# ===== 工具函數 =====
print_header() {
echo ""
echo -e "${BLUE}================================${NC}"
echo -e "${BLUE} Tool_OCR 開發環境設置${NC}"
echo -e "${BLUE}================================${NC}"
echo ""
}
print_step() {
local step=$1
local total=$2
local msg=$3
echo ""
echo -e "${YELLOW}[$step/$total] $msg${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
# ===== 預檢函數 =====
check_not_root() {
if [ "$EUID" -eq 0 ]; then
print_error "請不要使用 sudo 運行此腳本"
echo "腳本會在需要時提示輸入 sudo 密碼"
exit 1
fi
}
check_disk_space() {
local available_gb=$(df -BG "$SCRIPT_DIR" | awk 'NR==2 {print $4}' | sed 's/G//')
if [ "$available_gb" -lt "$MIN_DISK_GB" ]; then
print_error "磁碟空間不足: ${available_gb}GB 可用, 需要至少 ${MIN_DISK_GB}GB"
echo ""
echo "解決方案:"
echo " 1. 清理不需要的文件: sudo apt autoremove && sudo apt clean"
echo " 2. 刪除舊的 Docker 映像: docker system prune -a"
echo " 3. 清理 pip 緩存: pip cache purge"
exit 1
fi
print_success "磁碟空間: ${available_gb}GB 可用"
}
check_memory() {
local total_gb=$(free -g | awk '/^Mem:/{print $2}')
if [ "$total_gb" -lt "$MIN_MEMORY_GB" ]; then
print_warning "記憶體較低: ${total_gb}GB (建議 ${MIN_MEMORY_GB}GB+)"
echo " OCR 處理可能會較慢,建議增加記憶體或使用 swap"
else
print_success "系統記憶體: ${total_gb}GB"
fi
}
check_python_version() {
if ! command -v python3 &> /dev/null; then
print_error "未找到 Python3"
echo ""
echo "解決方案:"
echo " sudo apt update && sudo apt install python3 python3-pip python3-venv"
exit 1
fi
local py_version=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
local py_major=$(echo $py_version | cut -d. -f1)
local py_minor=$(echo $py_version | cut -d. -f2)
local min_major=$(echo $MIN_PYTHON_VERSION | cut -d. -f1)
local min_minor=$(echo $MIN_PYTHON_VERSION | cut -d. -f2)
if [ "$py_major" -lt "$min_major" ] || ([ "$py_major" -eq "$min_major" ] && [ "$py_minor" -lt "$min_minor" ]); then
print_error "Python 版本過低: $py_version (需要 $MIN_PYTHON_VERSION+)"
echo ""
echo "解決方案:"
echo " sudo apt update && sudo apt install python3.10 python3.10-venv"
exit 1
fi
print_success "Python 版本: $py_version"
}
run_preflight_checks() {
echo -e "${BLUE}執行預檢...${NC}"
check_not_root
check_disk_space
check_memory
check_python_version
echo ""
print_success "預檢完成"
}
# ===== GPU 偵測函數 =====
detect_gpu() {
if [ "$FORCE_CPU" = true ]; then
echo -e "${YELLOW} 已指定 --cpu-only跳過 GPU 偵測${NC}"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
return
fi
if command -v nvidia-smi &> /dev/null; then
print_success "偵測到 NVIDIA GPU"
nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || true
CUDA_VERSION=$(nvidia-smi 2>/dev/null | grep "CUDA Version" | awk '{print $9}')
if [ -n "$CUDA_VERSION" ]; then
print_success "CUDA 版本: $CUDA_VERSION"
CUDA_MAJOR=$(echo $CUDA_VERSION | cut -d. -f1)
if [ "$CUDA_MAJOR" -ge 12 ]; then
echo "將安裝 PaddlePaddle GPU 版本 (CUDA 12.x)"
USE_GPU=true
PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1"
PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu123/"
elif [ "$CUDA_MAJOR" -eq 11 ]; then
echo "將安裝 PaddlePaddle GPU 版本 (CUDA 11.x)"
USE_GPU=true
PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1"
PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu118/"
else
print_warning "CUDA 版本不支援 ($CUDA_VERSION),將使用 CPU 版本"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
fi
else
print_warning "無法獲取 CUDA 版本,將使用 CPU 版本"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
fi
else
echo -e "${YELLOW} 未偵測到 NVIDIA GPU將使用 CPU 版本${NC}"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
fi
}
# ===== 數據庫初始化 =====
init_database() {
if [ "$SKIP_DB" = true ]; then
print_warning "已指定 --skip-db跳過數據庫初始化"
return
fi
echo "初始化數據庫..."
cd "$SCRIPT_DIR/backend"
# 檢查 .env.local 是否存在
if [ ! -f "$SCRIPT_DIR/.env.local" ]; then
print_warning "未找到 .env.local跳過數據庫初始化"
echo " 請複製 .env.example 到 .env.local 並配置後,手動執行:"
echo " cd backend && alembic upgrade head"
cd "$SCRIPT_DIR"
return
fi
# 載入環境變量
export $(grep -v '^#' "$SCRIPT_DIR/.env.local" | xargs)
# 執行遷移
if alembic upgrade head 2>/dev/null; then
print_success "數據庫遷移完成"
else
print_warning "數據庫遷移失敗 (可能數據庫未連接)"
echo " 請確認 .env.local 中的數據庫配置正確後,手動執行:"
echo " cd backend && alembic upgrade head"
fi
cd "$SCRIPT_DIR"
}
# ===== 主流程 =====
print_header
# 預檢
run_preflight_checks
# Step 1: 更新系統
print_step 1 10 "更新系統套件列表..."
sudo apt update
echo ""
echo -e "${YELLOW}[2/8] 安裝 Python 開發工具...${NC}"
# Step 2: Python 開發工具
print_step 2 10 "安裝 Python 開發工具..."
sudo apt install -y \
python3-pip \
python3-venv \
@@ -33,8 +260,8 @@ sudo apt install -y \
build-essential \
pkg-config
echo ""
echo -e "${YELLOW}[3/8] 安裝系統層級依賴...${NC}"
# Step 3: 系統依賴
print_step 3 10 "安裝系統層級依賴..."
sudo apt install -y \
pandoc \
libmagic1 \
@@ -71,270 +298,125 @@ sudo apt install -y \
libxslt1-dev \
python3-cffi
echo ""
echo -e "${YELLOW}[4/8] 安裝 Node.js 和 npm...${NC}"
# 檢查是否已安裝 nvm
# Step 4: Node.js
print_step 4 10 "安裝 Node.js..."
if [ ! -d "$HOME/.nvm" ]; then
echo "安裝 nvm..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 載入 nvm
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
else
echo "nvm 已安裝"
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
fi
# 安裝 Node.js LTS
echo "安裝 Node.js LTS..."
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install --lts
nvm use --lts
print_success "Node.js $(node -v) 已安裝"
echo ""
echo -e "${YELLOW}[5/8] 創建 Python 虛擬環境...${NC}"
if [ ! -d "venv" ]; then
python3 -m venv venv
echo "虛擬環境已創建"
# Step 5: Python 虛擬環境
print_step 5 10 "創建 Python 虛擬環境..."
if [ ! -d "$SCRIPT_DIR/venv" ]; then
python3 -m venv "$SCRIPT_DIR/venv"
print_success "虛擬環境已創建"
else
echo "虛擬環境已存在"
print_success "虛擬環境已存在"
fi
echo ""
echo -e "${YELLOW}[6/9] 偵測 GPU 和 CUDA 支援...${NC}"
# GPU 偵測函數
detect_gpu() {
# 檢查是否有 NVIDIA GPU
if command -v nvidia-smi &> /dev/null; then
echo -e "${GREEN}✓ 偵測到 NVIDIA GPU${NC}"
nvidia-smi --query-gpu=name,memory.total --format=csv,noheader
# 獲取 CUDA 版本
CUDA_VERSION=$(nvidia-smi | grep "CUDA Version" | awk '{print $9}')
if [ -n "$CUDA_VERSION" ]; then
echo -e "${GREEN}✓ CUDA 版本: $CUDA_VERSION${NC}"
# 根據 CUDA 版本選擇對應的 PaddlePaddle
CUDA_MAJOR=$(echo $CUDA_VERSION | cut -d. -f1)
CUDA_MINOR=$(echo $CUDA_VERSION | cut -d. -f2)
if [ "$CUDA_MAJOR" -ge 13 ]; then
echo "將安裝 PaddlePaddle GPU 版本 (CUDA 13.x)"
echo "使用版本 3.2.1+ (兼容 CUDA 12.6+, 支援圖表識別)"
USE_GPU=true
PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1"
PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu126/"
elif [ "$CUDA_MAJOR" -eq 12 ]; then
echo "將安裝 PaddlePaddle GPU 版本 (CUDA 12.x)"
echo "使用版本 3.2.1+ (兼容 CUDA 12.3+, 支援圖表識別)"
USE_GPU=true
PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1"
PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu123/"
elif [ "$CUDA_MAJOR" -eq 11 ]; then
echo "將安裝 PaddlePaddle GPU 版本 (CUDA 11.x)"
echo "使用版本 3.2.1+ (兼容 CUDA 11.8+, 支援圖表識別)"
USE_GPU=true
PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1"
PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu118/"
else
echo -e "${YELLOW}⚠ CUDA 版本不支援 ($CUDA_VERSION)${NC}"
echo "將安裝 CPU 版本"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
fi
else
echo -e "${YELLOW}⚠ 無法獲取 CUDA 版本${NC}"
echo "將安裝 CPU 版本"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
fi
else
echo -e "${YELLOW} 未偵測到 NVIDIA GPU 或 nvidia-smi${NC}"
echo "將安裝 CPU 版本的 PaddlePaddle"
USE_GPU=false
PADDLE_PACKAGE="paddlepaddle>=3.2.1"
fi
}
# 執行 GPU 偵測
# Step 6: GPU 偵測
print_step 6 10 "偵測 GPU 支援..."
detect_gpu
echo ""
echo -e "${YELLOW}[7/9] 安裝 Python 依賴...${NC}"
source venv/bin/activate
# Step 7: Python 依賴
print_step 7 10 "安裝 Python 依賴..."
source "$SCRIPT_DIR/venv/bin/activate"
pip install --upgrade pip setuptools wheel
# 先安裝 PaddlePaddle
echo ""
echo -e "${YELLOW}安裝 PaddlePaddle...${NC}"
echo "安裝 PaddlePaddle..."
if [ "$USE_GPU" = true ]; then
echo "安裝 GPU 加速版本: $PADDLE_PACKAGE"
if [ -n "$PADDLE_INDEX" ]; then
echo "使用官方索引: $PADDLE_INDEX"
pip install "$PADDLE_PACKAGE" -i "$PADDLE_INDEX"
else
pip install "$PADDLE_PACKAGE"
echo "安裝 GPU 版本: $PADDLE_PACKAGE"
pip install "$PADDLE_PACKAGE" -i "$PADDLE_INDEX"
# WSL CUDA 路徑配置
if grep -qi microsoft /proc/version && [ -d "/usr/lib/wsl/lib" ]; then
if ! grep -q "export LD_LIBRARY_PATH=/usr/lib/wsl/lib" ~/.bashrc; then
echo "" >> ~/.bashrc
echo "# WSL CUDA Libraries Path (Added by Tool_OCR setup)" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=/usr/lib/wsl/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc
fi
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
print_success "WSL CUDA 路徑已配置"
fi
else
echo "安裝 CPU 版本..."
pip install 'paddlepaddle>=3.2.1'
fi
# WSL CUDA 路徑配置 (針對 WSL GPU 用戶)
if [ "$USE_GPU" = true ]; then
echo ""
echo -e "${YELLOW}配置 WSL CUDA 庫路徑...${NC}"
# 檢查是否在 WSL 環境中
if grep -qi microsoft /proc/version; then
echo "偵測到 WSL 環境,配置 CUDA 庫路徑..."
# 檢查 CUDA 庫是否存在於 WSL 路徑
if [ -d "/usr/lib/wsl/lib" ]; then
# 檢查 ~/.bashrc 中是否已包含此配置
if ! grep -q "export LD_LIBRARY_PATH=/usr/lib/wsl/lib" ~/.bashrc; then
echo "" >> ~/.bashrc
echo "# WSL CUDA Libraries Path for PaddlePaddle GPU support (Added by Tool_OCR setup)" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=/usr/lib/wsl/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc
echo "✓ 已將 WSL CUDA 路徑添加到 ~/.bashrc"
else
echo "✓ WSL CUDA 路徑已存在於 ~/.bashrc"
fi
# 立即應用到當前 session
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
echo "✓ 已應用 CUDA 路徑到當前環境"
else
echo -e "${YELLOW}⚠ 未找到 /usr/lib/wsl/lib 目錄${NC}"
echo "請確認 NVIDIA CUDA 驅動已安裝於 WSL"
fi
else
echo "非 WSL 環境,跳過 WSL CUDA 路徑配置"
fi
fi
# 安裝其他依賴(跳過 requirements.txt 中的 paddlepaddle
echo ""
echo -e "${YELLOW}安裝其他 Python 依賴...${NC}"
pip install -r requirements.txt
echo "安裝其他 Python 依賴..."
pip install -r "$SCRIPT_DIR/requirements.txt"
echo ""
echo -e "${YELLOW}測試關鍵套件...${NC}"
python -c "import magic; print('✓ python-magic')" || echo "python-magic failed"
python -c "from weasyprint import HTML; print('✓ WeasyPrint')" || echo "WeasyPrint failed"
python -c "import cv2; print('✓ OpenCV')" || echo "OpenCV failed"
# Step 8: 驗證安裝
print_step 8 10 "驗證安裝..."
python -c "import magic; print('✓ python-magic')" || print_warning "python-magic 未正確安裝"
python -c "from weasyprint import HTML; print('✓ WeasyPrint')" || print_warning "WeasyPrint 未正確安裝"
python -c "import cv2; print('✓ OpenCV')" || print_warning "OpenCV 未正確安裝"
python -c "import paddle; print('✓ PaddlePaddle', paddle.__version__)" || print_warning "PaddlePaddle 未正確安裝"
# 驗證 PaddlePaddle GPU 可用性
echo ""
echo -e "${YELLOW}驗證 PaddlePaddle 設置...${NC}"
python -c "
import paddle
print('✓ PaddlePaddle 版本:', paddle.__version__)
try:
if paddle.is_compiled_with_cuda():
gpu_count = paddle.device.cuda.device_count()
if gpu_count > 0:
print('✓ GPU 加速: 已啟用')
print('✓ GPU 數量:', gpu_count)
for i in range(gpu_count):
gpu_name = paddle.device.cuda.get_device_properties(i).name
print(f' GPU {i}: {gpu_name}')
else:
print(' GPU 加速: CUDA 已編譯但無可用 GPU')
else:
print(' GPU 加速: 未啟用 (CPU 模式)')
except Exception as e:
print('⚠ GPU 檢測失敗:', str(e))
print(' 將使用 CPU 模式')
" || echo "⚠ PaddlePaddle 驗證失敗,但可繼續使用"
# Step 9: 前端依賴
print_step 9 10 "安裝前端依賴..."
cd "$SCRIPT_DIR/frontend"
# 驗證圖表識別 API 可用性
echo ""
echo -e "${YELLOW}驗證圖表識別 API...${NC}"
python -c "
import paddle.incubate.nn.functional as F
# 檢查 API 可用性
has_base = hasattr(F, 'fused_rms_norm')
has_ext = hasattr(F, 'fused_rms_norm_ext')
print('📊 圖表識別 API 檢查:')
print(f' - fused_rms_norm: {'✅ 可用' if has_base else '❌ 不可用'}')
print(f' - fused_rms_norm_ext: {'✅ 可用' if has_ext else '❌ 不可用'}')
if has_ext:
print('🎉 圖表識別功能: ✅ 可啟用')
else:
print('⚠️ 圖表識別功能: ❌ 不可用 (需要 PaddlePaddle 3.2.0+)')
" || echo "⚠ 圖表識別 API 驗證失敗"
echo ""
echo -e "${YELLOW}[8/9] 安裝前端依賴...${NC}"
cd frontend
# 清理可能存在的鎖定文件
if [ -d "node_modules" ]; then
echo "清理現有 node_modules..."
rm -rf node_modules package-lock.json
fi
# 清理 npm 緩存
npm cache clean --force
# 安裝依賴(使用 --force 避免鎖定問題)
echo "安裝前端依賴..."
npm install --force
cd ..
cd "$SCRIPT_DIR"
print_success "前端依賴已安裝"
echo ""
echo -e "${YELLOW}[9/9] 創建必要的目錄...${NC}"
# Step 10: 創建目錄和初始化數據庫
print_step 10 10 "創建目錄和初始化數據庫..."
mkdir -p backend/uploads/{temp,processed,images}
mkdir -p backend/storage/{markdown,json,exports}
mkdir -p backend/storage/{markdown,json,exports,results}
mkdir -p backend/models/paddleocr
mkdir -p backend/logs
init_database
# ===== 完成 =====
echo ""
echo -e "${GREEN}================================${NC}"
echo -e "${GREEN}環境設置完成!${NC}"
echo -e "${GREEN} 環境設置完成!${NC}"
echo -e "${GREEN}================================${NC}"
echo ""
echo "系統配置:"
if [ "$USE_GPU" = true ]; then
echo -e " GPU 加速: ${GREEN}已啟用${NC}"
echo " PaddlePaddle: GPU 版本 (3.2.1+)"
echo -e " 圖表識別: ${GREEN}已啟用${NC}"
if grep -qi microsoft /proc/version; then
echo " WSL CUDA 路徑: 已配置於 ~/.bashrc"
fi
echo " PaddlePaddle: GPU 版本"
else
echo -e " GPU 加速: ${YELLOW}未啟用 (CPU 模式)${NC}"
echo " PaddlePaddle: CPU 版本 (3.2.1+)"
echo -e " 圖表識別: ${GREEN}已啟用${NC} (CPU 模式)"
echo " PaddlePaddle: CPU 版本"
fi
echo ""
echo "下一步操作:"
echo "1. 初始化數據庫:"
echo " source venv/bin/activate"
echo " cd backend"
echo " alembic upgrade head"
echo " python create_test_user.py"
echo " cd .."
echo ""
echo "2. 啟動後端:"
echo " ./start_backend.sh"
echo "1. 配置環境變量 (如尚未配置):"
echo " cp .env.example .env.local"
echo " # 編輯 .env.local 填入實際配置"
echo ""
echo "3. 啟動前端 (新終端):"
echo " ./start_frontend.sh"
echo "2. 啟動應用:"
echo " ./start.sh # 同時啟動前後端"
echo " ./start.sh backend # 僅啟動後端"
echo " ./start.sh frontend # 僅啟動前端"
echo ""
echo "4. 訪問應用:"
echo "3. 訪問應用:"
echo " 前端: http://localhost:5173"
echo " API文檔: http://localhost:8000/docs"
echo " 健康檢查: http://localhost:8000/health"
echo ""
if [ "$USE_GPU" = true ] && grep -qi microsoft /proc/version; then
echo "注意: WSL GPU 用戶需要重新啟動終端或執行 'source ~/.bashrc' 以應用 CUDA 路徑配置"
echo -e "${YELLOW}注意: WSL GPU 用戶需要重新啟動終端以應用 CUDA 路徑配置${NC}"
echo ""
fi