Выполните сценарий удара буквально после каждых 3 дней

Я хочу выполнить сценарий оболочки буквально после каждых 3 дней. Используя crontab с 01 00 */3 * *на самом деле не выполнит условие, потому что оно работало бы 31-й и с другой стороны в 1-й день месяца. */3 синтаксис совпадает с высказыванием 1,4,7... 25,28,31.

Должны быть способы заставить сам сценарий проверить условия и выход, если 3 дня не передали. Таким образом, crontab каждый день выполняет сценарий, но сам сценарий проверил бы, передали ли 3 дня.

Я даже нашел некоторый код, но он дал мне синтаксическую ошибку, любая справка будет цениться.

if (! (date("z") % 3)) {
     exit;
}

main.sh: line 1: syntax error near unexpected token `"z"'
main.sh: line 1: `if (! (date("z") % 3)) {'
8
задан 25 September 2016 в 06:48

5 ответов

Чтобы сразу прервать и выйти из сценария, если последнее выполнение еще не было, по крайней мере, определенное время назад, Вы могли бы использовать этот метод, который требует внешнего файла, который хранит последнюю дату и время выполнения.

Добавьте эти строки к верхней части Вашего сценария Bash:

#!/bin/bash

# File that stores the last execution date in plain text:
datefile=/path/to/your/datefile

# Minimum delay between two script executions, in seconds. 
seconds=$((60*60*24*3))

# Test if datefile exists and compare the difference between the stored date 
# and now with the given minimum delay in seconds. 
# Exit with error code 1 if the minimum delay is not exceeded yet.
if test -f "$datefile" ; then
    if test "$(($(date "+%s")-$(date -f "$datefile" "+%s")))" -lt "$seconds" ; then
        echo "This script may not yet be started again."
        exit 1
    fi
fi

# Store the current date and time in datefile
date -R > "$datefile"

# Insert your normal script here:

Не забывайте устанавливать значимое значение как datefile= и адаптируйте значение seconds= к Вашим потребностям ($((60*60*24*3)) оценивает к 3 дням).


Если Вы не хотите отдельный файл, Вы могли бы также сохранить прошлое время выполнения в штампе времени изменения Вашего сценария. Это означает однако, что внесение любых изменений в Ваш файл сценария сбросит эти 3 счетчика и рассматриваться как то, если сценарий успешно работал.

Для реализации этого добавьте отрывок ниже к вершине файла сценария:

#!/bin/bash

# Minimum delay between two script executions, in seconds. 
seconds=$((60*60*24*3))

# Compare the difference between this script's modification time stamp 
# and the current date with the given minimum delay in seconds. 
# Exit with error code 1 if the minimum delay is not exceeded yet.
if test "$(($(date "+%s")-$(date -r "$0" "+%s")))" -lt "$seconds" ; then
    echo "This script may not yet be started again."
    exit 1
fi

# Store the current date as modification time stamp of this script file
touch -m -- "$0"

# Insert your normal script here:

Снова, не забывайте адаптировать значение seconds= к Вашим потребностям ($((60*60*24*3)) оценивает к 3 дням).

12
ответ дан 23 November 2019 в 05:21

Во-первых, приведенный выше фрагмент кода имеет недопустимый синтаксис Bash, выглядит как Perl. Во-вторых, параметр z для date заставляет его выводить числовой часовой пояс. +%j номер дня. Вам нужно:

if [[ ! $(( $(date +%j) % 3 )) ]] ;then
     exit
fi

Но вы все равно увидите странность в конце года:

$ for i in 364 365  1 ; do echo "Day $i, $(( $i % 3 ))"; done
Day 364, 1
Day 365, 2
Day 1, 1

Возможно, вам повезет больше с ведением счета в файле и тестированием / обновить это.

3
ответ дан 23 November 2019 в 05:21

Если можно просто оставить сценарий, работающий постоянно, Вы могли бы сделать:

while true; do

[inert code here]

sleep 259200
done

Этот цикл всегда верен, таким образом, он будет всегда выполнять код, затем ожидать в течение трех дней прежде, чем запустить цикл снова.

2
ответ дан 23 November 2019 в 05:21

Вы можете использовать анакрон вместо cron, он предназначен именно для того, чтобы делать то, что вам нужно. С man-страницы:

Anacron может использоваться для периодического выполнения команд с частотой, указанной в днях. В отличие от cron (8), он не предполагает, что машина работает непрерывно. Следовательно, его можно использовать на машинах, которые не работают 24 часа в сутки, для контроля ежедневных, еженедельных и ежемесячных заданий, которые обычно контролируются cron.

При выполнении Anacron считывает список заданий из файла конфигурации, обычно это / etc / anacrontab (см. Anacrontab (5)). Этот файл содержит список заданий, которые контролирует Anacron. Каждая запись задания указывает период в днях, задержку в минутах, уникальный идентификатор задания и команду оболочки.

Для каждого задания Anacron проверяет, было ли это задание выполнено за последние n дней, где n - период, указанный для этого задания. Если нет, Anacron запускает команду оболочки задания, ожидая количества минут, указанных в качестве параметра задержки.

После выхода из команды Anacron записывает дату в специальный файл метки времени для этого задания, чтобы он мог знать, когда его выполнить снова. Только дата используется для расчета времени. Час не используется.

2
ответ дан 23 November 2019 в 05:21

Крон действительно является неправильным инструментом для этого. Существует на самом деле наиболее часто используемый и underloved инструмент, в который заходят, который мог бы работать. at's, главным образом разработанный для интерактивного использования и я уверен, что кто-то нашел бы лучший способ сделать это.

В моем случае у меня был бы скрипт, который я запускаю перечисленный в testjobs.txt и включаю строку, которая читает.

Как пример, у меня было бы это как testjobs.txt

echo "cat" >> foo.txt
date >> foo.txt
at now + 3 days < testjobs.txt

У меня есть две невинных команды, которые могли бы быть Вашими сценариями оболочки. Я выполняю эхо, чтобы удостовериться, что у меня есть детерминированный вывод и дата для подтверждения выполнений команды по мере необходимости. Когда при выполнениях эта команда, это закончится путем добавления нового задания к в в течение 3 дней. (Я протестировал с одной минутой - который работает),

Я вполне уверен, я буду вызван для способа, в котором я злоупотребил, но это - удобный инструмент для планирования команды, которая будет выполнена за один раз или x дни после предыдущей команды.

12
ответ дан 23 November 2019 в 05:21

Другие вопросы по тегам:

Похожие вопросы: