Какой PID принадлежит разделу systemd PIDFile при создании демона сценария оболочки?

Если ваш вопрос можно переформулировать как «распечатать все поля, разделенные пробелами , заканчивающиеся на .local.com », то это должно сделать следующее (с использованием GNU grep):

grep -Eo '[^ ]+\.local\.com\b'
6
03.08.2018, 15:53
2 ответа

Хорошо, сообщение об ошибке daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directoryисчезло после того, как я добавил следующий оператор в служебный файл:

ExecStartPost=/bin/sleep 2
5
27.01.2020, 20:23

Таким образом, проблема, которую вы здесь видите, заключается в том, что когда 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 сделать всю тяжелую работу за вас! Так намного эффективнее.

12
27.01.2020, 20:23

Теги

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