有没有办法告诉我cron运行某个应用程序,但如果已经存在某个进程,则不要运行它?
有没有办法告诉我cron运行某个应用程序,但如果已经存在某个进程,则不要运行它?
Answers:
最简单的方法,使用pgrep
在crontab中:
* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1
export DISPLAY=:0
以防止Could not connect to display
发生错误。* * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
运行脚本,而不是直接运行程序。有很多可能性。例如 :
MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
$RESTART
fi
pgrep myprog; if [ $? -ne 0 ]; then ...
最好写成if ! pgrep myprog; then ...
$?
例如,通过在行之间添加日志消息或错误处理,很容易无意间破坏的值。
如果先前的实例尚未完成,则此脚本将不会再次运行。如果您不想在运行其他特定进程的情况下不运行某些程序,请参阅harrymc的脚本。
DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;
if flock -n -x 8; then
echo ""
echo "Starting your script..."
echo ""
[PUT YOUR STUFF HERE]
echo ""
echo "Script started $DATE";
echo "Script finished `date +%c`";
else
echo "Script NOT started - previous one still running at $DATE";
fi
*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
通常由程序本身而不是由处理cron
。为此,有两种标准技术:
1)grep
的输出ps
以查看是否已经有该名称的进程正在运行
2)在启动时,首先检查pid(进程ID)文件的存在(通常在/var/run/program_name.pid
),如果存在,则从文件中读取pid,并检查该进程是否仍然存在;如果是这样,请拒绝启动。如果pid文件不存在或文件中的pid已消失,则创建一个pid文件,将您的进程ID写入其中,然后继续正常启动。
虽然在技术上可以将可以直接执行这两个操作的bash管道写入到crontab中,但最好将它们添加到正在启动的程序中(以便无论如何启动它们都可以应用)或编写包装脚本来如harrymc建议的那样处理此问题。
* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1
我将上述答案重新用于模式匹配。没有f选项的pgrep与进程模式不匹配。但是使用f选项存在问题。使用f选项,生成cron的外壳程序总是匹配并返回其pid,因此该进程永远不会重新启动。
在其中一个字母模式附近添加[]只会匹配该进程,并且不会返回cron shell的pid。
文件:https://www.timkay.com/solo/
solo是一个非常简单的脚本(10行),可防止程序一次运行多个副本。使用cron来确保作业在上一个作业完成之前不会运行是很有用的。
例
* * * * * solo -port=3801 ./job.pl blah blah