集成 venv 方案: 安装脚本 + 服务文件适配虚拟环境

- install.sh: 创建 .venv、安装 adbutils、生成包装脚本使用 venv python
- padsleep.service: ExecStart 指向 .venv/bin/python3
- requirements.txt: 添加 venv 安装说明
- 解决 PEP 668 (externally-managed-environment) 问题
This commit is contained in:
kushidou
2026-07-10 19:45:50 +08:00
parent 36fe0bb4fd
commit e17d03cea9
3 changed files with 44 additions and 10 deletions
+39 -9
View File
@@ -3,6 +3,7 @@
# 用法: sudo ./install.sh
#
# 将程序安装到 /opt/apps/padsleep,创建命令行软链接。
# 自动创建 Python 虚拟环境并安装依赖。
# 代码中 SCRIPT_DIR 使用 Path(__file__).resolve().parent
# 会自动适配安装路径,无需修改代码。
@@ -11,6 +12,8 @@ set -e
INSTALL_DIR="/opt/apps/padsleep"
BIN_DIR="/usr/local/bin"
SERVICE_DIR="/etc/systemd/system"
VENV_DIR="$INSTALL_DIR/.venv"
PYTHON_BIN="$VENV_DIR/bin/python3"
# 颜色
RED='\033[0;31m'
@@ -40,7 +43,6 @@ fi
# ── 确定运行用户(sudo 的原用户)──
RUN_USER="${SUDO_USER:-}"
if [ -z "$RUN_USER" ]; then
# fallback: 从服务文件提取 User= 字段
if [ -f "$SRC_DIR/padsleep.service" ]; then
RUN_USER=$(grep '^User=' "$SRC_DIR/padsleep.service" | head -1 | cut -d= -f2)
fi
@@ -75,6 +77,25 @@ fi
touch "$INSTALL_DIR/padsleep.log"
chmod 644 "$INSTALL_DIR/padsleep.log"
# ── 创建 Python 虚拟环境 ──
if [ ! -d "$VENV_DIR" ]; then
info "正在创建 Python 虚拟环境..."
python3 -m venv "$VENV_DIR"
info "虚拟环境已创建: $VENV_DIR"
else
info "虚拟环境已存在,跳过创建"
fi
# ── 安装 Python 依赖 ──
info "正在安装 Python 依赖..."
"$VENV_DIR/bin/pip" install --quiet adbutils 2>&1 || {
warn "pip 安装失败,尝试离线安装..."
if [ -f "$SRC_DIR/.venv" ]; then
cp -r "$SRC_DIR/.venv" "$VENV_DIR"
fi
}
info "Python 依赖安装完成"
# 设置执行权限
chmod 755 "$INSTALL_DIR/padsleep.py"
chmod 755 "$INSTALL_DIR/padsleep_tui.py"
@@ -85,19 +106,28 @@ chmod 755 "$INSTALL_DIR"
chmod 644 "$INSTALL_DIR/padsleep.log" 2>/dev/null
info "文件所有权已设置为 $RUN_USER"
# ── 创建软链接 ──
ln -sf "$INSTALL_DIR/padsleep.py" "$BIN_DIR/padsleep"
ln -sf "$INSTALL_DIR/padsleep_tui.py" "$BIN_DIR/padsleep-config"
info "已创建命令软链接:"
info " $BIN_DIR/padsleep → 启动守护进程"
info " $BIN_DIR/padsleep-config → 启动 TUI 配置工具"
# ── 创建命令包装脚本(使用 venv Python──
create_wrapper() {
local script="$1" # padsleep.py 或 padsleep_tui.py
local link="$2" # /usr/local/bin/padsleep
cat > "$link" <<WRAPPER
#!/bin/bash
exec "$PYTHON_BIN" "$INSTALL_DIR/$script" "\$@"
WRAPPER
chmod 755 "$link"
}
create_wrapper "padsleep.py" "$BIN_DIR/padsleep"
create_wrapper "padsleep_tui.py" "$BIN_DIR/padsleep-config"
info "已创建命令入口:"
info " $BIN_DIR/padsleep → 启动守护进程 ($PYTHON_BIN)"
info " $BIN_DIR/padsleep-config → 启动 TUI 配置工具 ($PYTHON_BIN)"
# ── 可选:复制 systemd 服务 ──
if [ -f "$SRC_DIR/padsleep.service" ]; then
# 复制并更新服务文件中的路径和用户
cp "$SRC_DIR/padsleep.service" "$SERVICE_DIR/padsleep.service"
sed -i "s|WorkingDirectory=.*|WorkingDirectory=$INSTALL_DIR|" "$SERVICE_DIR/padsleep.service"
sed -i "s|ExecStart=.*|ExecStart=/usr/bin/python3 $INSTALL_DIR/padsleep.py|" "$SERVICE_DIR/padsleep.service"
sed -i "s|ExecStart=.*|ExecStart=$PYTHON_BIN $INSTALL_DIR/padsleep.py|" "$SERVICE_DIR/padsleep.service"
sed -i "s|^User=.*|User=$RUN_USER|" "$SERVICE_DIR/padsleep.service"
systemctl daemon-reload
info "已复制 systemd 服务文件: $SERVICE_DIR/padsleep.service"