安排命令运行的最佳方法是什么,以确保先前的一组命令已经完成?

安排命令运行的最佳方法是什么,以确保先前的一组命令已经完成?

也就是说,我需要轮换备份文件夹。我安排多台机器通过 rsync 同步到一台备份机器。虽然我安排备份在深夜开始,并安排文件夹轮换(使文件夹 day0 变成 day1,从最旧的开始)在第二天的深夜(例如,提供 10 小时让备份完成),但我希望能够确保所有备份都已完成,然后再允许轮换开始,而不是做出假设(因为,如果我在备份过程中轮换文件夹,我的备份就不准确)。

对于单台机器来说,这可能很简单,但对于多台机器来说,我希望有人知道最好的方法...我能想到一些,但不想在正在运行的系统上进行“实验”:

让每个备份创建一个完成戳记,并在一定时间后每隔几分钟运行一次轮换脚本,检查它是否已成功运行以及所有戳记是否都是最新的(比上一个轮换脚本戳记更旧)?

是否让每个备份 mv 其先前的 rsync 到正在进行的文件夹,rsync,然后 mv 返回 day0,以便如果备份未完成则轮换会跳过该备份?

只能忍受可能不准确的备份吗?

答案1

我可能会向中央服务器写入一个包含日期和主机名的完成文件;您可以使用这个:

#!/bin/bash
# when each backup completes, write a completion file:
ssh user@central-server "touch /path/to/completion-files/$HOST-$(date +%F).complete"

在中央服务器上:

#!/bin/bash
# on the central server, run this before attempting folder rotation
for h in (list of hosts); do
  if [[ -e "/path/to/completion-files/$h-$(date +%F)" ]]; 
    then # do your thing
  fi
done

答案2

为了解决更普遍的情况,即“安排命令运行的最佳方法是什么,以确保先前的一组命令已经完成?

您需要运行一个命令,并测试成功(退出代码),然后您可以使用系统调度程序来调度该命令(通常)例如:

 #!/bin/bash
 rsync "${opts[@]}" "$source" "$dest"
 if [[ $? -eq 0 ]]; then
   at now+10hours <<<"~jdoe/bin/rotatefolders.sh"
 fi

我在这里假设你的文件夹轮换脚本被命名为旋转文件夹垃圾桶在 jdoe 的主文件夹中。

答案3

由于您使用的是 rsync,我假设您是通过 ssh 隧道执行此操作的。如果是这样,您也已安装 ssh。

当 rsync 作业完成时,最好使用信号发送,而不是忙等待循环。

“信号”可以触发 backup.server 系统上的日志轮转 - 可以通过直接启动 logrotate,也可以通过间接启动(通过 sudo 或 ssh-key)。

答案4

您可以使用 pid 文件:

PID_FILE="/path/to/pid.pid"   
    if [ -f $PID_FILE ]
    then
            OLD_PID=`cat $PID_FILE`
            RUNNING=`ps aux |grep $OLD_PID|grep -v grep|wc -l`
            if [ $RUNNING -gt 0 ]
            then
                    echo "WARNING PROGRAM already running"
                    exit 0
            else
                    echo "PID file exists but program is not running. Overriding PID file"
            fi
    fi
    echo $$ > $PID_FILE
    trap "rm -f $PID_FILE; exit" INT TERM EXIT

共享 pid 文件,您将确保 B 在 A 完成之前不会运行,反之亦然。

相关内容