Docker Exec не работает в Cron

У меня есть довольно простая команда, которая отлично работает в автономном режиме как команда или сценарий bash, но не тогда, когда я помещаю ее в crontab

40 05 * * * bash /root/scripts/direct.sh >> /root/cron.log

который имеет следующую строку

PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
SHELL=/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root/
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/

Я пытался изменить URL скрипта на /usr/bin/scirpts/ неудачно

Я даже пытался запустить скрипт прямо в cron

26 08 * * * docker exec -it mongodb mongodump -d meteor -o /dump/ >> /root/cron.log

без удачи, любая помощь приветствуется.

РЕДАКТИРОВАТЬ

Я не вижу ошибок в /root/cron.log либо файл

6 ответов

Решение

Ваш docker exec Команда говорит, что ей нужен "псевдотерминал и он работает в интерактивном режиме" ( -it flags), в то время как cron не подключается ни к одному TTY.

Попробуйте изменить команду docker exec на это и посмотреть, работает ли это?

docker exec mongodb mongodump -d meteor -o /dump/

Для чего бы это ни стоило у меня была точно такая же проблема. Исправление вашего PATH, изменение разрешений и проверка того, что вы работаете в качестве соответствующего пользователя докера, - все это хорошо, но этого недостаточно. Он будет продолжать сбой, потому что вы используете "docker exec -it", который указывает докеру использовать интерактивную оболочку. Измените его на "docker exec -t", и он будет работать нормально. Однако нигде не будет выводиться лог, сообщающий вам об этом. Наслаждайтесь!

отладка cron

1. /var/log или же sendmail

Как crond работать как демон, без возможности сбоя, выполнение более важно, чем ведение журнала. Тогда по умолчанию, если что-то пойдет не так, cron отправит письмо на $USER@localhost отчет о выходе скрипта и ошибках.

Посмотри на /var/mail или же /var/spool/mail для некоторых писем, возможно

и в /etc/aliases чтобы увидеть, куда отправляются сообщения root.

2. Кронд и $PATH

Когда вы запускаете команду cron, будьте осторожны, $PATH это путь пользователя по умолчанию, а не корневой путь по умолчанию (т.е. нет */sbin и другие зарезервированные пути к инструментам суперпользователя).

Для этого проще всего распечатать путь по умолчанию в среде, где все работает нормально:

echo $PATH

или исправьте ваш скрипт из командной строки:

sed -e "2aPATH='$PATH'" -i /root/scripts/direct.sh

Это добавит текущий $PATH инициализатор в строке 2 в вашем скрипте.

Или это, выкинет из вашего скрипта все остальные PATH=:

sed -e "s/PATH=[^ ]*\( \|$\)/\1/;2aPATH='$PATH'" -i /root/scripts/direct.sh

3. Принудительная регистрация

Добавьте вверху вашего скрипта:

exec 1>/tmp/cronlog-$$.log
exec 2>/tmp/cronlog-$$.err

Попробуй это:

sed -e '1a\\nexec 1>/tmp/cronlog-$$.log\nexec 2>/tmp/cronlog-$$.err' -i ~/scripts/direct.sh

Доработанный скрипт может выглядеть так:

#!/bin/bash

# uncomment two following lines to force log to /tmp
# exec 1>/tmp/cronlog-$$.log
# exec 2>/tmp/cronlog-$$.err

PATH='....' # copied from terminal console!

docker exec -it mongodb mongodump -d meteor -o /dump/

Исполняемый флаг

Если вы запустите свой скрипт

40 05 * * * bash /root/scripts/direct.sh

исполняемые флаги не требуются, но вы должны добавить их:

chmod +x ~/scripts/direct.sh

если вы хотите запустить:

40 05 * * * /root/scripts/direct.sh

1) Убедитесь, что эта задача находится в crontab пользователя root - возможно, это так, но вы не написали ее явно

2) cron может быть не в состоянии найти bash, Я бы удалил его и вызвал непосредственно ваш скрипт после того, как сделал его исполняемым:

chmod 755 /root/scripts/direct.sh

а затем установите запись в crontab как 40 05 * * * /root/scripts/direct.sh 2>&1 >> /root/cron.log

Если он все еще не работает, вы должны получить полезный вывод в /root/cron.log

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

40 05 * * * /root/scripts/direct.sh &>> /root/cron.log

Затем вы устанавливаете свой путь в обратном порядке, и вы пропускаете свой shbang. Я понятия не имею, почему вы определяете SHELL как /bin/sh, когда вы запускаете bash, а не dash. Измените свой сценарий на это.

#!/usr/bin/env bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root
PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/

Посмотрите, даст ли это что-то лучшее для работы.

Вы уверены, что ваш скрипт работает? Добавьте другую команду как touch /tmp/cronok перед docker exec вызов.

Не забывайте, что в конце crontab нужна новая строка. использование crontab -e редактировать это.

Перезапустите сервис cron и проверьте логи (grep -i cron /var/log/syslog).

Если ваша ОС - redhat/centos/fedora, попробуйте использовать имя пользователя (root) между частотой и командой.

Проверьте свою почту с mail команда.

Проверьте разрешения crontab. chmod 644 /etc/crontab,

Может быть, вы просто не хотите изобретать велосипед.

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