我正在使用cron定期运行bash脚本,并尝试使用flock来阻止此脚本以及多次运行它所创build的进程。
crontab中每分钟运行它的条目是:
*/1 * * * * flock -n /tmp/mylockfile /home/user/myscript.sh arg1 arg2
问题是,myscript.sh在分离模式下产生多个屏幕会话,它包含
for i in {1..3}; do screen -d -m ./mysubscript.sh arg3 done
如上所述运行“-d -m”的屏幕以“分离”模式启动屏幕为分叉进程,但这些进程不会inheritanceflock的locking,因此每分钟会显示3个运行mysubscript.sh的新屏幕进程。
如果我使用“-D -m”,那么只有一个屏幕进程一直运行,直到mysubscript.sh完成,而不是三个。
如果没有运行mysubscript.sh的屏幕进程正在运行,我需要的只是运行myscript.sh。
这怎么能实现? 在屏幕或群体中有没有可以帮助实现这一目标的标志?
编辑:如果我改变for循环内的行到运行mysubscript.sh作为后台进程:
./mysubscript.sh arg3 &
locking行为完全是我想要的,除了我没有单独的屏幕了。
根据您确切的需求,您可以连续运行下标循环,也可以为每个循环创建单独的屏幕会话。
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 -ls
和ps aux | grep screen
ps aux | grep screen
,显示您当前正在运行的屏幕和进程。