find -delete fonctionne bien, mais pas avec cron

10

VEUILLEZ NOTER : J'ai lu toutes les questions similaires concernant. cron, chemins, variables env et ainsi de suite, mais n'en ont trouvé aucune qui offre des solutions à mon problème particulier.


J'ai un script qui fait des vidages MySQL puis supprime les anciens comme ceci:

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

(la commande ci - dessus a été modifiée par rapport à ma commande d'origine par des suggestions de commentaires )

Cependant, les fichiers ne sont jamais supprimés lorsque cron exécute ce script. L'utilisateur cron est root.

Notes de débogage

  • Si j'exécute manuellement le script dans lequel la commande apparaît, il les supprime comme prévu.

  • Si j'exécute la commande find ci-dessus seule à partir de la ligne de commande en tant que root, elle les supprime comme prévu (et avec -print, elle renvoie une liste de fichiers de plus de 5 jours comme prévu)

  • J'ai également ajouté une instruction de chemin explicite à la crontab de root, mais
    cela ne change rien.

  • Cron n'envoie aucune erreur et si je redirige l'opération de recherche vers un fichier journal,
    celui-ci apparaît vide ou n'est pas créé du tout.

  • J'utilise le serveur Ubuntu 14.04.03 LTS.

TommyPeanuts
la source
J'éviterais l'expansion des caractères génériques (par exemple * .gz) dans le chemin. cron peut interpréter comme * .gz, sans étendre tous les fichiers gz.
Archemar
Quelle sortie obtenez-vous si vous exécutez le travail sans action/usr/bin/find /home/bkp/dbdump/*.gz -mtime +5
user9517
@Archemar Pourquoi le caractère générique ne serait-il pas étendu? cronles commandes sont exécutées via le shell, et le shell développe les caractères génériques.
Barmar
crondevrait envoyer un e-mail avec des messages de sortie et d'erreur. Recevez-vous un tel e-mail de ce travail?
Barmar
@Iain cela fonctionne comme prévu.
TommyPeanuts

Réponses:

6

Le problème est qu'il crontabn'a pas été $PATHdéfini lors de son exécution. Vous pouvez en fait lui fournir un chemin en l'ajoutant en haut du fichier ouvert via crontab -e:

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

(ou tout PATHce que vous préférez utiliser). Cela signifie que vous pouvez éviter de spécifier les chemins d'accès complets aux commandes, directement à partir de cron.

Il y a plusieurs problèmes avec votre commande d'origine. Vous demandez essentiellement au shell de faire l'extension générique, plutôt que find. Deuxièmement, vous ne fournissez pas un chemin complet pour rm; utilisez /bin/rmou /usr/bin/rm, où qu'il se trouve sur votre système (voir which rm).

Le premier argument pour rechercher est «l'emplacement à rechercher», puis vous spécifiez la «requête de recherche» avec les différents -<option>s. Ainsi, le format approprié de la commande que vous souhaitez exécuter est:

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

ou

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

Si vous ne spécifiez pas la PATHdéfinition comme ci-dessus, utilisez:

/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
Volonté
la source
1
Il aurait dû être $PATHdéfini, mais ce sera la valeur par défaut du système. Cela inclura /usr/binet /bin, donc il devrait être capable de trouver la rmcommande.
Barmar
J'ai donc essayé de mettre $ PATH dans la crontab (bien que comme mentionné ailleurs, il serait probablement par défaut sur le chemin système s'il n'est pas indiqué), et je me suis assuré que tout avait des chemins complets. J'ai également utilisé -name "* .gz" au lieu d'un caractère générique sur le chemin de recherche. Mais rien ne se passe. La commande ne semble tout simplement pas s'exécuter et aucune erreur n'est générée.
TommyPeanuts
3

Essayez ceci à la place

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete
shad0VV
la source
Pourquoi voudriez-vous rediriger stderr vers un fichier? Par défaut, il sera envoyé par e-mail en cas de sortie.
kasperd
Oui, il est vrai que, par défaut, il envoie tout e-mail au spouleur MAIL de l'utilisateur et peut être lu à l'aide du courrier.
shad0VV
1
Pour obtenir le même effet que la commande d'origine, vous devez ajouter -maxdepth 1.
Niels Keurentjes
0

Si j'appelle la commande find directement à partir de la crontab de root et non dans le cadre du script, alors cela fonctionne.

Le script en question utilise csh. Je crois que l'environnement cron de root sur Ubuntu utilisera / bin / bash (ou / bin / dash?). Peut-être que cela entre en conflit avec la façon dont la commande find était en cours d'exécution.

Quoi qu'il en soit, le principal problème qu'il a résolu, quoique quelque peu inélégant.

TommyPeanuts
la source