#!/bin/bash set -e # 初始化变量 OPERATION="" VERSION="" DOCKER_PACKAGES="docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin" # 提取版本号(如从"5:28.4.0-1~ubuntu.24.04~noble"中提取"28.4.0") EXTRACT_VERSION=$(echo "$VERSION" | awk -F'[:-]' '{print $2}') # 打印步骤信息(仅关键流程) print_step() { echo -e "\033[1;34m[*] $1\033[0m" } # 打印成功信息(最终结果) print_success() { echo -e "\033[1;32m[+] $1\033[0m" } # 打印错误信息(仅报错时显示) print_error() { echo -e "\033[1;31m[-] 错误:$1\033[0m" >&2 } # 解析命令行参数 parse_args() { while [[ $# -gt 0 ]]; do case "$1" in --install) OPERATION="install" shift ;; --uninstall) OPERATION="uninstall" shift ;; --version) if [[ -n "$2" && "$2" != --* ]]; then VERSION="$2" EXTRACT_VERSION=$(echo "$VERSION" | awk -F'[:-]' '{print $2}') # 提前提取版本号 shift 2 else print_error "缺少版本号,请用 --version 指定(如 5:28.4.0-1~ubuntu.24.04~noble)" exit 1 fi ;; *) print_error "未知参数:$1" exit 1 ;; esac done # 验证必要参数 if [[ -z "$OPERATION" ]]; then print_error "请指定操作:--install(安装) 或 --uninstall(卸载)" exit 1 fi if [[ -z "$VERSION" ]]; then print_error "请用 --version 指定Docker版本" exit 1 fi } # 安装必要依赖(屏蔽冗余日志,仅捕错) install_dependencies() { print_step "正在安装依赖工具" # apt-get 静默执行,日志重定向到/dev/null,仅保留错误输出 if ! apt-get update -qq >/dev/null 2>&1; then print_error "更新软件源失败" exit 1 fi if ! apt-get install -qq -y ca-certificates curl gnupg lsb-release >/dev/null 2>&1; then print_error "安装依赖(ca-certificates/curl等)失败" exit 1 fi print_success "依赖工具安装完成" } # 添加Docker GPG密钥(自动覆盖,屏蔽日志) add_gpg_key() { print_step "正在添加Docker GPG密钥" mkdir -p /etc/apt/keyrings # curl+gpg 静默执行,自动覆盖现有文件 if ! curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg >/dev/null 2>&1; then print_error "添加GPG密钥失败(网络或密钥地址异常)" exit 1 fi print_success "GPG密钥添加完成" } # 添加Docker源(屏蔽日志) add_docker_repo() { print_step "正在配置Docker软件源" # 写入源配置,更新源时静默执行 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null 2>&1 if ! apt-get update -qq >/dev/null 2>&1; then print_error "更新Docker软件源失败" exit 1 fi print_success "Docker软件源配置完成" } # 安装指定版本Docker(核心:屏蔽安装日志,仅显结果/错误) install_docker() { print_step "正在安装Docker $EXTRACT_VERSION(版本号:$VERSION)" # 构建安装命令:仅docker-ce/cli指定版本,其他包默认最新(兼容依赖) install_cmd="apt-get install -qq -y" for pkg in $DOCKER_PACKAGES; do if [[ $pkg == "docker-ce" || $pkg == "docker-ce-cli" ]]; then install_cmd="$install_cmd $pkg=$VERSION" else install_cmd="$install_cmd $pkg" fi done # 静默安装:日志重定向,仅捕获错误 if ! eval $install_cmd >/dev/null 2>&1; then print_error "Docker安装失败(可能版本不兼容或网络问题)" exit 1 fi # 启动并设置开机自启(静默处理) if ! systemctl is-active --quiet docker; then if ! systemctl start docker >/dev/null 2>&1; then print_error "Docker服务启动失败" exit 1 fi fi if ! systemctl is-enabled --quiet docker; then systemctl enable docker >/dev/null 2>&1 fi # 最终验证 if ! docker --version >/dev/null 2>&1; then print_error "Docker安装后验证失败(命令不可用)" exit 1 fi print_success "Docker $EXTRACT_VERSION 安装成功!" } # 卸载指定版本Docker(屏蔽日志) uninstall_docker() { print_step "正在卸载Docker $EXTRACT_VERSION(版本号:$VERSION)" # 停止服务(静默) if systemctl is-active --quiet docker; then if ! systemctl stop docker >/dev/null 2>&1; then print_error "Docker服务停止失败" exit 1 fi fi # 构建卸载命令:仅指定docker-ce/cli版本,其他包全卸载 uninstall_cmd="apt-get purge -qq -y" for pkg in $DOCKER_PACKAGES; do if [[ $pkg == "docker-ce" || $pkg == "docker-ce-cli" ]]; then uninstall_cmd="$uninstall_cmd $pkg=$VERSION" else uninstall_cmd="$uninstall_cmd $pkg" fi done # 静默卸载,清理残留 if ! eval $uninstall_cmd >/dev/null 2>&1; then print_error "Docker卸载失败(可能包依赖冲突)" exit 1 fi # 清理数据目录(屏蔽日志) rm -rf /var/lib/docker /var/lib/containerd >/dev/null 2>&1 print_success "Docker $EXTRACT_VERSION 卸载成功!" } # 主函数(入口) main() { # 检查root权限 if [[ $EUID -ne 0 ]]; then print_error "请用root用户运行脚本(sudo bash docker.sh ...)" exit 1 fi parse_args "$@" # 根据操作分支执行 case "$OPERATION" in install) install_dependencies add_gpg_key add_docker_repo install_docker ;; uninstall) uninstall_docker ;; *) print_error "未知操作:$OPERATION" exit 1 ;; esac # 正常退出(状态码0) exit 0 } # 启动脚本 main "$@"