Tengo una tarea cron programada para ejecutarse todos los días, además de cambiar la programación, ¿hay alguna otra forma de realizar una ejecución de prueba del comando ahora mismo para ver si funciona según lo previsto?
EDITAR: (de los comentarios) Sé que el comando funciona bien cuando lo ingresa en Shell (mi Shell), pero quiero saber si funciona correctamente cuando cron lo ejecuta, podría verse afectado por ENV o cosas específicas del Shell (~ expansión ) o cosas de propiedad y permiso o ...
Respuesta1
Puede forzar la ejecución del crontab con el siguiente comando:
run-parts /etc/cron.daily
Respuesta2
Puede simular el entorno de usuario cron como se explica en"Ejecutar un trabajo cron de forma manual e inmediata". Esto le permitirá probar que el trabajo funciona cuando se ejecute como usuario cron.
Extracto del enlace:
Paso 1: Puse esta línea temporalmente en el crontab del usuario:
* * * * * /usr/bin/env > /home/username/tmp/cron-env
Luego lo sacó una vez que se escribió el archivo.
Paso 2: Hice un pequeño script bash ejecutable como cron que contiene:
#!/bin/bash
/usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@"
Entonces, como usuario en cuestión, pude
run-as-cron /the/problematic/script --with arguments --and parameters
Respuesta3
Hasta donde yo sé, no hay forma de hacerlo directamente, ya que cron tiene un propósito especial: ejecutar comandos programados en un momento específico. Entonces, lo mejor es crear manualmente una entrada crontab (temporal) o escribir un script que elimine y restablezca el entorno.
Explicación de "elimina y restablece el entorno":
Se podría iniciar un script contenedor env -i
(que elimina el entorno), lo que generaría un entorno guardado (asegurándose de exportar todas las variables, posiblemente configurándolas set -a
primero) antes de iniciar el script.
El entorno guardado sería el entorno predeterminado de un trabajo cron, registrado al ejecutarlo env
(o declare -p
dependiendo del shell que utilicen sus trabajos cron) como un trabajo cron, guardando su salida.
Respuesta4
Después de tener la necesidad de depurar trabajos cron, escribí el siguiente script. Se esfuerza por simular exactamente las mismas condiciones que cron antes de ejecutar un comando (eso incluye un entorno modificado, pero también tiene que ver con shells no interactivos, sin terminal conectado, etc.).
Llámelo con su comando/script como argumento y tendrá una forma instantánea y sencilla de depurar su trabajo cron. También está alojado (y posiblemente actualizado) en GitHub:run-as-cron.sh
:
#!/bin/bash
# Run as if it was called from cron, that is to say:
# * with a modified environment
# * with a specific shell, which may or may not be bash
# * without an attached input terminal
# * in a non-interactive shell
function usage(){
echo "$0 - Run a script or a command as it would be in a cron job," \
"then display its output"
echo "Usage:"
echo " $0 [command | script]"
}
if [ "$1" == "-h" -o "$1" == "--help" ]; then
usage
exit 0
fi
if [ $(whoami) != "root" ]; then
echo "Only root is supported at the moment"
exit 1
fi
# This file should contain the cron environment.
cron_env="/root/cron-env"
if [ ! -f "$cron_env" ]; then
echo "Unable to find $cron_env"
echo "To generate it, run \"/usr/bin/env > /root/cron-env\" as a cron job"
exit 0
fi
# It will be a nightmare to expand "$@" inside a shell -c argument.
# Let's rather generate a string where we manually expand-and-quote the arguments
env_string="/usr/bin/env -i "
for envi in $(cat "$cron_env"); do
env_string="${env_string} $envi "
done
cmd_string=""
for arg in "$@"; do
cmd_string="${cmd_string} \"${arg}\" "
done
# Which shell should we use?
the_shell=$(grep -E "^SHELL=" /root/cron-env | sed 's/SHELL=//')
echo "Running with $the_shell the following command: $cmd_string"
# Let's redirect the output into files
# and provide /dev/null as input
# (so that the command is executed without an open terminal
# on any standard file descriptor)
so=$(mktemp "/tmp/fakecron.out.XXXX")
se=$(mktemp "/tmp/fakecron.err.XXXX")
"$the_shell" -c "$env_string $cmd_string" > "$so" 2> "$se" < /dev/null
echo -e "Done. Here is \033[1mstdout\033[0m:"
cat "$so"
echo -e "Done. Here is \033[1mstderr\033[0m:"
cat "$se"
rm "$so" "$se"