Я думаю об использовании rsync
резервировать мой ноутбук к моему домашнему серверу через ssh
. Я хочу сделать это ежедневно, таким образом, я планирую использовать crontab
. Мой вопрос: если задание будет пропущено (скажите, что резервное копирование планируется какое-то время, когда ноутбук будет выключен), то это будет выполняться как можно скорее? или это будет просто пропущено?
Так как Вы конкретно попросили его:
Сбой очереди или пропущенные задания резервного копирования, даже если компьютер спит или прочь
То, когда рабочие задания резервного копирования на сервере, было бы относительно легко повторить (очередь), привело задания к сбою, так как мы можем предположить, что сервер будет "стабильным" фактором. Очередь - луг отсутствовал, резервные копии могут быть сделаны путем маршрутизации cronjob к сценарию, создания очереди каждый раз, когда резервное копирование перестало работать.
Когда задания работают на клиенте однако, история немного отличается. Когда мы выполняем задание от cron
, как мы замечаем отказавшее задание? Так как задание не инициировалось, если бы клиентский компьютер спит или выключенный, вещи стали бы намного более сложными для установки от крона.
Поэтому, если бы Вы хотите выполнить запланированное резервное копирование, проверку, что отказавшие или пропущенные задания будут работать на первом случае, я предложил бы не использовать крон вообще.
Решением ниже является относительно простое для установки следующими шагами:
rsync
команда резервного копирования. Использовать grsync
если Вы не уверены в том, как сделать это.Скопируйте сценарий ниже в пустой файл, дайте ему имя (например). из задания резервного копирования, как:
backup1.py
В заголовке сценария установите соответствующие настройки:
#--- enter the working rsync command below
rsync = "rsync -r -t --progress -s '/home/jacob/Bureaublad/test2' '/home/jacob/Bureaublad/test1'"
#--- set backup time interval below in hours/minutes
interval = [0, 10]
#--- set message True if you'd like a warning if a job failed (else False)
message = True
Войдите rsync
команда между двойными кавычками, как в примере.
unique_name.py
Именно. Со времени начала сценария резервные копии будут работать точно за каждым интервалом. Если задание перестало работать, оно ставится в очередь (повторенный однажды в минуту), пока оно не может быть выполнено успешно. После этого новое резервное копирование установлено на точном запланированном (следующем) разе.
Впоследствии, тестовый прогон сценарий с командой:
python3 /path/to/script.py
Если все хорошо работает, добавьте его для Запущения Приложений: Тире> Приложения Запуска> Добавляет. Добавьте команду:
python3 /path/to/script.py
Сценарий
#!/usr/bin/env python3
import subprocess
import time
import os
import datetime
#--- enter the working rsync command below
rsync = "rsync -r -t -s '/home/jacob/Bureaublad/test2' '/home/jacob/Bureaublad/test1'"
#--- set backup time interval below in hours/minutes
interval = [24, 0]
#--- set message True if you'd like a warning if a job failed (else False)
message = True
#--- set the max- size of the logfile below (n- lines)
maxlog = 100
#--- don't change anything below
backup_id = os.path.basename(__file__).split(".")[0]
home = os.environ["HOME"]
datefile = home+"/next_backup_"+backup_id; logfile = home+"/backup_log_"+backup_id
print(datefile, logfile)
interval = (interval[0]*3600)+(interval[1]*60)
failed = False
def failed_message():
# shows a zenity message if a backup failed
subprocess.Popen([
"zenity",
"--info",
"--text="+backup_id+" failed\n"+\
"See "+logfile])
def readable_t(sec):
# converts epoch time to readable date & time
return datetime.datetime.fromtimestamp(sec).strftime('%Y-%m-%d %H:%M:%S')
def currtime():
# returns current (epoch) time
return int(time.strftime("%s"))
def sync(failed):
# performs the rsync command, on errors: writes to log and shows message
try:
subprocess.check_call(["/bin/bash", "-c", rsync])
set_next(planned, interval, currt)
return False
except subprocess.CalledProcessError:
if failed == False:
open(logfile, "+a").write(readable_t(planned)+" failed\n")
if message == True:
failed_message()
return True
def next_run():
# reads current queue file, creates it if it doesn't exist
try:
return int(open(datefile).read())
except FileNotFoundError:
currt = currtime()
open(datefile, "wt").write(str(currt))
return currt
def set_next(lastr, interval, currt):
# creates the next queue, maintains the log file
nextrun = lastr
while nextrun <= currt:
nextrun += interval
open(datefile, "wt").write(str(nextrun))
newline = [readable_t(lastr)+" succesfully finished on "+\
readable_t(currtime())+"\n"]
try:
limited_lines = open(logfile).readlines()[-maxlog+1:]+newline
except FileNotFoundError:
limited_lines = newline
with open(logfile, "wt") as log:
for l in limited_lines:
print("4")
log.write(l)
while True:
time.sleep(60)
planned = next_run(); currt = currtime()
if currt > planned:
failed = sync(failed)
Сценарий сохраняет файл журнала, названный в честь backupscript.
Максимальный номер строк, для хранения в файле журнала, может быть определен в заголовке сценария:
#--- set the max- size of the logfile below (n- lines)
maxlog = 50
Пример
В примере ниже, сценарий установлен копировать каждые пять минут, начав с 11:10.
Затем задание, запланированное в 11:35, перестало работать, вследствие того, что сервер не доступен. Если Вы устанавливаете message = True
:
Задание ставится в очередь и успешно работает позже в 11:41:44
и так далее
Просто удалите файл очереди в своем корневом каталоге соответствующего задания резервного копирования (запускающийся с next_backup_
) текущее время будет быть новым временем начала цикла.
[24, 0]
, следующее резервное копирование будет всегда ставиться в очередь в 12:00
из следующего дня.Сценарий спит большую часть времени. В противном случае это только изучает файл очереди однажды в минуту. Начиная со средств ничто к Вашей системе очень хорошо возможно выполнить несколько заданий резервного копирования, каждого с их собственным журналом и файлом очереди, одновременно. И начиная с называют журнал - и начиная с файл очереди после названия сценария все Вы имеете к к, должен дать каждый из сценариев уникальное имя