我有一个以 root 身份运行的脚本,并尝试让它设置用户服务来运行 IPFS 守护进程。问题是我需要以用户身份而不是 root 身份启用该服务。它通常在重新启动后起作用,但我想如果可以的话避免这种情况。
服务脚本位于~/.config/systemd/user/ipfs.service
它包含了:
[Unit]
Description=IPFS daemon
[Service]
# Environment="IPFS_PATH=/data/ipfs" # optional path to ipfs init directory if not default (\$HOME/.ipfs)
ExecStart=/usr/local/bin/ipfs daemon
Restart=on-failure
[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)
(我从这里获取了这段代码:https ://github.com/ipfs/go-ipfs/tree/master/misc )
如果我以用户身份运行这些命令,它可以正常工作:
systemctl --user enable ipfs
systemctl --user start ipfs
Run Code Online (Sandbox Code Playgroud)
问题是我的脚本以 root 身份运行,我不知道如何让它以用户身份运行。到目前为止我已经尝试过了:
# Enable linger so IPFS can run at boot
loginctl enable-linger $USER_ACCOUNT
# Enable the service to run at boot
sudo -u $USER_ACCOUNT systemctl --user enable ipfs
# Start the service now
sudo -u $USER_ACCOUNT systemctl --user start ipfs
Run Code Online (Sandbox Code Playgroud)
不幸的是,服务无法启动,当我收到此错误消息时:
无法连接到总线:$DBUS_SESSION_BUS_ADDRESS 和 $XDG_RUNTIME_DIR 未定义(考虑使用 --machine=@.host --user 连接到其他用户的总线)
一旦脚本完成并重新启动,服务就会正常启动,但我希望避免用户必须重新启动(如果可以的话)。任何帮助,将不胜感激。
假设someuser
使用bash作为登录 shell,请将以下导出添加到~someuser/.profile
[1]:
export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
Run Code Online (Sandbox Code Playgroud)
然后,具有 root/ sudo权限的用户可以someuser
通过将命令包装为与 systemd交互runuser
:
sudo runuser someuser -l -c "systemctl --user enable ipfs"
sudo runuser someuser -l -c "systemctl --user start ipfs"
Run Code Online (Sandbox Code Playgroud)
runuser someuser -l -c "printenv"
可以帮助对这些和其他导出的环境变量进行故障排除。
[1]:相反,将这些导出放入~someuser/.bashrc
可能会无效,因为默认设置.bashrc
通常设置为在检测到正在非交互式运行时提前退出;请参阅https://unix.stackexchange.com/a/257613/20230
一般来说,设置XDG_RUNTIME_DIR
和DBUS_SESSION_BUS_ADDRESS
手动/显式更像是一种解决方法;更好的方法是使用 user正确登录someuser
。正确登录将自动设置这些环境变量,并避免someuser
原始用户的设置污染环境变量。
这种正确的登录可以通过命令完成machinectl
,例如对于Ubuntu 22.04 LTS jammy可以通过 apt package 获得systemd-container
。
可用时machinectl
,任何用户都可以正确someuser
登录到其 shell,并正确设置所有环境变量:
sudo machinectl shell someuser@
Run Code Online (Sandbox Code Playgroud)
这些变量是用户特定的。它们是在用户登录时由 systemd 的用户实例设置的。如果您的脚本作为系统服务运行,那么它当然无法访问特定用户的此变量。
如果您使用systemctl --user --global enable
,则将为所有用户启用该服务。
我在 Ubuntu 22.04 LTS 上按照https://docs.docker.com/desktop/install/ubuntu/安装 docker-desktop 后遇到了这个问题。
以下解决了这个问题。首先检查“下载”目录中下载的 .deb 文件的权限,或者只是设置它:
sudo chmod 755 docker-desktop-<version>-<arch>.deb
接下来将您的用户添加到 docker 组:
sudo usermod -aG docker $USER
激活对组的更改:
newgrp docker
现在尝试执行命令来启动 docker-desktop:
systemctl --user start docker-desktop
要修复 docker-desktop 的 docker-hub 登录问题:
https://docs.docker.com/desktop/get-started/#credentials-management-for-linux-users
参考:https: //docs.docker.com/engine/install/linux-postinstall/
归档时间: |
|
查看次数: |
25302 次 |
最近记录: |