Jalankan sementara true dalam skrip systemd

8

Saya mendapat skrip bash pada dasarnya menjalankan ini:

#!/bin/bash

[...]

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

Sekarang saya ingin menjalankan ini sebagai layanan systemd, skrip layanan saya terlihat seperti ini:

[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

Sayangnya ketika saya menjalankan layanan ini melalui service somescript startitu berfungsi tetapi karena sementara true loop terminal saya macet dalam memulai skrip:

 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

Bagaimana saya bisa menjalankan skrip ini sebagai layanan tanpa terjebak dalam "mulai" / while true loop?

Flatron
sumber

Jawaban:

8

Anda perlu membiarkan systemd bekerja untuk Anda. Biarkan itu menangani percabangan di awal dan membunuh proses. Misalnya ganti bagian layanan Anda dengan

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

maka Anda bisa menggunakan systemctl start, statusdan stop. Anda harus ingat bahwa baris-baris dalam systemd TIDAK ditafsirkan oleh shell, jadi misalnya Anda &;hanya dilewatkan sebagai parameter lain dari 2 karakter ke skrip Anda.

meuh
sumber
Oke terima kasih, saya melakukan perubahan. Sayangnya skripnya masih hang ketika mencoba memulainya seperti sebelumnya.
Flatron
1
Apakah Anda ingat melakukannya sudo systemctl daemon-reload?
meuh
Anda tahu saat-saat ini Anda pikir Anda sudah melakukan sesuatu padahal tidak? Terima kasih itu berhasil! :)
Flatron
1

Tergantung pada kebutuhan Anda, Anda mungkin mempertimbangkan untuk mengganti loop Anda dengan konfigurasi pengatur waktu systemd. Itu tidak akan memulai layanan dua kali bahkan jika server_send_message membutuhkan waktu lebih lama dari "OnUnitActiveSec":

somescript.timer

[Unit]
Description=Announce every minute

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

[Install]
WantedBy=default.target

somescript.service Bagian layanan:

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c 'str="broadcast "`randArrayElement "messages[@]"`; server_send_message $str'
Gerrit Griebel
sumber