Блок 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?

0
задан 29 February 2020 в 14:42

2 ответа

Вы должны поместить все, что хотите запустить, в бесконечный цикл без кода выхода и сна 15 например. чтобы служба продолжалась.

-1
ответ дан 5 August 2020 в 09:40

Хотя я не знаю, почему ваш скрипт не удается, я вижу несколько вещей, которые следует исправить, что может приблизить вас к решению, даже если они сами по себе не являются решением:

  • При запуске исполняемого скрипта, в котором есть соответствующую оболочку/интерпретатор, как в вашем примере, не вызывайте /bin/bash явно, когда вы хотите запустить скрипт. Просто вызовите скрипт.
  • Если и когда вам действительно нужно передавать команды непосредственно в вызове bash, используйте синтаксис /bin/bash -c "<команды для выполнения>". В вашем примере сначала запускается /bin/bash без аргументов или команд, а затем (как отдельная вторая команда) запускается ваш скрипт. В службе типа oneshot, которая на самом деле не должна ничего ломать, но имейте в виду, что oneshot — это единственный тип службы, который допускает более одной команды таким образом.
  • Помещая единственную команду в сценарий оболочки в этом контексте, все, что вы действительно делаете, это делает все непрозрачным для systemd. Попробуйте просто поместить команду mergerfs непосредственно в директиву ExecStart= юнит-файла (вам может понадобиться заключить ее в двойные кавычки).Таким образом, systemd может зафиксировать статус выхода mergerfs, а журнал journalctl будет содержать любые выходные данные и/или сообщения об ошибках, созданные mergerfs. Затем, если это не удается, у вас должна быть некоторая информация о том, почему.

Примечание. Например, файлы .desktop, используемые для автозапуска полезных функций рабочего стола, принимают только одну команду. Если вы хотите, скажем, автоматически запустить программу после небольшой задержки, эта одна команда может быть /bin/bash -c "sleep 10; <программа для запуска>". Она работает, потому что вы на самом деле передаете строка команд в двойных кавычках для bash в качестве аргумента, поэтому единственная команда, запускаемая из файла .desktop, — это сам bash.

1
ответ дан 14 November 2020 в 20:26

Другие вопросы по тегам:

Похожие вопросы: