find -delete funciona bem, mas não com cron

10

ATENÇÃO : Li todas as perguntas semelhantes sobre re. cron, caminhos, variáveis ​​env e assim por diante, mas não encontraram nenhum que ofereça soluções para o meu problema específico.


Eu tenho um script que faz alguns despejos do MySQL e exclui os antigos como este:

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -delete

(o comando acima foi modificado do meu comando original por sugestões de comentários )

No entanto, os arquivos nunca são excluídos quando o cron executa esse script. O usuário cron é root.

Notas de depuração

  • Se eu executar manualmente o script no qual o comando aparece, ele os excluirá conforme o esperado.

  • Se eu executar o comando find acima por conta própria a partir da linha de comando como root, ele os excluirá conforme o esperado (e com -print ele retornará uma lista de arquivos com mais de 5 dias conforme o esperado)

  • Também adicionei uma declaração explícita do caminho ao crontab do root, mas
    isso não muda nada.

  • Cron não envia nenhum erro, e se eu canalizar a operação de localização para um arquivo de log,
    ele ficará vazio ou não será criado.

  • Estou usando o servidor Ubuntu 14.04.03 LTS.

TommyPeanuts
fonte
Eu evitaria a expansão de curinga (por exemplo, * .gz) no caminho. O cron pode interpretar como * .gz, não expandindo todos os arquivos gz.
Archemar
O que a saída que você ganha se você executar o trabalho sem uma ação/usr/bin/find /home/bkp/dbdump/*.gz -mtime +5
user9517
@Archemar Por que o curinga não foi expandido? cronOs comandos são executados no shell e o shell expande curingas.
Barmar
crondeve enviar email com mensagens de saída e erro. Você recebe algum e-mail desse trabalho?
Barmar
@Iain funciona como esperado.
TommyPeanuts

Respostas:

6

O problema é que crontabnão foi $PATHdefinido quando é executado. Na verdade, você pode fornecer um caminho adicionando isso ao topo do arquivo aberto via crontab -e:

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

(ou o que PATHvocê preferir usar). Isso significa que você pode evitar especificar os caminhos completos para os comandos, diretamente do cron.

Existem vários problemas com o seu comando original. Você está basicamente pedindo ao shell para fazer a expansão de curinga, em vez de find. Em segundo lugar, você não está fornecendo um caminho completo para rm; use /bin/rmou /usr/bin/rm, onde quer que esteja localizado no seu sistema (consulte which rm).

O primeiro argumento para localizar é o "local a pesquisar" e, em seguida, você especifica a "consulta de pesquisa" com os vários -<option>s. Portanto, o formato adequado do comando que você deseja executar é:

find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -exec rm -f {} \;

ou

find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete

Se você não especificar a PATHdefinição como acima, use:

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -exec /bin/rm -f {} \;

ou

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete
Vai
fonte
1
Deveria ter $PATHdefinido, mas será o padrão do sistema. Isso incluirá /usr/bine /bin, portanto, deve ser capaz de encontrar o rmcomando.
Barmar
Então, tentei colocar $ PATH no crontab (embora, como mencionado em outro lugar, provavelmente seria o padrão para o caminho do sistema, se não indicado), e certifiquei-me de que tudo tivesse caminhos completos. Eu também usei -name "* .gz" em vez de um curinga no caminho de localização. Mas nada acontece. O comando simplesmente não parece ser executado e não há erros lançados.
TommyPeanuts
3

Tente isso em vez disso

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete
shad0VV
fonte
Por que você redirecionaria o stderr para um arquivo? Por padrão, ele será enviado por email se houver alguma saída.
kasperd
Sim, é verdade que, por padrão, está enviando qualquer email para o spooler MAIL do usuário e pode ser lido usando o email.
shad0VV
1
Para obter o mesmo efeito que o comando original, você precisará adicionar -maxdepth 1.
Niels Keurentjes
0

Se eu chamar o comando find diretamente do crontab do root e não como parte do script, ele funcionará.

O script em questão usa csh. Eu acredito que o ambiente cron da raiz no Ubuntu estará usando / bin / bash (ou / bin / dash?). Talvez isso entre em conflito com o funcionamento do comando find.

De qualquer forma, a principal questão foi resolvida, embora de maneira um tanto deselegante.

TommyPeanuts
fonte