将 shell 脚本置于 systemd 控制之下

Cal*_*eng 6 bash arch-linux init.d systemd

假设我有一个这样的 shell 脚本:-

#!/bin/sh
# cherrypy_server.sh

PROCESSES=10
THREADS=1 # threads per process
BASE_PORT=3035 # the first port used
# you need to make the PIDFILE dir and insure it has the right permissions
PIDFILE="/var/run/cherrypy/myproject.pid"
WORKDIR=`dirname "$0"`
cd "$WORKDIR"

cp_start_proc()
{
 N=$1
 P=$(( $BASE_PORT + $N - 1 ))
 ./manage.py runcpserver daemonize=1 port=$P pidfile="$PIDFILE-$N" threads=$THREADS request_queue_size=0 verbose=0
}

cp_start()
{
 for N in `seq 1 $PROCESSES`; do
  cp_start_proc $N
 done
}

cp_stop_proc()
{
 N=$1
 #[ -f "$PIDFILE-$N" ] && kill `cat "$PIDFILE-$N"`
 [ -f "$PIDFILE-$N" ] && ./manage.py runcpserver pidfile="$PIDFILE-$N" stop
 rm -f "$PIDFILE-$N"
}

cp_stop()
{
 for N in `seq 1 $PROCESSES`; do
  cp_stop_proc $N
 done
}

cp_restart_proc()
{
 N=$1
 cp_stop_proc $N
 #sleep 1
 cp_start_proc $N
}

cp_restart()
{
 for N in `seq 1 $PROCESSES`; do
  cp_restart_proc $N
 done
}

case "$1" in
 "start")
  cp_start
 ;;
 "stop")
  cp_stop
 ;;
 "restart")
  cp_restart
 ;;
 *)
  "$@"
 ;;
esac
Run Code Online (Sandbox Code Playgroud)

从 bash 脚本中,我们基本上可以做 3 件事:

  1. 通过调用启动cherrypy服务器 ./cherrypy_server.sh start
  2. 通过调用停止cherrypy服务器 ./cherrypy_server.sh stop
  3. 通过调用重新启动cherrypy服务器 ./cherrypy_server.sh restart

我如何将这个 shell 脚本systemd作为一个cherrypy.service文件置于的控制之下(明显的目标是在机器重新启动时让 systemd 启动cherrypy 服务器)?

systemd此处参考服务文件示例 - https://wiki.archlinux.org/index.php/Systemd#Using_service_file

cor*_*ump 6

我将它们用于 Sick Beard 和 SabNZBd,这两个 python/cherrypy 应用程序。不同之处在于知道何时使用“分叉”。这基本上告诉 systemd 主二进制文件将派生东西,因此它必须从文件中猜测 PID。 WantedBy只是定义需要它启动的目标,将其视为运行级别。您还会注意到,第二个定义使用一个目录来保存运行信息,这是因为它$process-$port为每个启动的守护进程创建了一个目录(您可能在不同的端口上有许多由主进程生成的守护进程)。

IMO,您可以在 ExecStart 上添加脚本并确保它是forking并添加一种方法来查找主 PIDfile,或者至少是一个 PIDfile,这意味着“如果它已死,请重新启动服务”。

也许理想的做法是为每个守护进程创建 1 个“简单”的服务文件?

[Unit]
Description=Internet PVR for your TV Shows
After=cryptsetup.target

[Service]
ExecStart=/usr/bin/python2 /path/to/Sick-Beard/SickBeard.py
Type=simple
User=<user under which to run>
Group=<group of said user>

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

这个是分叉的

[Unit]
Description=Binary Newsreader
After=cryptsetup.target

[Service]
ExecStart=/usr/bin/python2 /path/to/sabnzbd/SABnzbd.py -d -f /path/to/inifile --pid /run/sabnzbd
Type=forking
PIDFile=/run/sabnzbd/sabnzbd-8080.pid
User=<user to run the process>
Group=<group of said user>

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)