You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本MOTD、Docker组用户功能无输出及交互缺失求助

Docker安装脚本问题排查与改进建议

问题描述

我编写了一个Bash脚本,预期实现以下功能:

  • 检测运行的操作系统,自动选择APT、DNF或Pacman对应的包管理器;
  • 通过匹配的包管理器安装Docker及Docker-Compose;
  • 更新Ubuntu服务器的MOTD信息;
  • 添加指定用户到Docker组(需支持交互式输入);
  • 配置Docker Daemon,设置MTU值为1442并配置日志。

但运行脚本后,仅能看到MTU=1442的输出,MOTD相关输出完全缺失,且未出现预期的交互式输入界面来添加用户到Docker组。附上脚本代码,寻求改进建议。

原脚本代码

#!/bin/bash

# This script will install Docker and Docker-Compose, configure the docker daemon,
# and add specified users to the docker group.

# Define default values
MTU=1442
VERBOSE=false

# Function to detect operating system
detect_os() {
  if [ -f /etc/lsb-release ]; then
    os="ubuntu"
    package_manager="apt"
  elif [ -f /etc/redhat-release ]; then
    os="centos"
    package_manager="dnf"
  elif [ -f /etc/arch-release ]; then
    os="arch"
    package_manager="pacman"
  else
    echo "Error: Unable to detect operating system."
    exit 1
  fi
}

# Function to update MOTD
update_motd() {
  local motd_file="/etc/motd"
  echo "$1" > "$motd_file"
  echo "MOTD updated with message: $1"
}

# Function to add users to docker group
add_users() {
  local users="$1"
  local group="docker"
  for user in $users; do
    # Check if user exists
    if ! id "$user" >/dev/null 2>&1; then
      useradd "$user"
      echo "User $user created."
    fi
    # Add user to docker group
    usermod -aG "$group" "$user"
    echo "User $user added to $group group."
  done
}

# Function to install Docker and Docker-Compose
install_docker() {
  local package_manager="$1"
  local packages="docker docker-compose"
  case "$package_manager" in
    apt)
      sudo apt-get update
      sudo apt-get install -y $packages
      ;;
    dnf)
      sudo dnf install -y $packages
      ;;
    pacman)
      sudo pacman -S --noconfirm $packages
      ;;
    *)
      echo "Error: Invalid package manager: $package_manager"
      exit 1
      ;;
  esac
}

# Function to configure Docker daemon
configure_docker() {
  local mtu="$1"
  local config_file="/etc/docker/daemon.json"
  # Create config file if it does not exist
  if [ ! -f "$config_file" ]; then
    sudo touch "$config_file"
    sudo chmod 644 "$config_file"
  fi
  # Update MTU value in config file
  sudo sh -c "echo '{\"mtu\": $mtu}' > $config_file"
  echo "Docker daemon configured with MTU=$mtu."
}

# Parse command line argume
while [ "$#" -gt 0 ]; do
  case "$1" in
    --motd )
      MOTD="$2"
      shift 2
      ;;
    --users)
      USERS="$2"
      shift 2
      ;;
    --mtu)
      MTU="$2"
      shift 2
      ;;
  esac
done

echo "MOTD: $MOTD"
echo "USERS: $USERS"
echo "MTU: $MTU"
echo "Script is finish"

问题根源分析

  1. 核心函数未被调用:脚本仅定义了所有功能函数,但从未执行detect_os、install_docker等核心逻辑,这是导致大部分功能失效的根本原因。
  2. 无交互式输入逻辑:原脚本仅支持通过--users参数传入用户,未实现交互式询问的功能。
  3. MOTD功能未触发:即使传入--motd参数,update_motd函数也未被调用,且未做系统兼容性判断(仅Ubuntu需更新MOTD)。
  4. Docker日志配置缺失:原脚本仅设置了MTU,未实现日志配置的需求。
  5. 拼写与细节错误:参数解析注释拼写错误、脚本结尾提示拼写错误,部分步骤无状态反馈。

改进后的脚本

#!/bin/bash

# 安装Docker及Docker-Compose、配置守护进程、更新Ubuntu MOTD、添加用户到Docker组

# 默认配置
MTU=1442

# 检测操作系统与包管理器
detect_os() {
  if [ -f /etc/lsb-release ]; then
    os="ubuntu"
    package_manager="apt"
  elif [ -f /etc/redhat-release ]; then
    os="centos"
    package_manager="dnf"
  elif [ -f /etc/arch-release ]; then
    os="arch"
    package_manager="pacman"
  else
    echo "错误:无法检测操作系统类型"
    exit 1
  fi
}

