diff --git a/install.sh b/install.sh index 1c6146b..a85e933 100644 --- a/install.sh +++ b/install.sh @@ -12,9 +12,54 @@ die() { printf '\033[1;31m错误:\033[0m %s\n' "$*" >&2; exit 1; } [ "$(uname)" = "Linux" ] || [ "$(uname)" = "Darwin" ] || die "此脚本仅支持 Linux / macOS" -# ---------- 依赖 ---------- -need_py() { - command -v python3 >/dev/null 2>&1 || die "未找到 python3,请先安装 Python 3.10+" +# ---------- 系统包管理器 ---------- +PKG_MGR="" +for m in apt-get dnf yum zypper pacman apk; do + command -v "$m" >/dev/null 2>&1 && { PKG_MGR="$m"; break; } +done + +as_root() { + if [ "$(id -u)" = 0 ]; then "$@" + elif command -v sudo >/dev/null 2>&1; then sudo "$@" + else die "需要 root 权限但未找到 sudo,请手动安装后重试"; fi +} + +# 各发行版补齐 python3+venv 所需的包 +py_pkgs() { + case "$PKG_MGR" in + apt-get) echo "python3 python3-venv" ;; + dnf|yum) echo "python3 python3-pip" ;; + zypper) echo "python3 python3-pip" ;; + pacman) echo "python python-pip" ;; + apk) echo "python3 py3-pip py3-virtualenv" ;; + *) echo "" ;; + esac +} + +pkg_install() { + [ -n "$PKG_MGR" ] || return 1 + say "自动安装系统依赖($PKG_MGR): $* — 可能要求输入密码" + case "$PKG_MGR" in + apt-get) as_root apt-get update -qq >/dev/null 2>&1 || true; as_root apt-get install -y "$@" ;; + dnf) as_root dnf install -y -q "$@" ;; + yum) as_root yum install -y -q "$@" ;; + zypper) as_root zypper --non-interactive install "$@" ;; + pacman) as_root pacman -S --noconfirm --needed "$@" ;; + apk) as_root apk add "$@" ;; + esac +} + +# ---------- Python 检查 + 自动补齐 ---------- +ensure_python() { + if ! command -v python3 >/dev/null 2>&1; then + say "未找到 python3,尝试自动安装 ..." + pkgs="$(py_pkgs)" + [ -n "$pkgs" ] || die "未识别到包管理器,请手动安装 Python 3.10+ 后重试" + pkg_install $pkgs || die "自动安装 Python 失败,请手动安装后重试" + command -v python3 >/dev/null 2>&1 || die "python3 仍不可用,请手动安装" + fi + + local pyver pyver=$(python3 -c 'import sys;print("%d.%d"%sys.version_info[:2])') case "$pyver" in 3.1[0-9]|3.[2-9][0-9]|[4-9].*) ;; @@ -22,6 +67,19 @@ need_py() { esac } +ensure_venv() { + if python3 -c "import ensurepip" >/dev/null 2>&1; then return 0; fi + say "系统 Python 缺少 venv/ensurepip 组件,尝试自动安装 ..." + pkgs="$(py_pkgs)" + [ -n "$pkgs" ] || die "当前平台无包管理器可自动补齐(如 macOS 可执行: xcode-select --install 或 brew install python)" + pkg_install $pkgs || die "自动安装 venv 组件失败,请手动执行后重试" + python3 -c "import ensurepip" >/dev/null 2>&1 \ + || die "venv 组件仍未就绪,请手动安装(Debian/Ubuntu: sudo apt install python3-venv)" +} + +ensure_python +ensure_venv + # ---------- 下载源码 ---------- say "下载最新代码到 $APP_DIR ..." mkdir -p "$APP_DIR" @@ -43,13 +101,14 @@ if [ ! -f "$APP_DIR/cli.py" ]; then fi [ -f "$APP_DIR/cli.py" ] || die "代码下载失败,请检查网络后重试" -# ---------- 虚拟环境 ---------- -if [ ! -x "$APP_DIR/.venv/bin/python" ]; then +# ---------- 虚拟环境(不完整则整体重建) ---------- +if [ ! -f "$APP_DIR/.venv/deps-done" ]; then + rm -rf "$APP_DIR/.venv" say "创建虚拟环境并安装依赖(首次约 1-2 分钟)..." - need_py - python3 -m venv "$APP_DIR/.venv" -fi -if [ ! -e "$APP_DIR/.venv/deps-done" ]; then + python3 -m venv "$APP_DIR/.venv" || { + rm -rf "$APP_DIR/.venv" + die "虚拟环境创建失败(Debian/Ubuntu 可执行: sudo apt install python3-venv)" + } "$APP_DIR/.venv/bin/pip" install --quiet --disable-pip-version-check \ paramiko cryptography keyring > /dev/null touch "$APP_DIR/.venv/deps-done"