Почему Мое задание Cron не работает должным образом?
-
08-06-2019 - |
Вопрос
У меня есть задание cron на Ubuntu Hardy VPS, которое работает только наполовину, и я не могу понять, почему.Задание представляет собой скрипт Ruby, который использует mysqldump для резервного копирования базы данных MySQL, используемой приложением Rails, которая затем архивируется и загружается на удаленный сервер с использованием SFTP.
Файл gzip создан и успешно скопирован, но в нем всегда ноль байт.Тем не менее, если я запускаю команду cron непосредственно из командной строки, она работает отлично.
Это и есть задание cron:
PATH=/usr/bin
10 3 * * * ruby /home/deploy/bin/datadump.rb
Это файл datadump.rb:
#!/usr/bin/ruby
require 'yaml'
require 'logger'
require 'rubygems'
require 'net/ssh'
require 'net/sftp'
APP = '/home/deploy/apps/myapp/current'
LOGFILE = '/home/deploy/log/data.log'
TIMESTAMP = '%Y%m%d-%H%M'
TABLES = 'table1 table2'
log = Logger.new(LOGFILE, 5, 10 * 1024)
dump = "myapp-#{Time.now.strftime(TIMESTAMP)}.sql.gz"
ftpconfig = YAML::load(open('/home/deploy/apps/myapp/shared/config/sftp.yml'))
config = YAML::load(open(APP + '/config/database.yml'))['production']
cmd = "mysqldump -u #{config['username']} -p#{config['password']} -h #{config['host']} --add-drop-table --add-locks --extended-insert --lock-tables #{config['database']} #{TABLES} | gzip -cf9 > #{dump}"
log.info 'Getting ready to create a backup'
`#{cmd}`
# Strongspace
log.info 'Backup created, starting the transfer to Strongspace'
Net::SSH.start(ftpconfig['strongspace']['host'], ftpconfig['strongspace']['username'], ftpconfig['strongspace']['password']) do |ssh|
ssh.sftp.connect do |sftp|
sftp.open_handle("#{ftpconfig['strongspace']['dir']}/#{dump}", 'w') do |handle|
sftp.write(handle, open("#{dump}").read)
end
end
end
log.info 'Finished transferring backup to Strongspace'
log.info 'Removing local file'
cmd = "rm -f #{dump}"
log.debug "Executing: #{cmd}"
`#{cmd}`
log.info 'Local file removed'
Я проверил и перепроверил все пути, и они верны.И то , и другое sftp.yml (Учетные данные SFTP) и база данных.yml (Учетные данные MySQL) принадлежат исполняющему пользователю (deploy) с разрешениями только для чтения для этого пользователя (chmod 400).Я использую версии net-ssh и net-sftp 1.1.x.Я знаю, что они не самые последние, но это то, с чем я знаком на данный момент.
Что может быть причиной сбоя задания cron?
Решение
Вы уверены, что временный файл создается правильно при запуске в качестве задания cron?Рабочий каталог для вашего скрипта будет указан либо в переменной среды HOME, либо в записи /etc/passwd для пользователя, установившего задание cron.Если у deploy нет прав на запись для каталога, в котором оно выполняется, то вы могли бы указать абсолютный путь к файлу дампа, чтобы устранить проблему.
Другие советы
Когда скрипты выполняются корректно в интерактивном режиме, но не при запуске cron, проблема обычно возникает из-за существующих настроек среды ...например, ПУТЬ, как уже упоминал @Ted Percival, но могут быть и другие переменные окружения.
Это связано с тем, что cron не будет вызывать .bash_profile, .bashrc или /etc/profile перед выполнением.
Лучший способ избежать этого - убедиться, что любые скрипты, вызываемые cron, не делают никаких предположений об окружающей среде при выполнении.В дальнейшем это может быть так же просто, как включить несколько строк в ваш скрипт, чтобы убедиться, что среда настроена правильно.Например, в моем случае у меня есть все важные настройки в /etc/profile (для RHEL), поэтому я буду включать следующую строку во все скрипты, которые будут запускаться под cron:
source /etc/profile
Похоже, твой PATH
отсутствует несколько каталогов, наиболее важных /bin
(для /bin/rm
).Вот что представляет собой моя система /etc/crontab
использование:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
Отправляет ли cron электронные письма с логами?
Если нет, передайте выходные данные cron в файл журнала.
Обязательно перенаправьте STDERR в журнал.