I have the following script:
#!/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;
It is saved in /home/me/scripts/mergePool.sh.
If I manually run the script like this: sudo ./mergePool.sh
, it works fine
I made this unit in /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
If I run the unit like this:
sudo systemctl start mergePool.service
It produces no error and it doesn't work at all.
This is the log:
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.
This is quite confusing to me, why doesn't it work when the script is ran by systemd?
While I don't know why your script is failing, I do see a couple of things that should be fixed, which might get you closer to a solution even if they aren't the solution in and of themselves:
/bin/bash
explicitly when you want to run the script. Just call the script./bin/bash -c "<commands to execute>"
. What your example is doing is first running/bin/bash
with no arguments or commands, then (as a completely separate second command) running your script. In a oneshot type service that shouldn't actually break anything, but do keep in mind that oneshot is the only service type that allows more than one command in this way.mergerfs
command directly in the unit file'sExecStart=
directive (you may need to enclose it in double quotes). That way systemd can capturemergerfs
's exit status, and thejournalctl
log will contain any output and/or error messages produced bymergerfs
. Then if it fails you should have some information as to why.Note: For example, the .desktop files used for autostarting desktop goodies only accept one command. If you want to, say, autostart a program after a little delay, that one command could be
/bin/bash -c "sleep 10; <program to launch>"
It works because you're actually passing the double-quoted string of commands to bash as an argument, so the only command being run from the .desktop file is bash itself.You should put the whole thing you want to run into an infinite loop without the exit code and a sleep 15 eg. to make the service ongoing.