bash cron 集群屏幕

Posted

技术标签:

【中文标题】bash cron 集群屏幕【英文标题】:bash cron flock screen 【发布时间】:2016-07-21 17:49:43 【问题描述】:

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

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

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

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

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

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

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

如果运行 mysubscript.sh 的屏幕进程都没有运行,我需要的是群起只运行 myscript.sh。

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

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

./mysubscript.sh arg3 &

锁定行为正是我想要的,只是我不再有单独的屏幕。

【问题讨论】:

你需要每个下标循环使用一个单独的屏幕,还是它们都可以在同一个屏幕上运行? 理想情况下,它们每个都在一个单独的屏幕上,但都在同一个屏幕上总比没有好。 两者都做很简单,我会在一分钟内为你发布答案:) 【参考方案1】:

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

多屏法

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。

单屏调用方法

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)

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

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

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

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

$ sh screens.sh

如果您想进入会话,您只需致电screen -r screenSession。其他一些有用的命令是 screen -lsps aux | grep screen,它们显示了您当前正在运行的屏幕和进程。

【讨论】:

如果有一些屏幕已经从另一个程序运行,这不会阻止screens.sh运行吗?

以上是关于bash cron 集群屏幕的主要内容,如果未能解决你的问题,请参考以下文章

Docker 并行运行 cron 作业

bash脚本:集群资源争夺战crazy-killer

如何使用 AWS Redshift 执行 Bash 脚本

使用docker搭建flink集群

在 Google Cloud DataProc 上安排 cron 作业

Cron 从每个系统的多个 crontab 文件中读取