我正在使用 cron 定期运行 bash 脚本,并尝试使用 flock以防止此脚本及其创建的进程被多次运行。
crontab 中每分钟运行一次的条目是:
*/1 * * * * flock -n /tmp/mylockfile /home/user/myscript.sh arg1 arg2
问题是,myscript.sh 生成多个 screen分离模式下的 session ,它包含
for i in {1..3};
do
screen -d -m ./mysubscript.sh arg3
done
如上使用“-d -m”运行 screen 以“分离”模式作为 fork 进程启动 screen ,但这些进程不会从 flock 继承锁,因此每分钟有 3 个运行 mysubscript.sh 的新 screen 进程出现.
如果我改用“-D -m”,那么在 mysubscript.sh 完成之前只有一个 screen 进程一直运行,而不是三个。
如果运行 mysubscript.sh 的 screen 进程都没有运行,我需要的是 flock 仅运行 myscript.sh。
如何实现? screen 或 flock 中是否有标志可以帮助实现这一目标?
编辑:如果我将 for 循环内的行更改为将 mysubscript.sh 作为后台进程运行:
./mysubscript.sh arg3 &
锁定行为完全符合我的要求,除了我不再有单独的 screen 。
最佳答案
根据您的具体需要,您可以连续运行下标循环,也可以为每个循环创建单独的 screen session 。
多屏方式
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
session
62646.screenSession_1 (Detached)
62647.screenSession_2 (Detached)
62648.screenSession_3 (Detached)
此方法将为循环的每次迭代设置 screen 并执行下标。如果 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
session
59916.screenSession (Detached)
此方法使用一个单独的调用程序脚本,然后在同一 screen session 中一个接一个地循环您的下标。
然后将像这样执行任一方法(例如 screens.sh 或 screencaller.sh):
*/1 * * * * flock -n /tmp/mylockfile screens.sh arg1 arg2
或者,如果您想从 CLI 手动运行它,只需执行以下操作:
$ sh screens.sh
如果您想进入 session ,只需调用 screen -r screenSession
。其他一些有用的命令是 screen -ls
和 ps aux | grep screen
显示您当前正在运行的 screen 和进程。
关于linux - bash cron 羊群 screen ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36364505/