CodeReview/scripts/setup_security_tools.sh

942 lines
28 KiB
Bash
Raw Normal View History

#!/bin/bash
#
# DeepAudit 安全工具一键安装脚本 (增强版)
# 自动安装沙盒和外部安全扫描工具
#
# 特性:
# - 多种安装方式自动回退
# - 网络问题自动重试
# - 详细的错误诊断
# - 支持代理设置
# - 虚拟环境兼容
#
set -e
# ============================================================
# 配置
# ============================================================
# 版本配置
GITLEAKS_VERSION="8.18.4"
OSV_SCANNER_VERSION="1.8.3"
TRUFFLEHOG_VERSION="3.80.0"
# 重试配置
MAX_RETRIES=3
RETRY_DELAY=2
# 超时配置
DOWNLOAD_TIMEOUT=60
INSTALL_TIMEOUT=120
# 获取脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# 工具安装目录
TOOLS_DIR="$HOME/.local/bin"
mkdir -p "$TOOLS_DIR"
# ============================================================
# 颜色和日志
# ============================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
log_info() { echo -e "${BLUE}${NC} $1"; }
log_success() { echo -e "${GREEN}${NC} $1"; }
log_warning() { echo -e "${YELLOW}!${NC} $1"; }
log_error() { echo -e "${RED}${NC} $1"; }
log_debug() { [[ "$VERBOSE" == "1" ]] && echo -e "${CYAN} $1${NC}"; }
log_header() {
echo ""
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo ""
}
# ============================================================
# 工具函数
# ============================================================
# 检查命令是否存在且可执行
command_exists() {
command -v "$1" &> /dev/null || return 1
# 额外检查:确保命令真的能运行(排除 pyenv shim 等假阳性)
case "$1" in
semgrep) "$1" --version &> /dev/null ;;
bandit) "$1" --version &> /dev/null ;;
safety) "$1" --version &> /dev/null ;;
gitleaks) "$1" version &> /dev/null ;;
osv-scanner) "$1" --version &> /dev/null ;;
trufflehog) "$1" --version &> /dev/null ;;
*) return 0 ;;
esac
}
# 检测操作系统
detect_os() {
if [[ "$OSTYPE" == "darwin"* ]]; then
OS="macos"
ARCH=$(uname -m)
if [[ "$ARCH" == "arm64" ]]; then
ARCH_TYPE="arm64"
else
ARCH_TYPE="x64"
fi
elif [[ -f /etc/debian_version ]]; then
OS="debian"
ARCH_TYPE=$(dpkg --print-architecture 2>/dev/null || echo "amd64")
elif [[ -f /etc/redhat-release ]]; then
OS="redhat"
ARCH_TYPE=$(uname -m)
else
OS="linux"
ARCH_TYPE=$(uname -m)
fi
# 标准化架构名称
case "$ARCH_TYPE" in
x86_64|amd64) ARCH_TYPE="x64" ;;
aarch64|arm64) ARCH_TYPE="arm64" ;;
esac
log_info "检测到系统: $OS ($ARCH_TYPE)"
}
# 检测 Python 环境
detect_python() {
PYTHON_CMD=""
PIP_CMD=""
# 优先使用虚拟环境
if [[ -n "$VIRTUAL_ENV" ]]; then
log_info "检测到虚拟环境: $VIRTUAL_ENV"
PYTHON_CMD="python"
PIP_CMD="pip"
# 检查 python3
elif command_exists python3; then
PYTHON_CMD="python3"
if command_exists pip3; then
PIP_CMD="pip3"
else
PIP_CMD="python3 -m pip"
fi
# 检查 python
elif command_exists python; then
PYTHON_CMD="python"
if command_exists pip; then
PIP_CMD="pip"
else
PIP_CMD="python -m pip"
fi
else
log_error "未找到 Python请先安装 Python 3.8+"
return 1
fi
# 验证 Python 版本
PYTHON_VERSION=$($PYTHON_CMD --version 2>&1 | grep -oE '[0-9]+\.[0-9]+')
log_info "Python 版本: $PYTHON_VERSION (命令: $PYTHON_CMD)"
log_debug "pip 命令: $PIP_CMD"
# 确保 pip 可用
if ! $PIP_CMD --version &>/dev/null; then
log_warning "pip 不可用,尝试安装..."
$PYTHON_CMD -m ensurepip --upgrade 2>/dev/null || true
fi
return 0
}
# 带重试的下载函数
download_with_retry() {
local url="$1"
local output="$2"
local description="$3"
for attempt in $(seq 1 $MAX_RETRIES); do
log_info "下载 $description (尝试 $attempt/$MAX_RETRIES)..."
if command_exists curl; then
if curl -fsSL --connect-timeout 10 --max-time $DOWNLOAD_TIMEOUT -o "$output" "$url" 2>/dev/null; then
log_success "$description 下载成功"
return 0
fi
elif command_exists wget; then
if wget -q --timeout=$DOWNLOAD_TIMEOUT -O "$output" "$url" 2>/dev/null; then
log_success "$description 下载成功"
return 0
fi
else
log_error "未找到 curl 或 wget"
return 1
fi
log_warning "下载失败,${RETRY_DELAY}秒后重试..."
sleep $RETRY_DELAY
done
log_error "$description 下载失败 (已重试 $MAX_RETRIES 次)"
return 1
}
# 带重试的 pip 安装
pip_install_with_retry() {
local package="$1"
for attempt in $(seq 1 $MAX_RETRIES); do
log_info "安装 $package (尝试 $attempt/$MAX_RETRIES)..."
# 尝试方式 1: 普通安装
if $PIP_CMD install "$package" --timeout 60 2>&1; then
log_success "$package 安装成功"
return 0
fi
# 尝试方式 2: --user 标志
log_debug "尝试 --user 安装..."
if $PIP_CMD install "$package" --user --timeout 60 2>&1; then
log_success "$package 安装成功 (--user)"
return 0
fi
# 尝试方式 3: --break-system-packages (Python 3.11+ PEP 668)
log_debug "尝试 --break-system-packages..."
if $PIP_CMD install "$package" --break-system-packages --timeout 60 2>&1; then
log_success "$package 安装成功 (--break-system-packages)"
return 0
fi
# 尝试升级 pip 后重试
if [[ $attempt -eq 1 ]]; then
log_debug "升级 pip 后重试..."
$PIP_CMD install --upgrade pip --quiet 2>/dev/null || true
fi
sleep $RETRY_DELAY
done
# 尝试方式 4: 使用 pipx (推荐的 CLI 工具安装方式)
if command -v pipx &> /dev/null; then
log_info "尝试使用 pipx 安装 $package..."
if pipx install "$package" 2>&1; then
log_success "$package 安装成功 (pipx)"
return 0
fi
fi
log_error "$package 安装失败"
return 1
}
# 添加到 PATH
add_to_path() {
local dir="$1"
# 当前会话
if [[ ":$PATH:" != *":$dir:"* ]]; then
export PATH="$dir:$PATH"
fi
# 持久化到 shell 配置
local shell_rc=""
if [[ -f "$HOME/.zshrc" ]]; then
shell_rc="$HOME/.zshrc"
elif [[ -f "$HOME/.bashrc" ]]; then
shell_rc="$HOME/.bashrc"
elif [[ -f "$HOME/.bash_profile" ]]; then
shell_rc="$HOME/.bash_profile"
fi
if [[ -n "$shell_rc" ]]; then
if ! grep -q "$dir" "$shell_rc" 2>/dev/null; then
echo "export PATH=\"$dir:\$PATH\"" >> "$shell_rc"
log_debug "已添加 $dir$shell_rc"
fi
fi
}
# ============================================================
# Python 工具安装
# ============================================================
install_python_tools() {
log_header "安装 Python 安全工具"
detect_python || return 1
local tools=("bandit" "safety")
local failed=()
local installed=()
# Semgrep 单独处理(较大)
log_info "检查 semgrep..."
if command_exists semgrep; then
log_success "semgrep 已安装: $(semgrep --version 2>&1 | head -1)"
else
# 尝试 pip 安装
if pip_install_with_retry "semgrep"; then
installed+=("semgrep")
# macOS: 尝试 brew 安装
elif [[ "$OS" == "macos" ]] && command -v brew &> /dev/null; then
log_info "pip 安装失败,尝试 brew install semgrep..."
if brew install semgrep 2>&1; then
installed+=("semgrep")
log_success "semgrep 安装成功 (brew)"
else
failed+=("semgrep")
fi
else
failed+=("semgrep")
log_warning "semgrep 安装失败,可尝试: brew install semgrep (macOS)"
fi
fi
# 安装其他工具
for tool in "${tools[@]}"; do
log_info "检查 $tool..."
if command_exists "$tool"; then
log_success "$tool 已安装"
else
if pip_install_with_retry "$tool"; then
installed+=("$tool")
else
failed+=("$tool")
fi
fi
done
# 可选: TruffleHog
if [[ "$INSTALL_OPTIONAL" == "1" ]] || [[ "$INTERACTIVE" == "1" ]]; then
if [[ "$INTERACTIVE" == "1" ]]; then
read -p "是否安装 TruffleHog (高级密钥扫描约100MB)? [y/N] " -n 1 -r
echo
fi
if [[ "$INSTALL_OPTIONAL" == "1" ]] || [[ $REPLY =~ ^[Yy]$ ]]; then
if command_exists trufflehog; then
log_success "trufflehog 已安装"
else
pip_install_with_retry "trufflehog" || failed+=("trufflehog")
fi
fi
fi
# 报告结果
echo ""
if [[ ${#installed[@]} -gt 0 ]]; then
log_success "已安装: ${installed[*]}"
fi
if [[ ${#failed[@]} -gt 0 ]]; then
log_warning "安装失败: ${failed[*]}"
log_info "💡 提示: 可尝试使用 pipx 安装: pipx install <package>"
log_info " 或使用虚拟环境: python3 -m venv venv && source venv/bin/activate && pip install <package>"
return 1
fi
return 0
}
# ============================================================
# 系统工具安装 (macOS)
# ============================================================
install_macos_tools() {
log_header "安装 macOS 系统工具"
local failed=()
local installed=()
# 检查/安装 Homebrew
if ! command_exists brew; then
log_warning "Homebrew 未安装"
if [[ "$INTERACTIVE" == "1" ]]; then
read -p "是否安装 Homebrew? [Y/n] " -n 1 -r
echo
[[ $REPLY =~ ^[Nn]$ ]] && return 1
fi
log_info "安装 Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || {
log_error "Homebrew 安装失败"
log_info "尝试使用二进制方式安装工具..."
install_binary_tools
return $?
}
# 配置 Homebrew PATH (Apple Silicon)
if [[ -f "/opt/homebrew/bin/brew" ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
fi
log_success "Homebrew 可用: $(brew --version | head -1)"
# Gitleaks
log_info "检查 gitleaks..."
if command_exists gitleaks; then
log_success "gitleaks 已安装: $(gitleaks version 2>&1 | head -1)"
else
log_info "安装 gitleaks..."
if brew install gitleaks 2>/dev/null; then
installed+=("gitleaks")
log_success "gitleaks 安装成功"
else
log_warning "brew 安装失败,尝试二进制安装..."
install_gitleaks_binary || failed+=("gitleaks")
fi
fi
# OSV-Scanner
log_info "检查 osv-scanner..."
if command_exists osv-scanner; then
log_success "osv-scanner 已安装"
else
log_info "安装 osv-scanner..."
if brew install osv-scanner 2>/dev/null; then
installed+=("osv-scanner")
log_success "osv-scanner 安装成功"
else
log_warning "brew 安装失败,尝试二进制安装..."
install_osv_scanner_binary || failed+=("osv-scanner")
fi
fi
# 可选: TruffleHog (brew)
if [[ "$INSTALL_OPTIONAL" == "1" ]]; then
if ! command_exists trufflehog; then
log_info "安装 trufflehog (brew)..."
brew install trufflehog 2>/dev/null || log_warning "trufflehog brew 安装失败"
fi
fi
# 报告结果
echo ""
if [[ ${#installed[@]} -gt 0 ]]; then
log_success "已安装: ${installed[*]}"
fi
if [[ ${#failed[@]} -gt 0 ]]; then
log_warning "安装失败: ${failed[*]}"
return 1
fi
return 0
}
# ============================================================
# 二进制工具安装 (回退方案)
# ============================================================
install_binary_tools() {
log_info "使用二进制方式安装工具..."
install_gitleaks_binary
install_osv_scanner_binary
}
install_gitleaks_binary() {
log_info "下载 Gitleaks 二进制..."
local arch_suffix=""
case "$OS-$ARCH_TYPE" in
macos-x64) arch_suffix="darwin_x64" ;;
macos-arm64) arch_suffix="darwin_arm64" ;;
*-x64) arch_suffix="linux_x64" ;;
*-arm64) arch_suffix="linux_arm64" ;;
*) arch_suffix="linux_x64" ;;
esac
local url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_${arch_suffix}.tar.gz"
local tmp_file="/tmp/gitleaks.tar.gz"
if download_with_retry "$url" "$tmp_file" "Gitleaks"; then
tar -xzf "$tmp_file" -C "$TOOLS_DIR" gitleaks 2>/dev/null || {
# 某些版本可能没有子目录
tar -xzf "$tmp_file" -C "/tmp" 2>/dev/null
mv /tmp/gitleaks "$TOOLS_DIR/" 2>/dev/null || true
}
chmod +x "$TOOLS_DIR/gitleaks"
rm -f "$tmp_file"
add_to_path "$TOOLS_DIR"
log_success "Gitleaks 二进制安装成功"
return 0
fi
return 1
}
install_osv_scanner_binary() {
log_info "下载 OSV-Scanner 二进制..."
local arch_suffix=""
case "$OS-$ARCH_TYPE" in
macos-x64) arch_suffix="darwin_amd64" ;;
macos-arm64) arch_suffix="darwin_arm64" ;;
*-x64) arch_suffix="linux_amd64" ;;
*-arm64) arch_suffix="linux_arm64" ;;
*) arch_suffix="linux_amd64" ;;
esac
local url="https://github.com/google/osv-scanner/releases/download/v${OSV_SCANNER_VERSION}/osv-scanner_${arch_suffix}"
local target="$TOOLS_DIR/osv-scanner"
if download_with_retry "$url" "$target" "OSV-Scanner"; then
chmod +x "$target"
add_to_path "$TOOLS_DIR"
log_success "OSV-Scanner 二进制安装成功"
return 0
fi
return 1
}
install_trufflehog_binary() {
log_info "下载 TruffleHog 二进制..."
local arch_suffix=""
case "$OS-$ARCH_TYPE" in
macos-x64) arch_suffix="darwin_amd64" ;;
macos-arm64) arch_suffix="darwin_arm64" ;;
*-x64) arch_suffix="linux_amd64" ;;
*-arm64) arch_suffix="linux_arm64" ;;
*) arch_suffix="linux_amd64" ;;
esac
local url="https://github.com/trufflesecurity/trufflehog/releases/download/v${TRUFFLEHOG_VERSION}/trufflehog_${TRUFFLEHOG_VERSION}_${arch_suffix}.tar.gz"
local tmp_file="/tmp/trufflehog.tar.gz"
if download_with_retry "$url" "$tmp_file" "TruffleHog"; then
tar -xzf "$tmp_file" -C "$TOOLS_DIR" trufflehog 2>/dev/null || {
tar -xzf "$tmp_file" -C "/tmp" 2>/dev/null
mv /tmp/trufflehog "$TOOLS_DIR/" 2>/dev/null || true
}
chmod +x "$TOOLS_DIR/trufflehog"
rm -f "$tmp_file"
add_to_path "$TOOLS_DIR"
log_success "TruffleHog 二进制安装成功"
return 0
fi
return 1
}
# ============================================================
# Linux 工具安装
# ============================================================
install_linux_tools() {
log_header "安装 Linux 系统工具"
# 直接使用二进制安装(最可靠)
install_binary_tools
}
# ============================================================
# Docker 沙盒安装
# ============================================================
install_docker_sandbox() {
log_header "配置 Docker 沙盒"
# 检查 Docker
if ! command_exists docker; then
log_error "Docker 未安装!"
log_info "macOS: brew install --cask docker"
log_info "Linux: https://docs.docker.com/engine/install/"
return 1
fi
# 检查 Docker 是否运行
if ! docker info &> /dev/null; then
log_error "Docker 未运行!请启动 Docker。"
# macOS: 尝试启动 Docker Desktop
if [[ "$OS" == "macos" ]]; then
log_info "尝试启动 Docker Desktop..."
open -a Docker 2>/dev/null || true
log_info "等待 Docker 启动 (最多 60 秒)..."
for i in {1..12}; do
sleep 5
if docker info &> /dev/null; then
log_success "Docker 已启动"
break
fi
echo -n "."
done
echo ""
if ! docker info &> /dev/null; then
log_error "Docker 启动超时,请手动启动 Docker Desktop"
return 1
fi
else
return 1
fi
fi
log_success "Docker 已运行"
# 构建沙盒镜像
local sandbox_dir="$PROJECT_ROOT/docker/sandbox"
local dockerfile="$sandbox_dir/Dockerfile"
if [[ ! -f "$dockerfile" ]]; then
log_warning "沙盒 Dockerfile 不存在,创建默认配置..."
mkdir -p "$sandbox_dir"
create_sandbox_dockerfile "$sandbox_dir"
fi
log_info "构建 DeepAudit 沙盒镜像..."
cd "$sandbox_dir"
# 带重试的构建
for attempt in $(seq 1 $MAX_RETRIES); do
log_info "构建镜像 (尝试 $attempt/$MAX_RETRIES)..."
if docker build -t deepaudit-sandbox:latest -f Dockerfile . 2>&1; then
log_success "沙盒镜像构建成功: deepaudit-sandbox:latest"
# 验证
log_info "验证沙盒镜像..."
if docker run --rm deepaudit-sandbox:latest python3 --version; then
log_success "Python 环境正常"
fi
if docker run --rm deepaudit-sandbox:latest node --version 2>/dev/null; then
log_success "Node.js 环境正常"
fi
return 0
fi
log_warning "构建失败,重试..."
sleep $RETRY_DELAY
done
log_error "沙盒镜像构建失败"
return 1
}
create_sandbox_dockerfile() {
local dir="$1"
cat > "$dir/Dockerfile" << 'EOF'
# DeepAudit 安全沙盒
FROM python:3.11-slim-bookworm
# 安装基础工具
RUN apt-get update && apt-get install -y --no-install-recommends \
curl wget netcat-openbsd dnsutils iputils-ping ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
# 安装 Node.js 20
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
# 创建非特权用户
RUN groupadd -g 1000 sandbox \
&& useradd -u 1000 -g sandbox -m -s /bin/bash sandbox
# 安装 Python 安全测试库
RUN pip install --no-cache-dir \
requests httpx aiohttp beautifulsoup4 lxml \
pycryptodome paramiko pyjwt python-jose sqlparse
# 设置工作目录
WORKDIR /workspace
RUN mkdir -p /workspace /tmp/sandbox \
&& chown -R sandbox:sandbox /workspace /tmp/sandbox
USER sandbox
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 HOME=/home/sandbox
CMD ["/bin/bash"]
EOF
log_success "已创建沙盒 Dockerfile"
}
# ============================================================
# 验证安装
# ============================================================
verify_installation() {
log_header "验证安装结果"
local tools=(
"semgrep:Semgrep 静态分析"
"bandit:Bandit Python安全"
"safety:Safety 依赖漏洞"
"gitleaks:Gitleaks 密钥检测"
"osv-scanner:OSV-Scanner 漏洞"
"trufflehog:TruffleHog 密钥"
"npm:NPM Audit"
"docker:Docker"
)
local installed=0
local total=${#tools[@]}
echo ""
printf "%-18s %-12s %-30s\n" "工具" "状态" "版本/路径"
echo "────────────────────────────────────────────────────────────"
for tool_info in "${tools[@]}"; do
IFS=':' read -r tool desc <<< "$tool_info"
if command_exists "$tool"; then
local version=""
case "$tool" in
semgrep) version=$(semgrep --version 2>&1 | head -1) ;;
bandit) version=$(bandit --version 2>&1 | head -1) ;;
safety) version=$(safety --version 2>&1 | head -1) ;;
gitleaks) version=$(gitleaks version 2>&1 | head -1) ;;
osv-scanner) version=$(osv-scanner --version 2>&1 | head -1) ;;
trufflehog) version=$(trufflehog --version 2>&1 | head -1) ;;
npm) version=$(npm --version 2>&1) ;;
docker) version=$(docker --version 2>&1 | cut -d' ' -f3) ;;
esac
version="${version:0:28}"
printf "%-18s ${GREEN}%-12s${NC} %-30s\n" "$tool" "已安装" "$version"
((installed++))
else
printf "%-18s ${YELLOW}%-12s${NC} %-30s\n" "$tool" "未安装" "-"
fi
done
echo "────────────────────────────────────────────────────────────"
# Docker 沙盒检查
if command_exists docker && docker info &>/dev/null; then
if docker image inspect deepaudit-sandbox:latest &>/dev/null; then
echo ""
log_success "Docker 沙盒镜像: deepaudit-sandbox:latest ✓"
else
echo ""
log_warning "Docker 沙盒镜像未构建"
fi
fi
echo ""
log_info "安装统计: $installed/$total 个工具可用"
# 检查 PATH
if [[ ":$PATH:" != *":$TOOLS_DIR:"* ]]; then
log_warning "请重启终端或运行: source ~/.zshrc (或 ~/.bashrc)"
fi
if [[ $installed -ge 5 ]]; then
log_success "核心安全工具已就绪!"
return 0
else
log_warning "部分工具未安装,某些功能可能受限"
return 1
fi
}
# ============================================================
# 更新环境配置
# ============================================================
update_env_config() {
log_header "更新环境配置"
local env_file="$PROJECT_ROOT/backend/.env"
if [[ ! -f "$env_file" ]]; then
log_warning ".env 文件不存在,跳过配置更新"
return 0
fi
if grep -q "SANDBOX_IMAGE" "$env_file"; then
log_info "沙盒配置已存在于 .env 文件中"
else
log_info "添加沙盒配置到 .env 文件..."
cat >> "$env_file" << 'EOF'
# =============================================
# 沙盒配置 (自动添加)
# =============================================
SANDBOX_IMAGE=deepaudit-sandbox:latest
SANDBOX_MEMORY_LIMIT=512m
SANDBOX_CPU_LIMIT=1.0
SANDBOX_TIMEOUT=60
SANDBOX_NETWORK_MODE=none
EOF
log_success "沙盒配置已添加到 .env"
fi
}
# ============================================================
# 显示帮助
# ============================================================
show_help() {
cat << 'EOF'
DeepAudit 安全工具一键安装脚本
用法:
./setup_security_tools.sh [选项]
选项:
-a, --all 全部安装 (默认交互式)
-p, --python 仅安装 Python 工具
-s, --system 仅安装系统工具
-d, --docker 仅构建 Docker 沙盒
-v, --verify 仅验证安装状态
-o, --optional 包含可选工具 (TruffleHog)
--verbose 显示详细输出
-h, --help 显示帮助
示例:
./setup_security_tools.sh # 交互式安装
./setup_security_tools.sh -a # 自动全部安装
./setup_security_tools.sh -a -o # 全部安装 + 可选工具
./setup_security_tools.sh -v # 仅检查状态
EOF
}
# ============================================================
# 主函数
# ============================================================
main() {
# 解析参数
INTERACTIVE="1"
INSTALL_ALL=""
INSTALL_PYTHON=""
INSTALL_SYSTEM=""
INSTALL_DOCKER=""
VERIFY_ONLY=""
INSTALL_OPTIONAL=""
VERBOSE=""
while [[ $# -gt 0 ]]; do
case $1 in
-a|--all) INSTALL_ALL="1"; INTERACTIVE="" ;;
-p|--python) INSTALL_PYTHON="1"; INTERACTIVE="" ;;
-s|--system) INSTALL_SYSTEM="1"; INTERACTIVE="" ;;
-d|--docker) INSTALL_DOCKER="1"; INTERACTIVE="" ;;
-v|--verify) VERIFY_ONLY="1"; INTERACTIVE="" ;;
-o|--optional) INSTALL_OPTIONAL="1" ;;
--verbose) VERBOSE="1" ;;
-h|--help) show_help; exit 0 ;;
*) log_error "未知选项: $1"; show_help; exit 1 ;;
esac
shift
done
# 显示标题
echo ""
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}║ 🔐 DeepAudit 安全工具一键安装脚本 (增强版) ║${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
# 检测系统
detect_os
# 仅验证模式
if [[ "$VERIFY_ONLY" == "1" ]]; then
verify_installation
exit $?
fi
# 自动安装模式
if [[ "$INSTALL_ALL" == "1" ]]; then
install_python_tools
if [[ "$OS" == "macos" ]]; then
install_macos_tools
else
install_linux_tools
fi
install_docker_sandbox
update_env_config
verify_installation
exit $?
fi
# 单独安装模式
if [[ "$INSTALL_PYTHON" == "1" ]]; then
install_python_tools
verify_installation
exit $?
fi
if [[ "$INSTALL_SYSTEM" == "1" ]]; then
if [[ "$OS" == "macos" ]]; then
install_macos_tools
else
install_linux_tools
fi
verify_installation
exit $?
fi
if [[ "$INSTALL_DOCKER" == "1" ]]; then
install_docker_sandbox
update_env_config
verify_installation
exit $?
fi
# 交互式模式
echo "请选择要安装的组件:"
echo " 1) 全部安装 (推荐)"
echo " 2) 仅 Python 工具 (pip)"
echo " 3) 仅系统工具 (brew/binary)"
echo " 4) 仅 Docker 沙盒"
echo " 5) 仅验证安装状态"
echo " 6) 退出"
echo ""
read -p "请输入选项 [1-6]: " choice
case $choice in
1)
install_python_tools
if [[ "$OS" == "macos" ]]; then
install_macos_tools
else
install_linux_tools
fi
install_docker_sandbox
update_env_config
verify_installation
;;
2) install_python_tools; verify_installation ;;
3)
if [[ "$OS" == "macos" ]]; then
install_macos_tools
else
install_linux_tools
fi
verify_installation
;;
4) install_docker_sandbox; update_env_config; verify_installation ;;
5) verify_installation ;;
6) echo "退出"; exit 0 ;;
*) log_error "无效选项"; exit 1 ;;
esac
log_header "安装完成"
echo ""
echo "下一步操作:"
echo " 1. 重启终端使 PATH 生效"
echo " 2. 启动后端: cd backend && uvicorn app.main:app --reload"
echo " 3. 在 Agent 审计中测试工具"
echo ""
}
main "$@"