153 lines
5.0 KiB
Bash
Executable File
153 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# YAMA Ghost (Linux client) — install + autostart deployment
|
||
#
|
||
# 用法(在解压/克隆后的 linux/ 目录下):
|
||
# ./install.sh # 默认安装到 ~/.local/bin/ghost
|
||
# ./install.sh /opt/yama # 安装到 /opt/yama/ghost(如需要会自动 sudo)
|
||
#
|
||
# 行为:
|
||
# 1. 复制 ghost 二进制到目标位置并加可执行权
|
||
# 2. 注册 XDG Autostart(~/.config/autostart/ghost.desktop)
|
||
# 3. 可选立即启动一次(继承当前桌面会话的 X 环境)
|
||
|
||
set -euo pipefail
|
||
|
||
# ---- 防止以 root 直接运行 ----
|
||
# 用 sudo 跑会让 $HOME 变成 /root(或 sudo 配置决定的值),
|
||
# autostart 写到 /root/.config/autostart/,桌面用户的 session 看不见,
|
||
# 自启动完全失效。需要 sudo 的地方(如装到 /opt/...),脚本会按需自调用 sudo。
|
||
if [[ "${EUID:-$(id -u)}" -eq 0 ]]; then
|
||
echo "请用普通用户身份运行此脚本,不要 sudo。" >&2
|
||
echo "如目标目录需要 root 权限,脚本会按需自动调用 sudo。" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# ---- 颜色 ----
|
||
if [[ -t 1 ]]; then
|
||
C_RED=$'\033[31m'; C_GREEN=$'\033[32m'; C_YELLOW=$'\033[33m'
|
||
C_BLUE=$'\033[34m'; C_BOLD=$'\033[1m'; C_RESET=$'\033[0m'
|
||
else
|
||
C_RED=''; C_GREEN=''; C_YELLOW=''; C_BLUE=''; C_BOLD=''; C_RESET=''
|
||
fi
|
||
|
||
info() { echo "${C_BLUE}[INFO]${C_RESET} $*"; }
|
||
ok() { echo "${C_GREEN}[ OK ]${C_RESET} $*"; }
|
||
warn() { echo "${C_YELLOW}[WARN]${C_RESET} $*"; }
|
||
error() { echo "${C_RED}[FAIL]${C_RESET} $*" >&2; }
|
||
|
||
# ---- 路径解析 ----
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
SRC_BIN="${SCRIPT_DIR}/ghost"
|
||
|
||
# 安装目标目录(参数 $1,默认 ~/.local/bin)
|
||
INSTALL_DIR="${1:-${HOME}/.local/bin}"
|
||
DEST_BIN="${INSTALL_DIR}/ghost"
|
||
|
||
AUTOSTART_DIR="${XDG_CONFIG_HOME:-${HOME}/.config}/autostart"
|
||
AUTOSTART_FILE="${AUTOSTART_DIR}/ghost.desktop"
|
||
|
||
echo "${C_BOLD}YAMA Ghost Linux 安装${C_RESET}"
|
||
echo " 源: ${SRC_BIN}"
|
||
echo " 目标: ${DEST_BIN}"
|
||
echo " 自启动: ${AUTOSTART_FILE}"
|
||
echo ""
|
||
|
||
# ---- 前置检查 ----
|
||
if [[ ! -f "${SRC_BIN}" ]]; then
|
||
error "找不到 ghost 二进制 ${SRC_BIN}"
|
||
error "请把 install.sh 放在 ghost 同目录后再运行"
|
||
exit 1
|
||
fi
|
||
|
||
if ! file "${SRC_BIN}" 2>/dev/null | grep -q "ELF.*executable"; then
|
||
error "${SRC_BIN} 不是有效的 ELF 可执行文件"
|
||
exit 1
|
||
fi
|
||
|
||
# 判断目标目录是否需要 sudo
|
||
# 三种情况都要走 sudo 分支:
|
||
# a) 目录不存在且父目录无写权(如 /opt/yama 父是 /opt root-owned)
|
||
# b) 目录已存在但当前用户无写权(如已存在的 /usr/local/bin root-owned)
|
||
# c) 介于两者之间的情况由 mkdir 的退出码决定
|
||
NEED_SUDO=""
|
||
if [[ -d "${INSTALL_DIR}" ]]; then
|
||
[[ -w "${INSTALL_DIR}" ]] || NEED_SUDO="sudo"
|
||
else
|
||
if ! mkdir -p "${INSTALL_DIR}" 2>/dev/null; then
|
||
NEED_SUDO="sudo"
|
||
fi
|
||
fi
|
||
if [[ -n "${NEED_SUDO}" ]]; then
|
||
info "目标目录需要 root 权限,将使用 sudo(可能需要输入密码)"
|
||
${NEED_SUDO} mkdir -p "${INSTALL_DIR}"
|
||
fi
|
||
|
||
# ---- 1. 如已运行则先停止 ----
|
||
if pgrep -x ghost > /dev/null; then
|
||
warn "检测到 ghost 进程正在运行,先停止以替换二进制"
|
||
pkill -x ghost || true
|
||
sleep 1
|
||
if pgrep -x ghost > /dev/null; then
|
||
warn "进程未优雅退出,强制 kill"
|
||
pkill -9 -x ghost || true
|
||
sleep 1
|
||
fi
|
||
ok "旧进程已停止"
|
||
fi
|
||
|
||
# ---- 2. 复制二进制 ----
|
||
info "复制 ghost 到 ${DEST_BIN}"
|
||
${NEED_SUDO} install -m 0755 "${SRC_BIN}" "${DEST_BIN}"
|
||
ok "二进制已部署 (mode 0755)"
|
||
|
||
# ---- 3. 写 XDG Autostart 文件 ----
|
||
mkdir -p "${AUTOSTART_DIR}"
|
||
cat > "${AUTOSTART_FILE}" <<EOF
|
||
[Desktop Entry]
|
||
Type=Application
|
||
Name=YAMA Ghost
|
||
Comment=YAMA remote control client
|
||
Exec=${DEST_BIN}
|
||
Terminal=false
|
||
X-GNOME-Autostart-enabled=true
|
||
NoDisplay=true
|
||
StartupNotify=false
|
||
EOF
|
||
ok "Autostart 已注册"
|
||
|
||
# 验证 .desktop 格式(如果系统装了 desktop-file-validate)
|
||
if command -v desktop-file-validate >/dev/null 2>&1; then
|
||
if desktop-file-validate "${AUTOSTART_FILE}" >/dev/null 2>&1; then
|
||
ok "Autostart 文件格式验证通过"
|
||
else
|
||
warn "desktop-file-validate 报告了警告,但通常不影响功能"
|
||
fi
|
||
fi
|
||
|
||
# ---- 4. 可选:立即启动 ----
|
||
echo ""
|
||
echo -n "${C_BOLD}是否立即启动 ghost(验证 X 环境)?[Y/n]${C_RESET} "
|
||
read -r ans
|
||
if [[ -z "${ans}" || "${ans}" =~ ^[Yy]$ ]]; then
|
||
if [[ -z "${DISPLAY:-}" ]]; then
|
||
warn "当前 shell 没有 DISPLAY 变量,可能不在桌面会话内 — 启动后远控仍可能 0x0"
|
||
warn "建议在 GNOME 终端/桌面环境的终端里运行此脚本"
|
||
fi
|
||
nohup "${DEST_BIN}" >/dev/null 2>&1 &
|
||
sleep 1
|
||
if pgrep -x ghost > /dev/null; then
|
||
ok "ghost 已启动 (PID=$(pgrep -x ghost | head -1))"
|
||
else
|
||
error "启动失败,请手动跑 ${DEST_BIN} 看错误输出"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
echo "${C_GREEN}${C_BOLD}✓ 安装完成${C_RESET}"
|
||
echo ""
|
||
echo "下次开机将自动启动;如需立即测试,重启或在桌面终端跑:"
|
||
echo " ${DEST_BIN}"
|
||
echo ""
|
||
echo "卸载请运行同目录的 ./uninstall.sh"
|