find -delete funktioniert OK, aber nicht mit cron

10

BITTE BEACHTEN SIE : Ich habe alle ähnlichen Fragen bezüglich gelesen. cron, Pfade, env-Variablen usw., aber keine gefunden, die Lösungen für mein spezielles Problem bieten.


Ich habe ein Skript, das einige MySQL-Dumps erstellt und dann alte wie folgt löscht:

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

(Der obige Befehl wurde von meinem ursprünglichen Befehl durch Vorschläge aus Kommentaren geändert. )

Die Dateien werden jedoch niemals gelöscht, wenn cron dieses Skript ausführt. Der Cron-Benutzer ist root.

Debuggen von Notizen

  • Wenn ich das Skript, in dem der Befehl angezeigt wird, manuell ausführe, werden sie wie erwartet gelöscht.

  • Wenn ich den obigen Befehl find alleine über die Befehlszeile als root ausführe, werden sie wie erwartet gelöscht (und mit -print wird erwartungsgemäß eine Liste von Dateien zurückgegeben, die älter als 5 Tage sind).

  • Ich habe auch eine explizite Pfadanweisung zu Roots Crontab hinzugefügt, aber
    das ändert nichts.

  • Cron sendet keinen Fehler, und wenn ich die Suchoperation an eine Protokolldatei weitergebe, wird
    diese leer oder überhaupt nicht erstellt.

  • Ich benutze Ubuntu Server 14.04.03 LTS.

TommyPeanuts
quelle
Ich würde eine Wildcard-Erweiterung (z. B. * .gz) im Pfad vermeiden. cron wird möglicherweise als * .gz interpretiert und erweitert nicht alle gz-Dateien.
Archemar
Welche Ausgabe erhalten Sie, wenn Sie den Job ohne Aktion /usr/bin/find /home/bkp/dbdump/*.gz -mtime +5
ausführen
@Archemar Warum wird der Platzhalter nicht erweitert? cronBefehle werden durch die Shell ausgeführt, und die Shell erweitert Platzhalter.
Barmar
cronsollte E-Mails mit Ausgabe- und Fehlermeldungen senden. Erhalten Sie eine solche E-Mail von diesem Job?
Barmar
@Iain es funktioniert wie erwartet.
TommyPeanuts

Antworten:

6

Das Problem ist, dass crontabnicht $PATHfestgelegt, wann es ausgeführt wird. Sie können ihm tatsächlich einen Pfad zuweisen, indem Sie diesen am Anfang der geöffneten Datei hinzufügen über crontab -e:

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

(oder was auch immer PATHSie bevorzugen zu verwenden). Dies bedeutet, dass Sie vermeiden können, die vollständigen Pfade zu Befehlen direkt von cron aus anzugeben.

Es gibt mehrere Probleme mit Ihrem ursprünglichen Befehl. Sie fordern die Shell grundsätzlich auf, die Platzhaltererweiterung durchzuführen, anstatt find. Zweitens bieten Sie keinen vollständigen Pfad für rm; Verwenden Sie /bin/rmoder /usr/bin/rm, wo immer es sich auf Ihrem System befindet (siehe which rm).

Das erste Argument für find ist der "zu suchende Ort", und dann geben Sie die "Suchabfrage" mit den verschiedenen -<option>s an. Das richtige Format für den Befehl, den Sie ausführen möchten, lautet also:

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

oder

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

Wenn Sie die PATHDefinition nicht wie oben angeben , verwenden Sie:

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

oder

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete
Wille
quelle
1
Es sollte $PATHeingestellt sein, aber es wird die Standardeinstellung des Systems sein. Dies schließt /usr/binund ein /bin, damit der rmBefehl gefunden werden kann.
Barmar
Also habe ich versucht, $ PATH in die Crontab einzufügen (obwohl, wie an anderer Stelle erwähnt, wahrscheinlich standardmäßig der Systempfad verwendet wird, wenn nicht angegeben), und ich habe sichergestellt, dass alles über vollständige Pfade verfügt. Ich habe auch -name "* .gz" anstelle eines Platzhalters im Suchpfad verwendet. Aber nichts passiert. Der Befehl scheint einfach nicht zu laufen und es werden keine Fehler ausgegeben.
TommyPeanuts
3

Versuchen Sie dies stattdessen

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete
Shad0VV
quelle
Warum sollten Sie stderr in eine Datei umleiten? Standardmäßig wird es per E-Mail gesendet, wenn eine Ausgabe erfolgt ist.
Kasperd
Ja, es ist wahr, dass standardmäßig jede E-Mail an die Spooler-MAIL des Benutzers gesendet wird und per E-Mail gelesen werden kann.
Shad0VV
1
Um den gleichen Effekt wie beim ursprünglichen Befehl zu erzielen, müssen Sie ihn hinzufügen -maxdepth 1.
Niels Keurentjes
0

Wenn ich den Befehl find direkt von der crontab-Datei von root aus und nicht als Teil des Skripts aufrufe, funktioniert er.

Das betreffende Skript verwendet csh. Ich glaube, dass die Cron-Umgebung von root unter Ubuntu / bin / bash (oder / bin / dash?) Verwendet. Vielleicht widerspricht dies in irgendeiner Weise der Ausführung des Befehls find.

In jedem Fall löste sich das Hauptproblem, wenn auch etwas unelegant.

TommyPeanuts
quelle