为什么我的定时任务不能正常工作?

7

我在一台Ubuntu Hardy VPS上有一个cron job,它只能部分工作,但我无法弄清楚原因。该任务是一个Ruby脚本,使用mysqldump备份Rails应用程序使用的MySQL数据库,然后使用SFTP将其压缩并上传到远程服务器。

虽然gzip文件成功创建并复制,但它始终为零字节。但是,如果我直接从命令行运行cron命令,则完美运行。

这是cron job:

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凭据)和database.yml(MySQL凭据)都由执行用户(deploy)拥有,并且该用户具有只读权限(chmod 400)。我正在使用net-ssh和net-sftp的1.1.x版本。我知道它们不是最新版本,但目前我熟悉这些版本。

可能是什么原因导致cron作业失败?

4个回答

9
当脚本在交互式运行时正常,但在由cron运行时出现问题时,通常是因为环境设置存在问题...例如PATH,如@Ted Percival所提到的,但可能还有其他环境变量。
这是因为cron在执行之前不会调用.bash_profile、.bashrc或/etc/profile。
避免这种情况的最好方法是确保cron调用的任何脚本在执行时都不会对环境进行任何假设。克服这个问题可以很简单,只需在您的脚本中包含几行代码来确保环境设置正确。例如,在我的情况下,我将所有重要的设置放在/etc/profile(对于RHEL),因此我会在任何要在cron下运行的脚本中包含以下行:
source /etc/profile

4

看起来您的PATH缺少一些目录,最重要的是/bin(用于/bin/rm)。这是我的系统的/etc/crontab使用的内容:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

2

你确定作为cron作业运行时临时文件被正确创建了吗?你的脚本工作目录将在HOME环境变量中指定,或者是安装cron作业的用户的/etc/passwd条目中。如果deploy在执行的目录中没有写权限,则可以指定转储文件的绝对路径来解决问题。


0

cron是否发送带有日志的电子邮件?

如果没有,请将cron的输出导入到日志文件中。

确保将STDERR重定向到日志中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接