我尝试创建一个 DEB 文件来安装 systemd 用户服务,并使用 postinst 脚本在安装后启用该服务。这是我的 postinst 脚本:
#!/bin/bash
set -e
systemctl --user enable myservice.service
当我安装 DEB ( dpkg --install mypackage.deb
) 时,它运行 postinst 脚本并返回以下错误消息:
无法连接到总线:没有这样的文件或目录
我也不能使用系统服务,并且包不会被发布,所以我不关心任何打包标准。我能做些什么来让这项工作成功吗?
如果不可能,我会将其添加到我的初始化脚本中,以便在每次启动后启用它,但如果可能的话,我想避免这种情况。
答案1
你试图做的事情是行不通的。为执行安装的用户安装 systemd 服务并不是很有用,因为该用户始终是 root。因此,您可能应该遵循将服务安装为所有用户的系统范围服务的约定。以下是执行此操作的标准方法:
现在大多数软件包都使用 debhelper - 它大大简化了过程。以下步骤应该可以帮助您入门。请参阅Debian Wiki 的 systemd 打包指南了解更多信息。
启用 dh_systemd
使用 debhelper compat level 10(检查和Build-Depends
中的部分),dh-systemd 会自动启用,您可以跳过此部分。对于较旧的 debhelper 兼容级别,您必须按照以下步骤启用它:debian/control
debian/compat
- 添加
dh-systemd (>=1.5)
到Build-Depends
中debian/control
。 - 附加
--with systemd
到您的dh $@
行中debian/rules
。
使用 dh_systemd
将您的 systemd 单元文件放入其中,debian/
以便安装它们。 Debhelper 将在软件包安装过程中自动检测并启用它们。
注意:无需向postinst
和postrm
脚本添加任何内容,debhelper 会自动为您处理这些事情。另请记住,您的手动方法依赖于systemctl
可执行文件,因此仅适用于用户安装软件包时已安装 systemd 的计算机。即使未安装 systemd,debhelper 方法也将启用 systemd 服务。如果用户稍后切换到 systemd,该服务已启用。如果您的软件包同时附带旧的 Sys-V 风格的初始化脚本和 systemd 单元文件,则 debhelper 方法也能很好地工作。
提前使用
如果您有特殊需求(例如安装多个单元文件但仅启用其中的一个子集),您可以覆盖dh_systemd_enable
和dh_systemd_start
中的目标debian/rules
并指定其他参数。请参阅dh_systemd_enable 的手册页和dh_systemd_启动了解详情。
答案2
正如马丁·康拉德所说,--user
按原样尝试安装服务根用户,这可能不是您想要的。
就我而言,我遇到了这个问题,但我确实需要为用户安装该服务,因为它必须访问音频系统,并且只有在为特定最终用户设置系统时才有效(并且该最终用户已登录) ——我的嵌入式系统就是这种情况)。
以下是我用来设置用户特定服务的几行代码:
# Manually enable "service-name" for USER_NAME
USER_NAME=nobody
mkdir -p /home/${USER_NAME}/.config/systemd/user/default.target.wants
chown -R ${USER_NAME}:${USER_NAME} /home/${USER_NAME}/.config/systemd
rm -f /home/${USER_NAME}/.config/systemd/user/default.target.wants/service-name.service
sudo -H -u ${USER_NAME} sh -c "ln -s /usr/lib/systemd/user/service-name.service /home/${USER_NAME}/.config/systemd/user/default.target.wants/service-name.service"
确保编辑要为其启用服务的用户的名称 ( USER_NAME=...
)。
替换service-name
为您的用户服务的名称。例如,如果它管理声音,您可以将其称为sound-manager
.
注1:该脚本假设用户是在 下创建的/home/<username>
。如果您使用不同的用户,则需要根据您的情况进行调整(即帐户root
出现在 下/root
,Debian/Ubuntu 上的 Apache2 帐户出现在 下/var/www
,等等)
笔记2:这一切你是怎么做到的?!事实上,这个脚本本身并不是我发明的。当您以 登录时$USER_NAME
,您可以使用以下命令启用该服务:
systemctl enable --user service-name
这将创建如上所示的目录和链接。如果事情发生变化或保存在不同的目录中,那么您可能需要调整命令来复制systemctl
所做的事情。
注3:您可以为所有用户安装它。在名称上添加一个循环/home/*
,并对每个名称重复命令。还有一组脚本在创建新用户时运行。希望您不需要此类服务。我认为最好让每个用户自己启用这样的服务。