bash cron 集群屏幕 [英] bash cron flock screen

查看:24
本文介绍了bash cron 集群屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 cron 定期运行 bash 脚本,并尝试使用 flock以防止多次运行此脚本及其创建的进程.

I am using cron to run a bash script periodically, and trying to use flock to prevent this script and the processes it creates from being run multiple times.

crontab 中每分钟运行一次的条目是:

The entry in crontab to run it every minute is:

*/1 * * * * flock -n /tmp/mylockfile /home/user/myscript.sh arg1 arg2

问题是,myscript.sh 在分离模式下产生多个 screen 会话,它包含

The problem is, myscript.sh spawns multiple screen sessions in detached mode, it contains

for i in {1..3}; 
do 
    screen -d -m ./mysubscript.sh arg3
done

如上使用-d -m"运行屏幕以分离"模式作为分叉进程启动屏幕,但这些进程不会从flock继承锁定,因此每分钟出现3个运行mysubscript.sh的新屏幕进程.

Running screen with "-d -m" as above starts screen in "detached" mode as forked process, but these processes do not inherit the lock from flock, so that every minute 3 new screen processes running mysubscript.sh show up.

如果我使用-D -m",那么在 mysubscript.sh 完成之前只有一个屏幕进程一直运行,而不是三个.

If I use "-D -m" instead then only one screen process runs all the time until mysubscript.sh finishes, not three.

如果没有运行 mysubscript.sh 的屏幕进程正在运行,我需要的是 flock 只运行 myscript.sh.

What I need is flock to only run myscript.sh if none of the the screen processes running mysubscript.sh are running.

如何实现?屏幕或羊群中是否有标志可以帮助实现这一目标?

How can this be achieved? Are there flags in screen or flock that can help to achieve this?

如果我将 for 循环内的行更改为运行 mysubscript.sh 作为后台进程:

If I change the line inside the for loop into running mysubscript.sh as a background process with:

./mysubscript.sh arg3 &

锁定行为与我想要的完全一样,只是我不再有单独的屏幕.

The locking behavior is exactly as I want, except that I do not have the separate screens anymore.

推荐答案

根据您的具体需求,您可以连续运行下标循环,也可以为每个循环创建单独的屏幕会话.

Depending on your exact needs you can either run your subscript loop all consecutively or create individual screen sessions for each.

screens.sh

#!/bin/bash

if ! screen -ls | grep -q "screenSession"
    then
        for i in {1..3};
            do
                screen -S screenSession_${i} -d -m sh mysubscript.sh arg3 &
            done
            { echo "waking up after 3 seconds"; sleep 3; } &
            wait # wait for process to finish
            exit # exit screen
    else echo "Screen Currently Running"
fi

会话

62646.screenSession_1   (Detached)
62647.screenSession_2   (Detached)
62648.screenSession_3   (Detached)

此方法将为循环的每次迭代设置屏幕并执行下标.如果 cron 碰巧在仍然有活动套接字的时候尝试运行脚本,那么它将退出,直到下一个 cron.

This method will setup screens for each of iteration of your loop and execute the subscript. If cron happens to try and run the script while there are still active sockets then it will exit until next cron.

screencaller.sh

#!/bin/bash

if ! screen -ls | grep -q "screenSession"
    then screen -S screenSession -d -m sh screen.sh
    else echo "Screen Currently Running"
fi

screen.sh

#!/bin/bash

for i in {1..3}; 
do 
    sh mysubscript.sh arg3
done

{ echo "waking up after 3 seconds"; sleep 3; } &

wait # wait for process to finish
exit # exit screen

会话

59916.screenSession (Detached)

此方法使用单独的调用程序脚本,然后在同一屏幕会话中一个接一个地循环您的下标.

This method uses a separate caller script then simply loops your subscript one after the other in the same screen session.

然后会像这样执行任一方法(例如,screens.sh 或 screencaller.sh):

Either method would then be executed like so (eg. screens.sh, or screencaller.sh):

*/1 * * * * flock -n /tmp/mylockfile screens.sh arg1 arg2

或者,如果您想从 CLI 手动运行它,只需执行以下操作:

Or if you wanted to run it manually from CLI just do:

$ sh screens.sh

如果您想进入会话,只需调用 screen -r screenSession.其他几个有用的命令是 screen -lsps aux |grep screen 显示您当前正在运行的屏幕和进程.

If you wanted to enter the session you would just call screen -r screenSession. A couple of other useful commands are screen -ls and ps aux | grep screen which shows the screens and processes that you are currently running.

这篇关于bash cron 集群屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