Eu tenho um cron job programado para ser executado todos os dias, além de alterar o agendamento. Existe alguma outra maneira de fazer um teste do comando agora para ver se funciona conforme o esperado?
EDIT: (dos comentários) Eu sei que o comando funciona bem quando inserido no shell (meu shell), mas quero saber se funciona corretamente quando o cron o executa, ele pode ser afetado por ENV ou coisas específicas do shell (~ expansão ) ou coisas de propriedade e permissão ou ...
Responder1
Você pode forçar a execução do crontab com o seguinte comando:
run-parts /etc/cron.daily
Responder2
Você pode simular o ambiente do usuário cron conforme explicado em"Executando um cron job manualmente e imediatamente". Isso permitirá que você teste o funcionamento do trabalho quando ele for executado como usuário cron.
Trecho do link:
Passo 1: coloquei esta linha temporariamente no crontab do usuário:
* * * * * /usr/bin/env > /home/username/tmp/cron-env
em seguida, retirei-o assim que o arquivo foi gravado.
Passo 2: Criei um pequeno script bash executado como cron contendo:
#!/bin/bash
/usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@"
Então, como usuário em questão, consegui
run-as-cron /the/problematic/script --with arguments --and parameters
Responder3
Até onde eu sei, não há como fazer isso diretamente, pois o cron tem um propósito especial - executar comandos de agendamento em um horário específico. Portanto, a melhor coisa é criar manualmente uma entrada crontab (temporária) ou escrever um script que remova e redefina o ambiente.
Explicação de "remove e redefine o ambiente":
Um script wrapper pode ser iniciado env -i
(que remove o ambiente), o que geraria um ambiente salvo (certificando-se de exportar todas as variáveis, possivelmente configurando set -a
primeiro) antes de iniciar seu script.
O ambiente salvo seria o ambiente padrão de um cron job, registrado pela execução env
(ou declare -p
dependendo de qual shell seus cron jobs usam) como um cronjob, salvando sua saída.
Responder4
Depois de precisar depurar tarefas cron, escrevi o seguinte script. Ele se esforça para simular exatamente as mesmas condições do cron antes de executar um comando (que inclui um ambiente modificado, mas também tem a ver com shells não interativos, nenhum terminal conectado, etc.).
Chame-o com seu comando/script como argumento e você terá uma maneira instantânea e fácil de depurar seu cron job. Também está hospedado (e possivelmente atualizado) no 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"