bash 脚本如何在向子进程发送信号时在非 0 退出时重新启动进程

How can a bash script restart a process on non-0 exit while sending signals to child

关注这个问题: How do I write a bash script to restart a process if it dies?

我正在尝试制作一个 bash 脚本,它只是 运行 一个 python 脚本,如果脚本以非 0 输出结束则重新启动脚本。我的 bash 脚本类似于:

#!/bin/bash

trap 'kill $(jobs -p)' SIGTERM SIGKILL; 
until python test.py & wait; do 
  echo "Test Critically Crashed" >&2
  sleep 1; 
done

虽然我的 python 脚本(虽然不是很相关)看起来像:

import logging,sys,signal,time

def signal_term_handler(signal, frame):
  print("SIGTERM recieved...quitting")
  sys.exit(0)

signal.signal(signal.SIGTERM, signal_term_handler)
while True:
  time.sleep(1)
  sys.exit(1)

我想 运行 bash 脚本并无限地 运行 我的进程,直到我将 sigterm 或 sigkill 发送到它所在的 bash 脚本会将其发送到子进程 (python test.py) 并最终以代码 0 退出,从而打破 until 循环并干净地退出。

仅供参考,我正在使用无限 运行ning python 脚本,并将此 bash 脚本用作 docker 容器的入口点。

不要编写 shell 脚本。使用 systemd, supervisor, docker 或任何可用的服务管理器直接管理 docker/script 进程。这是服务经理生来要做的工作,他们为此而生。

systemd 服务会 运行 docker run {image} python test.py 并且您需要无限期地将其设置为 运行。

systemd 配置如下所示:

[Unit]
Description=My Super Script
Requires=docker.service
After=docker.service

[Service]
ExecStart=/bin/docker run --name={container} --rm=true {image} python test.py
ExecStop=/bin/docker stop --time=10 {container}
TimeoutStopSec=11
KillMode=control-group

Restart=on-failure
RestartSec=5
TimeoutStartSec=5

[Install]
WantedBy=multi-user.target

Restart=on-failure 设置符合您的要求,即仅在返回非 0 退出代码时才重新启动进程,因此您仍然可以在需要时终止 systemd 下的进程。

如果您想 运行 并在已经 运行ning 的容器中管理您的 python 进程,运行 supervisord 可能更容易,因为主容器进程并让它管理 python test.pySupervisor is not as feature complete as systemd 但它可以完成所有基本的服务管理任务。