更新 'init.sh'

master
Gettler 6 months ago
parent cbcd6f5e38
commit 0022f96a88

@ -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 <<EOF
deb $mirror_url/ubuntu/ $ubuntu_codename main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-updates main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-backports main restricted universe multiverse
cat > /etc/apt/sources.list <<EOF
# Ubuntu 官方源
deb http://archive.ubuntu.com/ubuntu/ $ubuntu_codename main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ $ubuntu_codename-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ $ubuntu_codename-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ $ubuntu_codename-security main restricted universe multiverse
EOF
else
sudo tee /etc/apt/sources.list > /dev/null <<EOF
cat > /etc/apt/sources.list <<EOF
# $mirror_name 镜像源
deb $mirror_url/ubuntu/ $ubuntu_codename main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-updates main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-backports main restricted universe multiverse
@ -297,12 +213,8 @@ EOF
# 更新软件包索引
print_info "正在更新软件包索引..."
if sudo apt-get update; then
print_success "软件包索引更新完成"
else
print_warning "软件包索引更新失败,请检查网络连接"
return 1
fi
apt-get update
print_success "软件包索引更新完成"
}
# 配置 CentOS/RHEL/Rocky/AlmaLinux 镜像源
@ -328,7 +240,6 @@ configure_centos_mirrors() {
;;
*)
print_warning "未知的镜像源参数,使用交互式选择"
MIRROR_ARG=""
;;
esac
fi
@ -343,7 +254,7 @@ configure_centos_mirrors() {
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
@ -376,52 +287,39 @@ configure_centos_mirrors() {
print_info "正在配置 $mirror_name 镜像源..."
# 根据不同的发行版配置
case $OS in
centos)
if [[ "$OS_VERSION" == "7" ]]; then
sudo sed -e "s|^mirrorlist=|#mirrorlist=|g" \
-e "s|^#baseurl=http://mirror.centos.org|baseurl=$mirror_url/centos|g" \
-i.bak /etc/yum.repos.d/CentOS-*.repo
elif [[ "$OS_VERSION" == "8" ]]; then
sudo tee /etc/yum.repos.d/centos.repo > /dev/null <<EOF
[BaseOS]
name=CentOS-\$releasever - Base
baseurl=$mirror_url/centos/\$releasever/BaseOS/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
[AppStream]
name=CentOS-\$releasever - AppStream
baseurl=$mirror_url/centos/\$releasever/AppStream/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
EOF
fi
;;
rocky|almalinux)
if [[ "$OS_VERSION" == "9"* ]]; then
sudo tee /etc/yum.repos.d/rocky.repo > /dev/null <<EOF
[baseos]
name=Rocky Linux \$releasever - BaseOS
baseurl=$mirror_url/rocky/\$releasever/BaseOS/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
[appstream]
name=Rocky Linux \$releasever - AppStream
baseurl=$mirror_url/rocky/\$releasever/AppStream/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
EOF
fi
;;
esac
if [[ "$mirror_name" != "官方源" ]]; then
case $OS in
centos)
if [[ "$OS_VERSION" == "7" ]]; then
sed -i.bak -e "s|^mirrorlist=|#mirrorlist=|g" \
-e "s|^#baseurl=http://mirror.centos.org|baseurl=$mirror_url/centos|g" \
/etc/yum.repos.d/CentOS-*.repo
elif [[ "$OS_VERSION" == "8" ]]; then
# CentOS 8 已停止支持,使用 vault 源
sed -i.bak -e "s|^mirrorlist=|#mirrorlist=|g" \
-e "s|^#baseurl=http://mirror.centos.org|baseurl=$mirror_url/centos-vault|g" \
/etc/yum.repos.d/CentOS-*.repo
fi
;;
rocky|almalinux)
if [[ "$OS_VERSION" == "8"* ]]; 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
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 <<EOF
cat > /etc/sysctl.d/99-custom.conf <<EOF
# 网络优化
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 连接优化
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192
net.ipv4.tcp_slow_start_after_idle = 0
# TIME_WAIT 优化
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
# 文件系统优化
fs.file-max = 1000000
fs.inotify.max_user_watches = 524288
EOF
sudo sysctl -p /etc/sysctl.d/99-custom.conf 2>/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

Loading…
Cancel
Save