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
,
Может быть, вы просто не хотите изобретать велосипед.