我有一个python脚本,将检查一个队列,并在每个项目上执行一个动作:

# checkqueue.py
while True:
  check_queue()
  do_something()

我如何编写一个bash脚本来检查它是否正在运行,如果没有,就启动它。大致如下伪代码(或者它应该做一些类似ps | grep?):

# keepalivescript.sh
if processidfile exists:
  if processid is running:
     exit, all ok

run checkqueue.py
write processid to processidfile

我将从crontab中调用它:

# crontab
*/5 * * * * /path/to/keepalivescript.sh

当前回答

最简单的方法是使用flock on file。在Python脚本中

lf = open('/tmp/script.lock','w')
if(fcntl.flock(lf, fcntl.LOCK_EX|fcntl.LOCK_NB) != 0): 
   sys.exit('other instance already running')
lf.write('%d\n'%os.getpid())
lf.flush()

在shell中,你可以测试它是否正在运行:

if [ `flock -xn /tmp/script.lock -c 'echo 1'` ]; then 
   echo 'it's not running'
   restart.
else
   echo -n 'it's already running with PID '
   cat /tmp/script.lock
fi

当然你不需要测试,因为如果它已经在运行,你重新启动它,它会以" other instance already running "退出

当进程死亡时,它的所有文件描述符将被关闭,所有锁将被自动移除。

其他回答

看看monit (http://mmonit.com/monit/)。它可以处理脚本的启动、停止和重新启动,并且可以执行健康检查,必要时还可以重新启动。

或者做一个简单的脚本:

while true
do
/your/script
sleep 1
done

最简单的方法是使用flock on file。在Python脚本中

lf = open('/tmp/script.lock','w')
if(fcntl.flock(lf, fcntl.LOCK_EX|fcntl.LOCK_NB) != 0): 
   sys.exit('other instance already running')
lf.write('%d\n'%os.getpid())
lf.flush()

在shell中,你可以测试它是否正在运行:

if [ `flock -xn /tmp/script.lock -c 'echo 1'` ]; then 
   echo 'it's not running'
   restart.
else
   echo -n 'it's already running with PID '
   cat /tmp/script.lock
fi

当然你不需要测试,因为如果它已经在运行,你重新启动它,它会以" other instance already running "退出

当进程死亡时,它的所有文件描述符将被关闭,所有锁将被自动移除。

我不确定它在操作系统之间的可移植性如何,但你可以检查你的系统是否包含'run-one'命令,即。“运行一个人”。 具体来说,这组命令包括“run-one-constant”,这似乎正是所需要的。

从手册页:

run-one-constant命令[ARGS]

注意:显然这可以在脚本中调用,但它也完全消除了拥有脚本的需要。

在线:

while true; do <your-bash-snippet> && break; done

如果失败,它将持续重新启动<your-bash-snippet>: && break将停止循环,如果<your-bash-snippet>优雅地停止(返回代码0)。

在所有情况下重启<your-bash-snippet>:

while true; do <your-bash-snippet>; done

例如# 1

while true; do openconnect x.x.x.x:xxxx && break; done

例如# 2

while true; do docker logs -f container-name; sleep 2; done
watch "yourcommand"

如果/当进程停止(经过2s延迟),它将重新启动进程。

watch -n 0.1 "yourcommand"

在0.1s后重新启动,而不是默认的2秒

watch -e "yourcommand"

如果程序出现错误退出,则停止重新启动。

优点:

内置命令 一行 易于使用和记忆。

缺点:

只在命令执行完成后在屏幕上显示命令的结果