diff --git a/init.sh b/init.sh index b3d38a2..57888ac 100755 --- a/init.sh +++ b/init.sh @@ -1,14 +1,14 @@ #!/bin/bash ################################################################################ -# Linux 系统初始化脚本 v1.2 +# Linux 系统初始化脚本 v1.3 # 功能: 镜像源切换 | 基础工具安装 | 系统优化配置 -# 支持: Ubuntu/Debian, CentOS/RHEL, Rocky Linux, AlmaLinux +# 支持: Ubuntu/Debian, CentOS/RHEL, Rocky, AlmaLinux # 作者: 自动化运维工具 # 使用: sudo ./init_system.sh [--auto] [--mirror=aliyun] [--non-interactive] ################################################################################ -set -euo pipefail +set -e # 颜色定义 - 用于终端彩色输出 RED='\033[0;31m' @@ -19,18 +19,10 @@ CYAN='\033[0;36m' PURPLE='\033[0;35m' NC='\033[0m' # No Color -# 日志文件路径 - 使用用户可写目录 -LOG_DIR="$HOME/.system-init-logs" -LOG_FILE="$LOG_DIR/system-init-$(date +%Y%m%d-%H%M%S).log" - -# 初始化日志系统 -init_logging() { - # 创建日志目录 - mkdir -p "$LOG_DIR" - - # 设置日志文件 - exec > >(tee -a "$LOG_FILE") 2>&1 -} +# 全局变量 +OS="" +OS_NAME="" +OS_VERSION="" # 输出函数定义 print_info() { @@ -49,19 +41,12 @@ print_error() { echo -e "${RED}[ERROR]${NC} $1" } -# 错误处理函数 -error_exit() { - print_error "$1" - echo "详细日志请查看: $LOG_FILE" - exit 1 -} - # 脚本横幅显示 print_banner() { clear echo -e "${PURPLE}" echo "==================================================" - echo " Linux 系统初始化脚本 v1.2" + echo " Linux 系统初始化脚本 v1.3" echo "==================================================" echo "功能: 镜像源切换 | 基础工具安装 | 系统优化配置" echo "支持: Ubuntu/Debian, CentOS/RHEL, Rocky, AlmaLinux" @@ -71,83 +56,27 @@ print_banner() { # 检查脚本运行权限 check_permissions() { - print_info "检查运行权限..." - - # 检查是否可以使用 sudo - if [[ $EUID -eq 0 ]]; then - print_success "当前为 root 用户" - return 0 - fi - - # 检查是否有 sudo 权限 - if sudo -n true 2>/dev/null; then - print_success "当前用户有 sudo 权限" - return 0 + if [[ $EUID -ne 0 ]]; then + print_error "此脚本需要 root 权限" + print_info "请使用: sudo $0" + exit 1 fi - - # 如果没有 root 权限也没有 sudo 权限,尝试获取 - print_info "尝试获取 sudo 权限..." - if ! sudo -v; then - error_exit "此脚本需要 root 权限或 sudo 权限\n请使用: sudo $0" - fi - print_success "权限检查通过" } -# 检查命令是否存在 -check_command() { - if ! command -v "$1" &> /dev/null; then - print_warning "命令 $1 未找到" - return 1 - fi - return 0 -} - # 检测操作系统类型和版本 detect_os() { print_info "正在检测操作系统..." - # 检查 /etc/os-release 文件是否存在 - if [[ ! -f /etc/os-release ]]; then - error_exit "无法检测操作系统: /etc/os-release 文件不存在" - fi - - # 加载操作系统信息 - . /etc/os-release - - # 设置全局变量 - OS="$ID" - OS_NAME="$NAME" - OS_VERSION="${VERSION_ID:-unknown}" - - # 显示检测结果 - print_success "操作系统: $OS_NAME $OS_VERSION" - - # 检测网络环境 - detect_network -} - -# 检测网络环境(国内/国际) -detect_network() { - print_info "正在检测网络环境..." - - # 测试多个网站,增加检测准确性 - local test_sites=("www.baidu.com" "mirrors.aliyun.com") - local china_count=0 - - for site in "${test_sites[@]}"; do - if timeout 3 curl -s --head "$site" > /dev/null 2>&1; then - ((china_count++)) - fi - done - - # 根据检测结果判断网络环境 - if [[ $china_count -gt 0 ]]; then - NETWORK_ENV="china" - print_info "检测到国内网络环境,建议使用国内镜像源" + if [[ -f /etc/os-release ]]; then + . /etc/os-release + OS="$ID" + OS_NAME="$NAME" + OS_VERSION="${VERSION_ID:-unknown}" + print_success "操作系统: $OS_NAME $OS_VERSION" else - NETWORK_ENV="international" - print_info "检测到国际网络环境" + print_error "无法检测操作系统" + exit 1 fi } @@ -155,37 +84,23 @@ detect_network() { backup_sources() { print_info "正在备份原始软件源..." - local backup_dir="$LOG_DIR/backup-$(date +%Y%m%d)" - mkdir -p "$backup_dir" + local timestamp=$(date +%Y%m%d-%H%M%S) case $OS in ubuntu|debian) - # 备份 sources.list if [[ -f /etc/apt/sources.list ]]; then - sudo cp /etc/apt/sources.list "$backup_dir/sources.list.bak" - print_success "已备份到 $backup_dir/sources.list.bak" - fi - - # 备份 sources.list.d 目录 - if [[ -d /etc/apt/sources.list.d ]]; then - sudo cp -r /etc/apt/sources.list.d "$backup_dir/" - print_success "已备份 sources.list.d 目录" + cp /etc/apt/sources.list /etc/apt/sources.list.bak.$timestamp + print_success "已备份到 /etc/apt/sources.list.bak.$timestamp" fi ;; centos|rhel|rocky|almalinux) - # 备份所有 .repo 文件 - if ls /etc/yum.repos.d/*.repo &> /dev/null; then - sudo cp /etc/yum.repos.d/*.repo "$backup_dir/" - print_success "已备份到 $backup_dir/" - else - print_warning "未找到 .repo 文件,跳过备份" + if [[ -d /etc/yum.repos.d ]]; then + mkdir -p /etc/yum.repos.d/backup-$timestamp + cp /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup-$timestamp/ 2>/dev/null || true + print_success "已备份到 /etc/yum.repos.d/backup-$timestamp/" fi ;; - - *) - print_warning "不支持的操作系统,跳过备份" - ;; esac } @@ -208,7 +123,7 @@ configure_ubuntu_mirrors() { esac fi - # 选择镜像源 + # 如果指定了镜像源参数,直接使用 local mirror_url="" local mirror_name="" @@ -228,7 +143,6 @@ configure_ubuntu_mirrors() { ;; *) print_warning "未知的镜像源参数,使用交互式选择" - MIRROR_ARG="" ;; esac fi @@ -237,13 +151,13 @@ configure_ubuntu_mirrors() { if [[ -z "$mirror_url" ]] && [[ -z "${NON_INTERACTIVE:-}" ]]; then echo "" echo "请选择镜像源:" - echo "1) 阿里云 (推荐国内用户)" + echo "1) 阿里云 (推荐)" echo "2) 清华大学" echo "3) 中国科技大学" - echo "4) 官方源 (推荐国际用户)" + echo "4) 官方源" echo "" - read -rp "请选择 [1-4, 默认: 1]: " mirror_choice + read -p "请选择 [1-4, 默认: 1]: " mirror_choice mirror_choice=${mirror_choice:-1} case $mirror_choice in @@ -278,14 +192,16 @@ configure_ubuntu_mirrors() { # 生成新的 sources.list if [[ "$mirror_url" == "http://archive.ubuntu.com" ]]; then - sudo tee /etc/apt/sources.list > /dev/null < /etc/apt/sources.list < /dev/null < /etc/apt/sources.list < /dev/null < /dev/null </dev/null || true + elif [[ "$OS_VERSION" == "9"* ]]; then + sed -i.bak -e "s|^mirrorlist=|#mirrorlist=|g" \ + -e "s|^#baseurl=http://dl.rockylinux.org|baseurl=$mirror_url/rocky|g" \ + /etc/yum.repos.d/rocky-*.repo /etc/yum.repos.d/almalinux-*.repo 2>/dev/null || true + fi + ;; + esac + fi # 清理缓存并更新 print_info "清理缓存并更新..." - sudo yum clean all - sudo yum makecache + yum clean all + yum makecache print_success "镜像源配置完成" } @@ -438,6 +336,11 @@ install_basic_tools() { net-tools unzip zip tar build-essential + software-properties-common + apt-transport-https + ca-certificates + gnupg + lsb-release ) local centos_tools=( @@ -453,7 +356,7 @@ install_basic_tools() { # 询问用户是否安装 if [[ -z "${NON_INTERACTIVE:-}" ]]; then echo "" - read -rp "是否安装基础工具? [Y/n]: " install_tools + read -p "是否安装基础工具? [Y/n]: " install_tools install_tools=${install_tools:-Y} if [[ ! $install_tools =~ ^[Yy]$ ]]; then @@ -465,13 +368,15 @@ install_basic_tools() { # 安装工具 case $OS in ubuntu|debian) - sudo apt-get update - sudo apt-get install -y "${ubuntu_tools[@]}" + apt-get update + apt-get install -y "${ubuntu_tools[@]}" ;; centos|rhel|rocky|almalinux) - sudo yum install -y epel-release || true - sudo yum install -y "${centos_tools[@]}" + if [[ "$OS" == "centos" ]] || [[ "$OS" == "rhel" ]]; then + yum install -y epel-release || true + fi + yum install -y "${centos_tools[@]}" ;; esac @@ -487,16 +392,16 @@ configure_ssh() { print_warning "SSH 服务未安装" case $OS in ubuntu|debian) - sudo apt-get install -y openssh-server + apt-get install -y openssh-server ;; centos|rhel|rocky|almalinux) - sudo yum install -y openssh-server + yum install -y openssh-server ;; esac fi if [[ -z "${NON_INTERACTIVE:-}" ]]; then - read -rp "是否优化 SSH 配置? [y/N]: " config_ssh + read -p "是否优化 SSH 配置? [y/N]: " config_ssh config_ssh=${config_ssh:-N} if [[ ! $config_ssh =~ ^[Yy]$ ]]; then @@ -506,22 +411,22 @@ configure_ssh() { fi # 备份 SSH 配置 - sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak + cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d) # 优化 SSH 配置 - sudo sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config - sudo sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config + sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config + sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config if ! grep -q "ClientAliveInterval" /etc/ssh/sshd_config; then - echo "ClientAliveInterval 60" | sudo tee -a /etc/ssh/sshd_config - echo "ClientAliveCountMax 3" | sudo tee -a /etc/ssh/sshd_config + echo "ClientAliveInterval 60" >> /etc/ssh/sshd_config + echo "ClientAliveCountMax 3" >> /etc/ssh/sshd_config fi # 重启 SSH 服务 if command -v systemctl &> /dev/null; then - sudo systemctl restart sshd 2>/dev/null || sudo systemctl restart ssh 2>/dev/null + systemctl restart sshd 2>/dev/null || systemctl restart ssh 2>/dev/null else - sudo service sshd restart 2>/dev/null || sudo service ssh restart 2>/dev/null + service sshd restart 2>/dev/null || service ssh restart 2>/dev/null fi print_success "SSH 配置优化完成" @@ -532,7 +437,7 @@ configure_timezone() { print_info "正在配置时区..." if [[ -z "${NON_INTERACTIVE:-}" ]]; then - read -rp "是否设置为中国时区 (Asia/Shanghai)? [Y/n]: " set_tz + read -p "是否设置为中国时区 (Asia/Shanghai)? [Y/n]: " set_tz set_tz=${set_tz:-Y} else set_tz="Y" @@ -540,9 +445,10 @@ configure_timezone() { if [[ $set_tz =~ ^[Yy]$ ]]; then if command -v timedatectl &> /dev/null; then - sudo timedatectl set-timezone Asia/Shanghai + timedatectl set-timezone Asia/Shanghai else - sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime + ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime + echo "Asia/Shanghai" > /etc/timezone 2>/dev/null || true fi print_success "时区已设置为 Asia/Shanghai" fi @@ -553,7 +459,7 @@ optimize_system() { print_info "正在应用系统优化配置..." if [[ -z "${NON_INTERACTIVE:-}" ]]; then - read -rp "是否应用系统优化配置? [Y/n]: " do_optimize + read -p "是否应用系统优化配置? [Y/n]: " do_optimize do_optimize=${do_optimize:-Y} if [[ ! $do_optimize =~ ^[Yy]$ ]]; then @@ -564,24 +470,33 @@ optimize_system() { # 优化文件描述符限制 if ! grep -q "^* soft nofile 65535" /etc/security/limits.conf; then - echo "* soft nofile 65535" | sudo tee -a /etc/security/limits.conf - echo "* hard nofile 65535" | sudo tee -a /etc/security/limits.conf + echo "* soft nofile 65535" >> /etc/security/limits.conf + echo "* hard nofile 65535" >> /etc/security/limits.conf fi # 优化内核参数 - sudo tee /etc/sysctl.d/99-custom.conf > /dev/null < /etc/sysctl.d/99-custom.conf </dev/null || true + sysctl -p /etc/sysctl.d/99-custom.conf > /dev/null 2>&1 || true print_success "系统优化配置完成" } @@ -591,7 +506,7 @@ clean_system() { print_info "正在清理系统..." if [[ -z "${NON_INTERACTIVE:-}" ]]; then - read -rp "是否清理系统缓存和无用包? [Y/n]: " do_clean + read -p "是否清理系统缓存和无用包? [Y/n]: " do_clean do_clean=${do_clean:-Y} if [[ ! $do_clean =~ ^[Yy]$ ]]; then @@ -602,13 +517,14 @@ clean_system() { case $OS in ubuntu|debian) - sudo apt-get autoremove -y - sudo apt-get autoclean -y + apt-get autoremove -y + apt-get autoclean -y + apt-get clean ;; centos|rhel|rocky|almalinux) - sudo yum autoremove -y - sudo yum clean all + yum autoremove -y + yum clean all ;; esac @@ -621,7 +537,7 @@ show_system_info() { print_success "==================== 系统信息 ====================" echo "" - echo "操作系统: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)" + echo "操作系统: $(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2 2>/dev/null || echo "Unknown")" echo "内核版本: $(uname -r)" echo "系统架构: $(uname -m)" @@ -634,13 +550,15 @@ show_system_info() { fi if command -v df &> /dev/null; then - echo "磁盘空间: $(df -h / | awk 'NR==2 {print $2}')" + echo "根目录空间: $(df -h / | awk 'NR==2 {print $2 " (可用: " $4 ")"}')" fi echo "当前用户: $(whoami)" echo "主机名称: $(hostname)" - if command -v timedatectl &> /dev/null; then + if [[ -f /etc/timezone ]]; then + echo "时区设置: $(cat /etc/timezone)" + elif command -v timedatectl &> /dev/null; then echo "时区设置: $(timedatectl | grep "Time zone" | awk '{print $3}')" fi @@ -664,8 +582,11 @@ show_menu() { echo "2) 仅更换镜像源" echo "3) 仅安装基础工具" echo "4) 仅系统优化" - echo "5) 显示系统信息" - echo "6) 退出" + echo "5) 仅配置 SSH" + echo "6) 仅设置时区" + echo "7) 仅系统清理" + echo "8) 显示系统信息" + echo "9) 退出脚本" echo "" } @@ -714,15 +635,16 @@ full_initialization() { show_system_info echo "" - print_info "日志文件: $LOG_FILE" - print_info "建议重启系统使所有配置生效" + print_info "建议执行以下操作:" + echo "1. 重启系统使所有配置生效: reboot" + echo "2. 检查系统更新: apt-get upgrade 或 yum update" echo "" } # 显示帮助信息 show_help() { echo "" - echo "Linux 系统初始化脚本 v1.2" + echo "Linux 系统初始化脚本 v1.3" echo "" echo "用法: $0 [选项]" echo "" @@ -735,7 +657,7 @@ show_help() { echo "示例:" echo " sudo $0" echo " sudo $0 --auto" - echo " sudo $0 --mirror=aliyun --non-interactive" + echo " sudo $0 --mirror=tsinghua --non-interactive" echo "" } @@ -772,13 +694,6 @@ parse_arguments() { # 主函数 main() { - # 初始化日志系统 - init_logging - - print_info "脚本开始执行" - print_info "日志文件: $LOG_FILE" - print_info "开始时间: $(date)" - # 解析命令行参数 parse_arguments "$@" @@ -800,7 +715,7 @@ main() { # 交互式菜单 while true; do show_menu - read -rp "请选择操作 [1-6]: " choice + read -p "请选择操作 [1-9]: " choice case $choice in 1) @@ -825,11 +740,19 @@ main() { optimize_system ;; 5) - show_system_info + configure_ssh ;; 6) + configure_timezone + ;; + 7) + clean_system + ;; + 8) + show_system_info + ;; + 9) print_info "退出脚本" - echo "详细日志请查看: $LOG_FILE" exit 0 ;; *) @@ -838,13 +761,12 @@ main() { esac # 询问是否继续 - if [[ $choice -ne 6 ]]; then + if [[ $choice -ne 9 ]]; then echo "" - read -rp "是否继续其他操作? [Y/n]: " continue_choice + read -p "是否继续其他操作? [Y/n]: " continue_choice continue_choice=${continue_choice:-Y} if [[ ! $continue_choice =~ ^[Yy]$ ]]; then print_info "退出脚本" - echo "详细日志请查看: $LOG_FILE" exit 0 fi fi