我正在尝试在启动时运行 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
并在传递--user
给systemctl
命令时启用它。
systemctl --user enable your-service-name
否则,我建议的更安全的方法是添加一个fstab
条目(或 systemd .mount 条目)来挂载驱动器。然后,正如其他答案所建议的那样,您可以将其用于Requires
或RequiresMountsFor
。
附言:这与您的问题没有直接关系,但是如果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
谢谢大家的帮助。