Автозапуск демона

SergJP

New member
Сообщения
4
#1
Коллеги, добрый день!
Возникла проблема, никак не удается запустить программу при загрузке системы. Пробовал и через system.d и через init.d
Скрипты прилагаю

файл pg_agent.service лежит в /etc/systemd/system
Код:
[Unit]
  Description=Lira database frequent tasks service

[Service]
  Type=forking
  ExecStart=/home/user0/pgagent/pg_agent
  User=user0
  Group=root
  Environment=LD_LIBRARY_PATH=/home/user0/pgagent/lib



[Install]
  WantedBy=multiuser.target
и файл pg_agent.sh лежит в /etc/init.d с правами выполнения
Код:
!/bin/bash
#
### BEGIN INIT INFO
# Provides:          pg_agent
# Required-Start:    $all
# Required-Stop:     $all
# Should-Start:      $all
# Should-Stop:       $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Lira database frequent tasks service
# Description:       Lira database frequent tasks service
### END INIT INFO

export LD_LIBRARY_PATH=/home/user0/pgagent/lib

service_name="pg_agent"
DAEMON="/home/user0/pgagent/pg_agent"
PIDFILE=/var/run/pg_agent.pid

test -x $DAEMON || exit 0

. /lib/lsb/init-functions

start() {
log_daemon_msg "Starting pg_agent..."
start_daemon -p $PIDFILE $DAEMON
log_end_msg $?
}
stop() {
log_daemon_msg "Stopping pg_agent..."
killproc -p $PIDFILE $DAEMON
log_end_msg $?
}
status() {
if (( $(ps -ef | grep -v grep | grep $service_name | wc -l) > 0 )); then
     echo "$service_name is running!!!"
else
     echo "$service_name is down!!!"
fi
}
case $1 in
  start|stop|status) $1;;
  restart) stop; start;;
  *) echo "Usage : $0 <start|stop|restart>"; exit 1;;
esac

exit 0
Команду update-rc.d pg_agent.sh выполнил, сработала молча.
При загрузке программа не стартует, journalctl ничего про нее не показывает. Такое впечатление, что Астра ее и не собиралась запускать.
Что-то я не доделал?
Система Астра Орел 2.12.39
 

oko

New member
Сообщения
1 246
#2
to SergJP
Primo, если скрипт называется pg_agent.sh, то у вас неверно указано имя скрипта в ExecStart...
Secundo, почитайте про:
  • очередность запуска (After= и Before=) - если ваш скрипт не просто выдает сообщение о своем старте/останове, а имеет зависимости от других сервисов - это вам точно понадобится;
  • опцию RemainAfterExit=True, которая настоятельно рекомендуется для условно регулируемых сервисов;
  • необходимость и достаточность systemctl enable имя-сервиса && systemctl daemon-reload (reload также при внесении изменений в Unit зачастую требуется) - никаких update-rc и никаких размещений в /etc/init.d (впрочем, поскольку Debian оставил обратную совместимость с SysVInit, так тоже можно, но... сложнее и не нужно)...
Tertio, состояние Type=forking имеет смысл для скрипта, который будет долгое время висеть в памяти отдельным процессом. Для всего остального и утилитарного настоятельно рекомендуется Type=oneshot...
Главное. Можно сделать сервис, запускаемый от лица какого-либо пользователя, через sudo...
[Unit]
Description=Autoloading bla-bla-bla
After=rsyslog.service
[Service]
Type=oneshot
RemainAfterExit=True
ExecStart=/usr/bin/sudo -u user123 /opt/myscript.sh
[Install]
WantedBy=multi-user.target

ЗЫ Знатоки systemd-диалекта могут раскритиковать, но... приведенные выкладки однозначно работают (только что проверил, ага). Да и не люблю я это нестабильное поделие - SysVInit был сложнее в оформлении и логике, зато с куда более гибким управлением оконечными процессами...
 

SergJP

