Запустите пока true в сценарии systemd

8

Я получил bash-скрипт, по сути работающий так:

#!/bin/bash

[...]

 while true; do
         str="broadcast "`randArrayElement "messages[@]"`
         server_send_message $str
         sleep $interval
 done

Теперь я хочу запустить это как сервис systemd, мой скрипт сервиса выглядит так:

[Unit]
Description=Announcer
After=network.target

[Service]
ExecStart=/usr/local/bin/somescript &; disown
ExecStop=/usr/bin/kill -9 `cat /tmp/somescript.pid`
Type=forking
PIDFile=/tmp/somescript.pid

[Install]
WantedBy=default.target

К сожалению, когда я запускаю этот сервис через service somescript startнего, он работает, но из-за цикла while true мой терминал зависает при запуске скрипта:

 somescript.service - somescript service
   Loaded: loaded (/etc/systemd/system/somescript.service; disabled; vendor preset: enabled)
   Active: activating (start) since Wed 2016-08-17 12:22:34 CEST; 43s ago
  Control: 17395 (somescript)
   CGroup: /system.slice/somescript.service
           ├─17395 /bin/bash /usr/local/bin/somescript &; disown
           └─17409 sleep 600

Как я могу запустить этот скрипт как сервис, не застревая в цикле «запуск» / while true?

Flatron
источник

Ответы:

8

Вы должны позволить systemd работать на вас. Пусть он справится с разветвлением в начале и уничтожением процесса. Например, заменить вашу сервисную часть на

[Service]
Type=simple
ExecStart=/usr/local/bin/somescript
PIDFile=/tmp/somescript.pid

то вы можете использовать systemctl start, statusи stop. Вы должны помнить, что строки в systemd НЕ интерпретируются оболочкой, поэтому, например, ваш &;просто передается как другой параметр из 2 символов в ваш скрипт.

meuh
источник
Хорошо, спасибо, я сделал изменения. К сожалению, скрипт по-прежнему зависает при попытке запустить его, как и раньше.
Флатрон
1
Вы помните, чтобы сделать sudo systemctl daemon-reload?
meuh
Вы знаете, в эти моменты вы думаете, что уже сделали что-то, хотя не сделали? Спасибо, это работает! :)
Флатрон
1

В зависимости от ваших требований вы можете подумать о замене цикла на конфигурацию системного таймера. Он не запустит службу дважды, даже если server_send_message займет больше времени, чем «OnUnitActiveSec»:

somescript.timer

[Unit]
Description=Announce every minute

[Timer]
OnUnitActiveSec=1m
AccuracySec=10s
Unit=somescript.service

[Install]
WantedBy=default.target

somescript.service Сервисная часть:

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c 'str="broadcast "`randArrayElement "messages[@]"`; server_send_message $str'
Геррит Грибель
источник