Systemd 单元无法运行 bash 脚本,但该脚本可以正常运行

Systemd 单元无法运行 bash 脚本,但该脚本可以正常运行

我有以下脚本:

#!/bin/bash

echo "Merging pool...";

if !(mergerfs -o minfreespace=4G,defaults,allow_other,category.create=ff /media/pool/hdd1:/media/pool/hdd2:/media/pool/hdd4:/media/pool/hdd5 /media/pool/merged/)
then
        echo "Merging failed."
        exit 1;
fi

echo "Done";

exit 0;

它保存在 /home/me/scripts/mergePool.sh 中。如果我像这样手动运行脚本:sudo ./mergePool.sh,它就可以正常工作

我在 /etc/systemd/system/mergePool.service 中创建了这个单元:

[Unit]
Description=Merge all pool drives into one big virtual drive

[Service]
Type=oneshot
ExecStart=/bin/bash /home/me/scripts/mergePool.sh

[Install]
WantedBy=multi-user.target

如果我像这样运行该装置:

sudo systemctl start mergePool.service

它不会产生任何错误并且根本不起作用。

这是日志:

sudo systemctl status mergePool.service
● mergePool.service - Merge all pool drives into one big virtual drive
   Loaded: loaded (/etc/systemd/system/mergePool.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Sat 2020-02-29 12:26:07 CET; 6min ago
  Process: 2066 ExecStart=/bin/bash /home/me/scripts/mergePool.sh (code=exited, status=0/SUCCESS)
 Main PID: 2066 (code=exited, status=0/SUCCESS)

Feb 29 12:26:07 junkbox systemd[1]: Starting Merge all pool drives into one big virtual drive...
Feb 29 12:26:07 junkbox bash[2066]: Merging pool...
Feb 29 12:26:07 junkbox bash[2066]: Done
Feb 29 12:26:07 junkbox systemd[1]: Started Merge all pool drives into one big virtual drive.

这让我很困惑,为什么当脚本由 systemd 运行时它不起作用?

答案1

虽然我不知道你的脚本为什么失败了,但我确实看到了一些应该修复的问题,即使它们本身不是解决方案,这些问题也可能让你更接近解决方案:

  • /bin/bash当启动一个可执行脚本时,如果该脚本有一个指定适当 shell/解释器的 sha-bang,就像您的示例一样,当您想要运行该脚本时,不要明确调用。只需调用该脚本即可。
  • 如果您确实需要在 bash 调用中直接传递命令,则语法为/bin/bash -c "<commands to execute>"。您的示例所做的是首先运行/bin/bash没有参数或命令的脚本,然后(作为完全独立的第二个命令)运行您的脚本。在单次运行类型的服务中,实际上不应该破坏任何东西,但请记住,单次运行是仅有的允许以此方式发出多个命令的服务类型。
  • 在此上下文中,通过用 shell 脚本包装单个命令,您真正要做的就是使事情对 systemd 不透明。尝试将您的mergerfs命令直接放在单元文件的ExecStart=指令中(您可能需要将其括在双引号中)。这样,systemd 就可以捕获 的mergerfs退出状态,并且journalctl日志将包含 产生的任何输出和/或错误消息mergerfs。然后,如果它失败了,您应该会有一些关于原因的信息。

注意:例如,用于自动启动桌面小工具的 .desktop 文件仅接受一个命令。例如,如果您想在稍等片刻后自动启动某个程序,那么这个命令就可以了。它之所以/bin/bash -c "sleep 10; <program to launch>"有效,是因为您实际上是将双引号内的命令字符串作为参数传递给 bash,因此从 .desktop 文件运行的唯一命令就是 bash 本身。

答案2

您应该将要运行的整个过程放入没有退出代码和 sleep 15 的无限循环中,例如,以使服务持续进行。

相关内容