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

时间:2015-11-29 18:42:05

标签: linux bash shell docker nohup

关注此问题: 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,因此打破了直到循环并彻底退出。

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

1 个答案:

答案 0 :(得分:1)

不要编写shell脚本。使用systemdsupervisordocker或任何可用的服务管理器直接管理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下的进程。

如果要在已经运行的容器中运行和管理python进程,可能更容易运行supervisord作为主容器进程并让它管理python test.pySupervisor不像systemd那样功能齐全,但它可以执行所有基本的服务管理任务。