# 更新Ubuntu MOTD(仅支持Ubuntu)
update_motd() {
  if [ "$os" != "ubuntu" ]; then
    echo "MOTD更新仅支持Ubuntu,跳过该步骤"
    return
  fi
  
  local motd_file="/etc/motd"
  read -p "请输入MOTD内容(留空则保留原有内容):" motd_content
  
  if [ -n "$motd_content" ]; then
    echo "$motd_content" > "$motd_file"
    echo "MOTD已更新:$motd_content"
  else
    echo "跳过MOTD更新,保留原有内容"
  fi
}

# 添加用户到Docker组(支持命令行参数/交互式输入)
add_users() {
  local target_users
  # 优先使用命令行参数,无参数则交互式询问
  if [ -n "$USERS" ]; then
    target_users="$USERS"
  else
    read -p "请输入要添加到Docker组的用户名(空格分隔):" target_users
  fi

  if [ -z "$target_users" ]; then
    echo "未指定用户,跳过Docker组添加操作"
    return
  fi

  local docker_group="docker"
  # 确保Docker组存在
  if ! getent group "$docker_group" >/dev/null 2>&1; then
    sudo groupadd "$docker_group"
    echo "Docker组已创建"
  fi

  for user in $target_users; do
    if ! id "$user" >/dev/null 2>&1; then
      read -p "用户$user不存在,是否创建?(y/n):" create_confirm
      if [ "$create_confirm" = "y" ] || [ "$create_confirm" = "Y" ]; then
        sudo useradd "$user"
        echo "用户$user已创建"
      else
        echo "跳过用户$user"
        continue
      fi
    fi
    sudo usermod -aG "$docker_group" "$user"
    echo "用户$user已添加到Docker组"
  done
}

# 安装Docker及Docker-Compose
install_docker() {
  local pkg_manager="$1"
  local packages="docker docker-compose"
  
  echo "通过$pkg_manager安装Docker及Docker-Compose..."
  case "$pkg_manager" in
    apt)
      sudo apt-get update -y
      sudo apt-get install -y $packages
      sudo systemctl enable --now docker
      ;;
    dnf)
      sudo dnf install -y $packages
      sudo systemctl enable --now docker
      ;;
    pacman)
      sudo pacman -S --noconfirm $packages
      sudo systemctl enable --now docker
      ;;
    *)
      echo "错误:无效的包管理器$pkg_manager"
      exit 1
      ;;
  esac
}

# 配置Docker守护进程(MTU+日志)
configure_docker() {
  local mtu="$1"
  local config_file="/etc/docker/daemon.json"
  
  echo "配置Docker守护进程:MTU=$mtu,日志滚动配置"
  # 构建完整配置内容
  local daemon_config=$(cat <<EOF
{
  "mtu": $mtu,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF
)
  
  # 备份原有配置(如果存在)
  if [ -f "$config_file" ]; then
    sudo cp "$config_file" "$config_file.bak"
    echo "原有配置已备份到$config_file.bak"
  fi
  
  sudo sh -c "echo '$daemon_config' > $config_file"
  sudo systemctl restart docker
  echo "Docker守护进程配置完成,已重启服务"
}

# 解析命令行参数
while [ "$#" -gt 0 ]; do
  case "$1" in
    --motd )
      MOTD="$2"
      shift 2
      ;;
    --users)
      USERS="$2"
      shift 2
      ;;
    --mtu)
      MTU="$2"
      shift 2
      ;;
    *)
      echo "未知参数:$1"
      exit 1
      ;;
  esac
done

# 执行核心流程
detect_os
install_docker "$package_manager"
update_motd
add_users
configure_docker "$MTU"

echo "脚本执行完成!"

关键改进说明

  • 触发核心逻辑:在脚本末尾添加了所有功能函数的调用,确保预期功能全部执行。
  • 交互式输入支持:add_users函数优先读取命令行参数,无参数则弹出交互式询问,创建用户前增加确认步骤。
  • MOTD优化:仅在Ubuntu系统执行更新,支持保留原有内容。
  • 补充日志配置:在daemon.json中添加了日志滚动策略(单文件最大10M,保留3个历史文件)。
  • 鲁棒性增强:安装后自动启动Docker并设置开机自启,修改配置前备份原有文件,确保Docker组存在。
  • 细节修正:修复拼写错误,增加各步骤状态反馈,提升脚本可读性。

内容的提问来源于stack exchange,提问作者Vegard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:45:43