bash cron flock screen

孤街浪徒 提交于 2019-12-17 16:59:47

问题


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.

The entry in crontab to run it every minute is:

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

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

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.

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

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?

EDIT: 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.


回答1:


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

Multiple Screen Method

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

Sessions

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

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.

Single Screen Caller Method

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

Session

59916.screenSession (Detached)

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

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

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

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

$ sh screens.sh

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.



来源:https://stackoverflow.com/questions/36364505/bash-cron-flock-screen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!