如何为 shell 脚本创建服务,以便我可以像守护进程一样启动和停止它?

cod*_*mer 38 cron centos shell-script services sysvinit

我正在使用 CentOS 7,我的目标是每五秒创建一个 cron,但正如我研究的那样,我们只能使用 cron 一分钟,所以我现在正在做的是我创建了一个 shell 文件。
命中.sh

while sleep 5; do curl http://localhost/test.php; done
Run Code Online (Sandbox Code Playgroud)

但我通过右键单击它手动点击了它。

我想要的是为该文件创建一个服务,以便我可以自动启动和停止它。

我找到了创建服务脚本

#!/bin/bash
# chkconfig: 2345 20 80
# description: Description comes here....

# Source function library.
. /etc/init.d/functions

start() {
    # code to start app comes here 
    # example: daemon program_name &
}

stop() {
    # code to stop app comes here 
    # example: killproc program_name
}

case "$1" in 
    start)
       start
       ;;
    stop)
       stop
       ;;
    restart)
       stop
       start
       ;;
    status)
       # code to check status of app comes here 
       # example: status program_name
       ;;
    *)
       echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 
Run Code Online (Sandbox Code Playgroud)

但是我不知道在 start 或 stop 方法中写什么我尝试将 hit.sh 的相同内容放入start(){}但它}在 stop 方法中出错。

Dmi*_*yev 45

如果您想重用您的代码示例,它可能如下所示:

#!/bin/bash

case "$1" in 
start)
   /path/to/hit.sh &
   echo $!>/var/run/hit.pid
   ;;
stop)
   kill `cat /var/run/hit.pid`
   rm /var/run/hit.pid
   ;;
restart)
   $0 stop
   $0 start
   ;;
status)
   if [ -e /var/run/hit.pid ]; then
      echo hit.sh is running, pid=`cat /var/run/hit.pid`
   else
      echo hit.sh is NOT running
      exit 1
   fi
   ;;
*)
   echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 
Run Code Online (Sandbox Code Playgroud)

自然,你想作为服务执行的脚本应该去 eg /usr/local/bin/hit.sh,上面的代码应该去/etc/init.d/hitservice

对于需要运行此服务的每个运行级别,您需要创建相应的符号链接。例如,一个名为的符号链接/etc/init.d/rc5.d/S99hitservice将启动运行级别 5 的服务。当然,您仍然可以通过service hitservice start/手动启动和停止它service hitservice stop


Ale*_*der 33

我相信 CentOS 7 及更高版本使用 systemd。如果您的系统是这种情况,请尝试以下操作:

  1. 将要运行的脚本命令放在/usr/bin/myscript.

  2. 请记住使用chmod +x.

  3. 创建以下文件:

/etc/systemd/system/my.service

[Unit]
Description=My Script

[Service]
Type=forking
ExecStart=/usr/bin/myscript

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
  1. 重新加载所有 systemd 服务文件: systemctl daemon-reload

  2. 通过使用 启动服务来检查它是否正常工作systemctl start my

奖金:

为了测试 systemd 服务,可以启动带有两个窗口窗格的 tmux 环境,其中顶部窗口监视脚本(stdoutstderr)的输出,底部窗口可用于重新启动服务。这需要tmux安装,然后简单地:

tmux new-session \; select-layout even-horizontal \; split-window -v journalctl -o cat --since=@$(date +%s) -f -u my \; rotate-window \; set -g status-bg colour0 \; set -g status-fg colour9 \; attach
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令重新启动服务:

systemctl restart my
Run Code Online (Sandbox Code Playgroud)

退出tmuxctrl-dctrl-c

一旦您对脚本和服务文件感到满意,请更改

Type=forking
Run Code Online (Sandbox Code Playgroud)

进入

Type=simple
Run Code Online (Sandbox Code Playgroud)

完毕。

  • 现在我喜欢 systemd! (4认同)
  • 我不推荐`Type=forking`。提问者可能需要 `Type=simple`,但一般不推荐分叉:http://0pointer.de/public/systemd-man/daemon.html#Writing%20Systemd%20Unit%20Files。人们一直在使用他们旧的 init 脚本并将它们包装在 `systemd` 中,以便他们的服务启动进入 `systemd(init-script(service))`。然而,`systemd` 是 init 脚本的替代品,所以你应该直接使用 `systemd` 调用该服务,使其看起来像 `systemd(service)`。 (4认同)

小智 5

这是我的脚本即服务:

[Unit]
Description=To change In test buffer
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/test.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)