Systemd 在运行 ExecStart 命令时看不到外部驱动器分区

Systemd 在运行 ExecStart 命令时看不到外部驱动器分区

我正在尝试在启动时运行 calibre-server。以下是服务内容的示例

[Unit]
Description=calibre Content server
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/opt/calibre/calibre-server "/path-to-mounted-external-hdd-partition/Calibre Library"

[Install]
WantedBy=multi-user.target

当我检查服务状态时:sudo systemctl status calibre-server.service

我收到以下消息:There is no calibre library at: /path-to-mounted-external-hdd-partition/Calibre Library

但是当我打字时:sudo systemctl start calibre-server.service它启动得很顺利。

我的假设是,在服务最初运行时,分区和文件夹结构尚未安装/可用。所以我尝试替换执行开始以及ExecStart=/test.sh内容测试文件

#!/bin/bash

ls -la /path-to-mounted-external-hdd-partition/ 2> /out.txt >> /out.txt

结果存储在输出文件显示(简化以简洁):

.
..

看来服务运行时外部硬盘的内容是空的。

这是为什么?我该如何解决?

附言我不知道这是否重要,但安装是通过 ubuntu/disks 应用程序完成的,而不是通过/etc/fstab

聚苯硫醚 systemctl list-units | grep '\.mount'

-.mount                   loaded active mounted   Root Mount
...
media-XXX-Storage.mount   loaded active mounted   /media/XXX/Storage

在哪里/媒体/XXX/存储正是我所描述的/安装外部硬盘分区的路径

答案1

这个答案取决于我根据您的编辑和评论做出的假设。

您使用的挂载是外部挂载,并且您依赖于 GNOME 的自动挂载功能。您没有在 systemd 中配置它,fstab也没有将其配置为 systemd 挂载。这个假设主要是因为您提到的ls目录显示为空,而事实并非如此。而且目录位于 下/media/XXX

systemctl list-units | grep '\.mount'自动安装的驱动器在启动期间不可用。您可以通过在测试中运行编辑中的命令而不是ls命令来确认这一点。结果不会显示安装点。因此将它们添加为依赖项不会产生任何效果,因为这些安装点是在您登录用户会话后自动生成的。

您可以尝试使用用户服务而不是系统服务。在这种情况下,你可能会发现Daniel T 的循环方法

在下面创建服务~/.config/systemd/user/your-service-name.service并在传递--usersystemctl命令时启用它。

systemctl --user enable your-service-name

否则,我建议的更安全的方法是添加一个fstab条目(或 systemd .mount 条目)来挂载驱动器。然后,正如其他答案所建议的那样,您可以将其用于RequiresRequiresMountsFor

附言:这与您的问题没有直接关系,但是如果ls -la /path-to-mounted-external-hdd-partition/您在启动时显示一个空目录,而您希望它显示磁盘的内容,那是因为该目录存在。挂载驱动器时,路径将从本地路径替换为挂载的驱动器。

您可以通过完全拔下驱动器并尝试该ls命令来测试这一点,看看是否会导致No such file or directory错误。

答案2

如果您需要在运行服务单元之前安装某个路径,您也可以RequiresMountsFor=[Unit]部分中添加指令。这将检查该路径是否可用。因此,在给定情况下,完整的指令将是 RequiresMountsFor="/path-to-mounted-external-hdd-partition

有关该指令的更多信息,请查看systemd 单元文档

答案3

您的 calibre-server 在您的挂载准备就绪之前启动。让我们添加正确的顺序依赖项(EDIT 请跳到我的第二个解决方案,或使用@noisefloor 的回答作为我的第一个解决方案的更清晰的版本):

[Unit]
Description=calibre Content server
After=network.target
# Added: wait for mount.
After=media-XXX-Storage.mount
# Added: Pull in the mount job if for some reason it's not
# started directly or indirectly by multi-user.target . Thanks @muru
Requires=media-XXX-Storage.mount

[Service]
Type=simple
User=root
Group=root
ExecStart=/opt/calibre/calibre-server "/path-to-mounted-external-hdd-partition/Calibre Library"

[Install]
WantedBy=multi-user.target

如果这不起作用,您可以在开始时添加一个循环来测试里面的文件:

[Unit]
Description=calibre Content server
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/opt/calibre/calibre-server "/path-to-mounted-external-hdd-partition/Calibre Library"
# Added: wait for mount, workaround
ExecStartPre=/bin/bash -c "while ! grep -q '/media/XXX/Storage' /proc/mounts; do sleep 1; done"
# Don't let the above command time out
TimeoutStartSec=infinity

[Install]
WantedBy=multi-user.target

答案4

设置静态安装后,/etc/fstab它可以按照您建议的设置工作。

[Unit]
Description=calibre Content server
After=network.target
RequiresMountsFor=/media/XXX/Storage

[Service]
Type=simple
User=user
Group=user
ExecStart=/opt/calibre/calibre-server "/home/XXX/Storage/Calibre Library"

[Install]
WantedBy=multi-user.target

谢谢大家的帮助。

相关内容