Таким образом, проблема, которую вы здесь видите, заключается в том, что когда Type=forking
используется, файл pid должен быть создан (с правильным pid )перед выходом родительского процесса.
Если создать pidfile из дочернего, то он будет гоняться с выходом родителя и в некоторых (многих? )случаев вызовут первую ошибку, которую вы видите.
Если вы создадите pid-файл, написав в него $$
до того, как запустите дочерний процесс, тогда он будет иметь pid родителя, который завершился, поэтому вы увидите другую ошибку.
Один из способов сделать это правильно — записать pid-файл из родителя непосредственно перед выходом. В этом случае напишите $!
(, а не $$
), что вернет pid последнего процесса, запущенного в фоновом режиме.
Например:
#!/bin/bash
# Run the following code in background:
(
while keep_running; do
do_something
done
) &
# Write pid of the child to the pidfile:
echo "$!" >/run/daemon.pid
exit
Это должно работать правильно... ОДНАКО , есть гораздо лучший способ сделать это! Читайте дальше...
На самом деле, весь смысл systemd в том, чтобы демонизировать процессы и запускать их в фоновом режиме для вас... Пытаясь сделать это самостоятельно, вы просто мешаете systemd сделать это за вас. Что в то же время сильно усложняет вашу жизнь...
Вместо использования Type=forking
просто напишите сценарий оболочки для запуска на переднем плане и настройте службу для использования Type=simple
. Тогда вам не нужны никакие pid-файлы.
Обновите свой /root/bin/daemon.sh
, чтобы просто сделать это:
#!/bin/bash
# Run the following code in foreground:
while keep_running; do
do_something
done
(ПРИМЕЧАНИЕ. :Возможно, daemon.sh
— не лучшее название для него на данный момент... Так как это означает, что он работает в фоновом режиме. Может быть, назовите его как-то более подходящим, связанным с тем, что он на самом деле делает.)
Затем обновите файл .service
, чтобы использовать Type=simple
(, который на самом деле будет использоваться здесь по умолчанию, так что вы даже можете его опустить.)
[Service]
Type=simple
ExecStart=/root/bin/daemon.sh
ExecReload=/bin/kill -1 -- $MAINPID
ExecStop=/bin/kill -- $MAINPID
TimeoutStopSec=5
KillMode=process
Кстати, вы, вероятно, можете бросить ExecStop=
,поскольку уничтожение процесса с помощью сигнала также является поведением по умолчанию...
systemd Type=forking
на самом деле существует только для устаревших программ, которые работают только таким образом и не могут быть легко исправлены для работы на переднем плане... Это хакерский и неэффективный. Весь смысл systemd (и некоторых его альтернатив, предшественников ), состоит в том, чтобы разветвляться и демонизировать себя, а службам просто беспокоиться о том, что им нужно делать!:-)
Я надеюсь, что вы найдете это полезным... И я действительно надеюсь, что вы решите позволить systemd сделать всю тяжелую работу за вас! Так намного эффективнее.
Я не уверен, что понял ваш вопрос, но, вероятно, вы ищете mknod
.
sudo mknod sda b 8 0
sudo mknod sda1 b 8 1
sudo mknod sda2 b 8 2