Скрипт из cron отправляет> 50 писем при ошибках, 1 при успехе

У меня есть проблема, которую я действительно не могу понять.

Следующие фрагменты из моего скрипта Python заархивируют каталог и отправят письмо в случае успеха. Он также отправляет письмо, если произошла ошибка. И вот проблема:

Когда я выполняю скрипт вручную, все работает нормально. 1 письмо в случае успеха, 1 письмо в случае ошибки.

Однако, если сценарий запускается из cron, Я получаю более 50 писем в случае возникновения ошибки (в случае успеха только одно)! Все письма имеют одинаковое содержимое (сообщение об ошибке) и все письма отправляются в одно и то же время (точно как "чч:мм").

Это фрагмент сценария:

def backup(pathMedia, pathZipMedia):
    [...]

    try:
        createArchive(pathMedia, pathZipMedia)
    except Exception as e:
        sendMail('Error in zipping the media dir: ' + str(e))
        sys.exit()

    sendMail('Backup successfully created!')


def sendMail(msg):
    sent = 0
    SMTPserver = '[...]'
    sender =     '[...]'
    destination = ['...']

    USERNAME = '[...]'
    PASSWORD = '[...]'

    text_subtype = 'plain'

    subject='Backup notification'
    content=msg

    try:
        msg = MIMEText(content, text_subtype)
        msg['Subject'] = subject
        msg['From'] = sender

        conn = SMTP(SMTPserver)
        conn.set_debuglevel(False)
        conn.login(USERNAME, PASSWORD)
        try:
            if (sent == 0):
                conn.sendmail(sender, destination, msg.as_string())
                sent = 1
        finally:
            conn.quit()

    except Exception as e:
        sys.exit()

Мой кронтаб выглядит следующим образом:

## run the backup script every 3 days at 4am
* 4 */3 * * /root/backup.py >/dev/null 2>&1

Я исправил ошибки или ошибки сейчас, но это все еще может произойти снова. И мне действительно любопытно, почему возникает эта проблема!

Спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
31
1

Ответы 1

* в начале вашей строки crontab говорит «выполнять это задание каждую минуту».

Предположительно, успешный запуск первого задания в 4:00 приводит к тому, что следующие 59 запусков обнаруживают, что никакой работы выполнять не нужно, поэтому они не пытаются создать резервную копию и спокойно завершают работу, не отправляя сообщения по электронной почте. Но неудачный запуск в 4:00 оставит работу для следующего задания в 4:01, и снова через минуту после этого, и так до 4:59. Все эти задания пытаются создать резервную копию, и все они терпят неудачу, поэтому вы получаете около 60 сообщений об ошибках. (Или меньше, если одному из заданий удается добиться успеха, разрывая цепочку сбоев.)

Чтобы исправить строку crontab для запуска задания только один раз в 4:00, измените первый * на 0.

Я не знаю, почему все ваши сообщения об ошибках имеют одинаковую отметку времени. Вы уверены, что они все одинаковые? Если это так, возможно, они группируются вашей почтовой системой и им присваивается заголовок Date во время обработки пакета. Или, возможно, все задания запускаются cron, а затем все они ждут, блокируются до тех пор, пока не произойдет какой-либо системный тайм-аут или другое событие, а затем все они одновременно испытывают сбой и все отправляют электронные письма в одно и то же время.

Спасибо за ответ! Похоже, это может быть решением. Попробую и подожду, если снова возникнут какие-то ошибки! Не знал, что есть разница между успехом и ошибкой для crontabs...

rflume 20.02.2019 21:47
cron ведет себя по-разному, если задание crontab терпит неудачу, но я предлагаю здесь то, что твой сценарий ведет себя по-разному, если он запускается 10 раз и первый запуск успешен, по сравнению с тем, если он запускается 10 раз и все запуски завершаются неудачно. Если ваш сценарий обнаруживает, что резервное копирование не требуется, поскольку предыдущий запуск сценария завершился успешно несколькими секундами ранее, что он делает? Он просто выходит без отправки электронной почты? Это будет соответствовать поведению, которое вы видите.
ottomeister 20.02.2019 22:33

Скрипт не выполняет никаких проверок, при запуске он заархивирует соответствующий каталог. Тем не менее, я проверил его на сбой при запуске из cron, и теперь, после изменения * на 0, как вы предложили, он также отправляет только одно письмо в случае сбоя, так что был ошибка :)

rflume 22.02.2019 20:41

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