
estou tentando executar um script armazenado em meu diretório pessoal via crontab, mas não está funcionando. O log CRON apenas diz isso toda vez que está em execução:
Sep 3 18:30:01 backup CRON[6778]: (root) CMD (/home/hannes/script > /tmp/yc.log)
Sep 3 18:30:01 backup CRON[6777]: (CRON) info (No MTA installed, discarding output)
Crontab:
*/1 * * * * /home/hannes/script > /tmp/yc.log
Se eu tentar adicionar a extensão de arquivo .sh, isso não mudará nada. O arquivo yc.log permanece vazio.
Este é o script que estou tentando executar (funciona bem se eu executá-lo manualmente):
#!/bin/sh
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server
zip -r mnt/backup-nas/01/1.19_Test.`date +%d.%m.%Y_%H.%M.%S`.zip mnt/backup-nas/01/temp/server
rm -r mnt/backup-nas/01/temp/server
Qualquer ajuda é apreciada! :)
Responder1
Seu roteiroérealmente em execução... mas está com erro em algum lugar. E como você não captura stderr
a saída, o stderr é enviado cron
para o usuário que está executando o script localmente. (E falhando também)
A causa raiz é esta: seu script redireciona apenas stdout
para arquivos. Muitos scripts e programas com falha, no entanto, são usados stderr
para gerar mensagens de erro. Você precisa capturar isso adicionando 2>&1
ao final da linha de comando que cron
é executado, o que também capturará stderr
e registrará erros em seu arquivo.
Como você não percebeu isso anteriormente, o stderr estava sendo entregue por correio para root
- mas como você não tem um MTA local (Mail Transfer Agent, também conhecido como servidor Local Mail Transport Protocol (LMTP)) para entrega local, você obteve esses erros do cron . Com a stderr
captura você verá erros e por que seus scripts não foram executados corretamente.
Depois de obter a saída de erro em seus logs, você poderá depurar ainda mais seu script para determinar o que precisa ser feito para 'consertar' as coisas.
Responder2
Então houve vários problemas. Primeiramente esqueci de adicionar o 2>&1
final do /home/hannes/script > /tmp/yc.log
para que o log fosse realmente salvo. E em segundo lugar, cometi um erro de digitação no meu script, onde esqueci a primeira barra em todos os caminhos. Foi disso home/hannes/...
para isso /home/hannes/...
. Espero que isso ajude outras pessoas com problemas semelhantes e obrigado a todos que responderam :)
Responder3
A resposta aceita está correta e cobre a questão formulada. No entanto, as informações fornecidas na pergunta indicam um problema potencial não relacionado com este script que considero importante alertar o OP, e explicá-lo adequadamente é muito longo para um comentário, por isso estou adicionando uma resposta especificamente para cobrir isso.
Além do problema de registro, seu arranjo também possui uma condição de corrida potencialmente desagradável. Como o script sempre usa o mesmo diretório para preparar os arquivos a serem arquivados, se mais de uma instância do script for executada simultaneamente, a primeira execução provavelmente removerá os arquivos nos quais as instâncias subsequentes estão trabalhando no momento, levando a problemas adicionais. falhas e provavelmente arquivos incompletos (porque os arquivos desaparecerão antes que zip
possamos processá-los).
Isso pode ser resolvido de duas maneiras: o próprio script deve usar um diretório por invocação ou o bloqueio de arquivo deve ser usado para evitar execuções simultâneas.
A primeira abordagem é muito mais fácil, basta adicionar a data ao diretório que você está usando. Isso seria mais ou menos assim (observe que isso também garante que date
seja chamado apenas uma vez):
#!/bin/sh
now="$(date +%d.%m.%Y_%H.%M.%S)"
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server/${now}
zip -r mnt/backup-nas/01/1.19_Test.${now}.zip mnt/backup-nas/01/temp/server/${now}
rm -r mnt/backup-nas/01/temp/server/${now}
A abordagem de bloqueio de arquivos é um pouco mais complicada, mas sem dúvida mais limpa, porque também garante que você não possa inundar acidentalmente o sistema com vários zip
comandos em execução ao mesmo tempo. Isso envolve o uso de um comando chamado flock
(parte do util-linux
pacote no Ubuntu e Debian, que já estará instalado) e é mais ou menos assim (com comentários para explicar o que está acontecendo):
#!/bin/sh
# All of this gets run in a subshell so we can hold a file descriptor open
# for all the commands. We're using file descriptor 9 here, but any number
# higher than 2 will work.
(
# This flock command is what actually takes the lock. The lock itself
# persists until the file descriptor is closed when the subshell exits.
# The -x means it's an exclusive lock (so only one instance can hold it).
# The -w says to try for that many seconds before failing if something
# else is holding the lock (this is an important safety net to ensure you
# don’t get a long queue of these scripts waiting to run).
# The -n indicates which file descriptor to take the lock on.
flock -x -w 30 -n 9 || exit 1
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server
zip -r mnt/backup-nas/01/1.19_Test.`date +%d.%m.%Y_%H.%M.%S`.zip mnt/backup-nas/01/temp/server
rm -r mnt/backup-nas/01/temp/server
# And this line closes the subshell, and also sets the path to be used for
# the lock file by opening it as file descriptor 9 for the subshell. /run
# is generally the place you want to put stuff like this, because it will
# get cleaned up automatically every time the system reboots.
) 9> /run/backup-nas.lock