New member
Сообщения
4
#3
to SergJP
Primo, если скрипт называется pg_agent.sh, то у вас неверно указано имя скрипта в ExecStart...
Secundo, почитайте про:
  • очередность запуска (After= и Before=) - если ваш скрипт не просто выдает сообщение о своем старте/останове, а имеет зависимости от других сервисов - это вам точно понадобится;
  • опцию RemainAfterExit=True, которая настоятельно рекомендуется для условно регулируемых сервисов;
  • необходимость и достаточность systemctl enable имя-сервиса && systemctl daemon-reload (reload также при внесении изменений в Unit зачастую требуется) - никаких update-rc и никаких размещений в /etc/init.d (впрочем, поскольку Debian оставил обратную совместимость с SysVInit, так тоже можно, но... сложнее и не нужно)...
Tertio, состояние Type=forking имеет смысл для скрипта, который будет долгое время висеть в памяти отдельным процессом. Для всего остального и утилитарного настоятельно рекомендуется Type=oneshot...
Главное. Можно сделать сервис, запускаемый от лица какого-либо пользователя, через sudo...
[Unit]
Description=Autoloading bla-bla-bla
After=rsyslog.service
[Service]
Type=oneshot
RemainAfterExit=True
ExecStart=/usr/bin/sudo -u user123 /opt/myscript.sh
[Install]
WantedBy=multi-user.target

ЗЫ Знатоки systemd-диалекта могут раскритиковать, но... приведенные выкладки однозначно работают (только что проверил, ага). Да и не люблю я это нестабильное поделие - SysVInit был сложнее в оформлении и логике, зато с куда более гибким управлением оконечными процессами...
если скрипт называется pg_agent.sh, то у вас неверно указано имя скрипта в ExecStart...
В ExecStart указан путь до выполняемого файла, то, что непосредственно должно быть запущено. А шелл-скрипт лежит в init.d
По замыслу программа должна запускаться при загрузке системы и работать постоянно. Поэтому я и поставил forking.
Руками сервис запускается. Проблема в том, то он не запускается автоматически после перезагрузки.

root@astra-meteo:/home/user0/Загрузки# systemctl status pg_agent.service
● pg_agent.service - Lira database frequent tasks service
Loaded: loaded (/etc/systemd/system/pg_agent.service; enabled; vendor preset: enabled)
Active: inactive (dead)
root@astra-meteo:/home/user0/Загрузки#
 

oko

New member
Сообщения
1 246
#4
to SergJP
Писал вам ответ и наконец понял идею. Но, епть, кто ж вас так учил информацию подавать?..
Очевидно, вам нужно при загрузке системы запустить некий pg_agent-сервис в окружении user0, а приведенный bash-скрипт - это вообще левая функция произвольного управления (запуск, останов, проверка статуса) для данного сервиса pg_agent, которая к сути вопроса вообще отношения не имеет (потому что у вас не стартует именно Unit, а не bash-скрипт)?
Если так, то:
  • забудьте про /etc/init.d - для упрощения доступа разместите pg_agent.sh хоть в /usr/bin (либо пропишите для пользователя, который потом будет использовать данный скрипт управления, путь к нему через переменные окружения);
  • исправьте код своего Unit на аналогичный моему (см. спойлер в прошлом сообщении), заменив oneshot на forking, добавив Environment=LD_LIBRARY_PATH=/home/user0/pgagent/lib и указав путь ExecStart=/usr/bin/sudo -u user0 /home/user0/pgagent/pg_agent;
  • выполните systemctl enable pg_agent.service && systemctl daemon-reload.
Если user0 не упрется в какие-либо права доступа и проч., сервис будет стартовать при загрузке системы. Повторюсь, неплохо бы выверить опции After и Before при написании Unit, чтобы ваш pg_agent не запустился раньше времени и зависимостей...

ЗЫ Для полноты проверки напишите короткий bash-скрипт, первой строкой которого будет отправка сообщения в лог (echo "bla-bla-bla" | logger), а второй - /home/user0/pgagent/pg_agent. Укажите его полный путь в ExecStart вашего Unit. Таким образом сможете проверить по syslog, правильно ли отрабатывает Unit...
 

SergJP

New member
Сообщения
4
#5
Спасибо большое за совет! (y) Я действительно забыл про systemctl enable Все заработало, pg_agent грузится при старте. Я действительно плохо описал задачу, приношу извинения.
Еще раз спасибо!