2008-08-16 23 views
7

Tengo un trabajo cron en un Ubuntu Hardy VPS que solo funciona a medias y no sé por qué. El trabajo es un script de Ruby que usa mysqldump para realizar una copia de seguridad de una base de datos MySQL utilizada por una aplicación de Rails, que luego se descomprime y se carga en un servidor remoto utilizando SFTP.¿Por qué mi trabajo de Cron no funciona correctamente?

El archivo gzip se crea y se copia con éxito, pero siempre es de cero bytes. Sin embargo, si ejecuto el comando cron directamente desde la línea de comandos, funciona perfectamente.

Este es el trabajo de cron:

PATH=/usr/bin 
10 3 * * * ruby /home/deploy/bin/datadump.rb 

Ésta es 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' 

He comprobado y doble comprobado todos los caminos y son correctos. Tanto sftp.yml (credenciales SFTP) como database.yml (credenciales de MySQL) son propiedad del usuario ejecutante (implementación) con permisos de solo lectura para ese usuario (chmod 400). Estoy usando las versiones 1.1.x de net-ssh y net-sftp. Sé que no son los últimos, pero son lo que estoy familiarizado en este momento.

¿Qué podría estar causando el error de la tarea cron?

Respuesta

2

¿Está seguro de que el archivo temporal se está creando correctamente cuando se ejecuta como un trabajo cron? El directorio de trabajo para su script se especificará en la variable de entorno HOME o en la entrada/etc/passwd para el usuario que instaló el trabajo cron. Si la implementación no tiene permisos de escritura para el directorio en el que se está ejecutando, puede especificar una ruta absoluta para el archivo de volcado para solucionar el problema.

4

Parece que su PATH le falta algunos directorios, lo más importante es /bin (para /bin/rm). Esto es lo que utiliza mi sistema /etc/crontab:

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

es el envío de mensajes de correo electrónico con cron registros?

Si no, canalice la salida de cron a un archivo de registro.

Asegúrese de redirigir STDERR al registro.

8

Cuando los scripts se ejecutan correctamente de forma interactiva pero no cron, el problema suele ser la configuración del entorno de entorno ... por ejemplo, la RUTA como se menciona anteriormente por @Ted Percival, pero puede haber otras variables de entorno.

Esto se debe a que cron no invocará .bash_profile, .bashrc o/etc/profile antes de la ejecución.

La mejor manera de evitar esto es asegurarse de que los scripts invocados por cron no hagan suposiciones sobre el entorno cuando se ejecutan. Vencer esto puede ser tan simple como incluir algunas líneas en tu script para asegurarte de que el entorno esté configurado correctamente. Por ejemplo, en mi caso tengo todas las configuraciones significativas en/etc/profile (para RHEL), así que incluiré la siguiente línea en cualquier script para ejecutar bajo cron:

source /etc/profile 
Cuestiones relacionadas