在 systemd 脚本中为 true 时运行

在 systemd 脚本中为 true 时运行

我有一个 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 循环?

答案1

您需要让 systemd 为您工作。让它处理启动时的分叉和进程的终止。例如,将您的维修部件更换为

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

那么你可以使用systemctl start,statusstop。您必须记住 systemd 中的行是不是由 shell 解释,因此例如您&;只是作为另一个 2 个字符的参数传递给您的脚本。

答案2

根据您的要求,您可能会考虑用 systemd 计时器配置替换循环。即使 server_send_message 花费的时间比“OnUnitActiveSec”长,它也不会启动服务两次:

一些脚本.定时器

[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'

相关内容