Files
BootRepairTool/arch-install.sh
2026-02-14 14:39:44 +08:00

395 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ==============================================================================
# BootRepairTool - Arch Linux 源码安装脚本
# ------------------------------------------------------------------------------
# 功能:
# 1. 自动安装依赖 (git, tk, python)
# 2. 克隆项目到 /opt/boot-repair-tool
# 3. 创建启动脚本和桌面入口
# 4. 提示用户如何运行
#
# 使用方式:
#
# 方式一:从 Git 仓库安装(默认)
# 默认会从 GitHub 克隆最新版本:
# sudo bash arch-install.sh
#
# 或指定自定义仓库地址:
# sudo bash arch-install.sh git https://github.com/username/repo.git
#
# 方式二:本地安装(离线)
# 将项目文件夹复制到 Arch Linux 系统,进入目录运行:
# sudo bash arch-install.sh local
#
# 注意: 使用前请修改脚本中的 DEFAULT_REPO_URL 为实际仓库地址
# ==============================================================================
# --- 配置变量 ---
APP_NAME="Linux GRUB 引导修复工具"
APP_NAME_EN="BootRepairTool"
# 默认 Git 仓库地址(请修改为实际地址)
DEFAULT_REPO_URL="https://git.yuyujing.cn/zj/BootRepairTool.git"
# 安装模式: "git" 或 "local"
INSTALL_MODE="${1:-git}"
# 可以通过第二个参数指定自定义仓库地址
CUSTOM_REPO_URL="${2:-}"
INSTALL_DIR="/opt/boot-repair-tool"
EXEC_FILE="boot-repair"
DESKTOP_FILE_NAME="boot-repair.desktop"
DESKTOP_INSTALL_DIR="/usr/share/applications"
POLICY_FILE="/usr/share/polkit-1/actions/com.bootrepair.tool.policy"
ICON_FILE="boot-repair.png"
# --- 颜色定义 ---
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# 检查是否以 root 权限运行
check_root() {
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}错误:此脚本需要 root 权限运行。请使用 'sudo bash $0'。${NC}"
exit 1
fi
}
# 检查并安装依赖
install_dependencies() {
echo -e "${YELLOW}[1/6] 检查并安装依赖...${NC}"
# 更新包数据库
echo -e "${BLUE} 更新包数据库...${NC}"
pacman -Sy --noconfirm
# 需要安装的包
PACKAGES="git tk python python-pip"
for pkg in $PACKAGES; do
if pacman -Q "$pkg" &>/dev/null; then
echo -e "${GREEN}$pkg 已安装${NC}"
else
echo -e "${YELLOW} 正在安装 $pkg...${NC}"
pacman -S --noconfirm "$pkg"
if [ $? -eq 0 ]; then
echo -e "${GREEN}$pkg 安装成功${NC}"
else
echo -e "${RED}$pkg 安装失败${NC}"
exit 1
fi
fi
done
}
# 克隆或更新项目
clone_or_update_project() {
echo -e "${YELLOW}[2/6] 安装项目文件...${NC}"
# 确定仓库地址
if [ -n "$CUSTOM_REPO_URL" ]; then
REPO_URL="$CUSTOM_REPO_URL"
else
REPO_URL="$DEFAULT_REPO_URL"
fi
# 检查是否使用本地文件安装
if [ "$INSTALL_MODE" = "local" ]; then
# 本地安装模式 - 复制当前目录的文件
SCRIPT_SOURCE="${BASH_SOURCE[0]}"
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")" && pwd)"
echo -e "${BLUE} 使用本地文件安装...${NC}"
# 检查必要的文件是否存在
if [ ! -f "${SCRIPT_DIR}/frontend.py" ] || [ ! -f "${SCRIPT_DIR}/backend.py" ]; then
echo -e "${RED} ✗ 未找到 frontend.py 或 backend.py${NC}"
echo -e "${YELLOW} 请确保在 BootRepairTool 项目目录中运行此脚本${NC}"
exit 1
fi
# 如果目录存在,备份
if [ -d "${INSTALL_DIR}" ]; then
mv "${INSTALL_DIR}" "${INSTALL_DIR}.backup.$(date +%Y%m%d%H%M%S)"
fi
# 创建安装目录
mkdir -p "${INSTALL_DIR}"
# 复制所有 Python 文件和必要的资源
cp -r "${SCRIPT_DIR}"/*.py "${INSTALL_DIR}/" 2>/dev/null || true
cp -r "${SCRIPT_DIR}"/*.md "${INSTALL_DIR}/" 2>/dev/null || true
cp -r "${SCRIPT_DIR}/tip" "${INSTALL_DIR}/" 2>/dev/null || true
echo -e "${GREEN} ✓ 项目文件已复制到 ${INSTALL_DIR}${NC}"
elif [ -d "${INSTALL_DIR}/.git" ]; then
# Git 更新模式
echo -e "${BLUE} 项目已存在,正在更新...${NC}"
cd "${INSTALL_DIR}" || exit 1
git pull origin main || git pull origin master
if [ $? -eq 0 ]; then
echo -e "${GREEN} ✓ 项目更新成功${NC}"
else
echo -e "${YELLOW} 警告:更新失败,使用现有版本${NC}"
fi
else
# Git 克隆模式(默认)
echo -e "${BLUE} 正在从 ${REPO_URL} 克隆项目...${NC}"
# 如果目录存在但不是 git 仓库,先备份
if [ -d "${INSTALL_DIR}" ]; then
mv "${INSTALL_DIR}" "${INSTALL_DIR}.backup.$(date +%Y%m%d%H%M%S)"
fi
# 克隆仓库
git clone --depth 1 "${REPO_URL}" "${INSTALL_DIR}"
if [ $? -eq 0 ]; then
echo -e "${GREEN} ✓ 项目克隆成功${NC}"
else
echo -e "${RED} ✗ 项目克隆失败${NC}"
echo -e "${YELLOW} 提示:请检查网络连接或仓库地址是否正确${NC}"
echo -e "${YELLOW} 当前仓库地址: ${REPO_URL}${NC}"
echo -e "${YELLOW} 或使用本地安装: sudo bash arch-install.sh local${NC}"
exit 1
fi
fi
}
# 创建启动脚本
create_launcher() {
echo -e "${YELLOW}[3/6] 创建启动脚本...${NC}"
# 创建主启动脚本
cat > "${INSTALL_DIR}/${EXEC_FILE}" << 'EOF'
#!/bin/bash
# ==============================================================================
# BootRepairTool 启动脚本
# 解决 Arch Linux 等系统上的 X11 字体渲染问题
# ==============================================================================
# 设置字体渲染环境变量,解决 "BadLength (poly request too large)" 错误
export XLIB_SKIP_ARGB_VISUALS=1
export GDK_NATIVE_WINDOWS=1
export TCL_DONT_USE_RENDER_EXTENSION=1
# 如果使用 Wayland强制使用 XWayland
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
export GDK_BACKEND=x11
fi
# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 切换到项目目录
cd "${SCRIPT_DIR}" || exit 1
# 使用系统 Python 运行前端
exec python frontend.py "$@"
EOF
chmod +x "${INSTALL_DIR}/${EXEC_FILE}"
# 创建软链接到 /bin
if [ -L "/bin/${EXEC_FILE}" ]; then
rm -f "/bin/${EXEC_FILE}"
fi
ln -sf "${INSTALL_DIR}/${EXEC_FILE}" "/bin/${EXEC_FILE}"
echo -e "${GREEN} ✓ 启动脚本创建完成${NC}"
}
# 创建图标
create_icon() {
echo -e "${YELLOW}[4/6] 创建图标...${NC}"
# 创建简单的 SVG 图标
cat > "${INSTALL_DIR}/${ICON_FILE}" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<circle cx="32" cy="32" r="28" fill="#2196F3"/>
<circle cx="32" cy="32" r="20" fill="#1976D2"/>
<path d="M32 16 L32 32 L44 40" stroke="white" stroke-width="4" fill="none" stroke-linecap="round"/>
<circle cx="32" cy="32" r="4" fill="white"/>
</svg>
EOF
echo -e "${GREEN} ✓ 图标创建完成${NC}"
}
# 创建桌面入口文件
create_desktop_entry() {
echo -e "${YELLOW}[5/6] 创建桌面入口...${NC}"
cat > "${DESKTOP_INSTALL_DIR}/${DESKTOP_FILE_NAME}" << EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=Linux GRUB 引导修复工具
Name[zh_CN]=Linux GRUB 引导修复工具
Name[en_US]=Boot Repair Tool
Comment=修复 Linux 系统 GRUB 引导加载器
Comment[zh_CN]=修复 Linux 系统 GRUB 引导加载器
Categories=System;Settings;Utility;
Terminal=false
Icon=${INSTALL_DIR}/${ICON_FILE}
Exec=pkexec ${INSTALL_DIR}/${EXEC_FILE}
Actions=;
EOF
chmod 644 "${DESKTOP_INSTALL_DIR}/${DESKTOP_FILE_NAME}"
# 创建 PolicyKit 规则
cat > "$POLICY_FILE" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<action id="com.bootrepair.tool.pkexec">
<description>Run Linux GRUB Boot Repair Tool</description>
<description xml:lang="zh_CN">运行 Linux GRUB 引导修复工具</description>
<message>Authentication is required to run the Boot Repair Tool.</message>
<message xml:lang="zh_CN">运行引导修复工具需要管理员权限</message>
<icon_name>boot-repair</icon_name>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/bin/${EXEC_FILE}</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
EOF
chmod 644 "$POLICY_FILE"
# 更新桌面数据库
if command -v update-desktop-database &>/dev/null; then
update-desktop-database "${DESKTOP_INSTALL_DIR}" 2>/dev/null || true
fi
echo -e "${GREEN} ✓ 桌面入口创建完成${NC}"
}
# 复制到用户桌面
copy_to_user_desktop() {
echo -e "${YELLOW}[6/6] 创建用户桌面快捷方式...${NC}"
CURRENT_USER=$(logname 2>/dev/null || echo "${SUDO_USER}")
if [ -z "$CURRENT_USER" ]; then
CURRENT_USER=$(whoami)
fi
USER_DESKTOP_DIR=""
if [ -d "/home/${CURRENT_USER}/桌面" ]; then
USER_DESKTOP_DIR="/home/${CURRENT_USER}/桌面"
elif [ -d "/home/${CURRENT_USER}/Desktop" ]; then
USER_DESKTOP_DIR="/home/${CURRENT_USER}/Desktop"
fi
if [ -n "${USER_DESKTOP_DIR}" ] && [ -d "/home/${CURRENT_USER}" ]; then
cp -f "${DESKTOP_INSTALL_DIR}/${DESKTOP_FILE_NAME}" "${USER_DESKTOP_DIR}/"
chmod 755 "${USER_DESKTOP_DIR}/${DESKTOP_FILE_NAME}"
chown "${CURRENT_USER}:" "${USER_DESKTOP_DIR}/${DESKTOP_FILE_NAME}" 2>/dev/null || true
echo -e "${GREEN} ✓ 已复制到 ${USER_DESKTOP_DIR}${NC}"
else
echo -e "${YELLOW} 未找到用户桌面目录,跳过${NC}"
fi
}
# 显示完成信息
show_completion() {
echo ""
echo -e "${CYAN}=================================================${NC}"
echo -e "${GREEN} 安装完成!${NC}"
echo -e "${CYAN}=================================================${NC}"
echo ""
echo -e "${YELLOW}📋 使用方式:${NC}"
echo ""
echo -e " ${GREEN}方法一:图形界面${NC}"
echo -e " 从应用程序菜单启动 '${APP_NAME}'"
echo ""
echo -e " ${GREEN}方法二:命令行 (推荐)${NC}"
echo -e " ${CYAN}sudo boot-repair${NC}"
echo ""
echo -e " ${GREEN}方法三:使用 pkexec${NC}"
echo -e " ${CYAN}pkexec boot-repair${NC}"
echo ""
echo -e "${YELLOW}📁 安装路径:${NC}"
echo -e " 源码目录: ${INSTALL_DIR}"
echo -e " 启动脚本: /bin/${EXEC_FILE}"
echo -e " 图标: ${INSTALL_DIR}/${ICON_FILE}"
echo ""
echo -e "${YELLOW}🔧 更新项目:${NC}"
echo -e " ${CYAN}cd ${INSTALL_DIR} && sudo git pull${NC}"
echo ""
echo -e "${YELLOW}🗑️ 卸载:${NC}"
echo -e " ${CYAN}sudo rm -rf ${INSTALL_DIR} /bin/${EXEC_FILE}${NC}"
echo -e " ${CYAN}sudo rm -f ${DESKTOP_INSTALL_DIR}/${DESKTOP_FILE_NAME}${NC}"
echo -e " ${CYAN}sudo rm -f ${POLICY_FILE}${NC}"
echo ""
echo -e "${CYAN}=================================================${NC}"
echo -e "${GREEN}提示: 如果未在菜单中看到程序,请尝试注销并重新登录。${NC}"
echo -e "${CYAN}=================================================${NC}"
echo ""
# 询问是否立即运行
read -p "是否立即运行程序? [y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${GREEN}正在启动 ${APP_NAME}...${NC}"
"${INSTALL_DIR}/${EXEC_FILE}"
fi
}
# 显示帮助信息
show_help() {
echo -e "${CYAN}=================================================${NC}"
echo -e "${APP_NAME} - Arch Linux 安装脚本"
echo -e "${CYAN}=================================================${NC}"
echo ""
echo -e "用法: sudo bash $0 [模式] [仓库地址]"
echo ""
echo -e "参数:"
echo -e " 模式: git (默认) 或 local"
echo -e " 仓库地址: 自定义 Git 仓库 URL可选"
echo ""
echo -e "示例:"
echo -e " ${GREEN}sudo bash $0${NC} # 默认从 Git 克隆"
echo -e " ${GREEN}sudo bash $0 git${NC} # 从默认仓库克隆"
echo -e " ${GREEN}sudo bash $0 git https://...${NC} # 从指定仓库克隆"
echo -e " ${GREEN}sudo bash $0 local${NC} # 从当前目录复制"
echo ""
}
}
# 主函数
main() {
# 显示帮助
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
exit 0
fi
echo -e "${CYAN}=================================================${NC}"
echo -e "${CYAN} ${APP_NAME} - Arch Linux 安装脚本${NC}"
echo -e "${CYAN}=================================================${NC}"
echo ""
check_root
install_dependencies
clone_or_update_project
create_launcher
create_icon
create_desktop_entry
copy_to_user_desktop
show_completion
}
# 运行主函数
main "$@"