find -delete berfungsi OK, tetapi tidak dengan cron


10

HARAP DICATAT : Saya telah membaca semua pertanyaan serupa kembali. cron, paths, env variabel dan sebagainya, tetapi tidak menemukan satupun yang menawarkan solusi untuk masalah khusus saya.


Saya memiliki skrip yang membuat beberapa dump MySQL dan kemudian menghapus yang lama seperti ini:

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

( perintah di atas telah dimodifikasi dari perintah asli saya dengan saran dari komentar )

Namun, file tidak pernah dihapus ketika cron menjalankan skrip ini. Pengguna cron adalah root.

Catatan debugging

  • Jika saya menjalankan skrip secara manual di mana perintah muncul, itu menghapusnya seperti yang diharapkan.

  • Jika saya menjalankan perintah find di atas sendiri dari baris perintah sebagai root, ia menghapusnya seperti yang diharapkan (dan dengan -cetak ia mengembalikan daftar file yang lebih lama dari 5 hari seperti yang diharapkan)

  • Saya juga menambahkan pernyataan path eksplisit ke crontab root, tapi
    itu tidak mengubah apa pun.

  • Cron tidak mengirim kesalahan, dan jika saya mem-pipe operasi find ke file log,
    yang muncul kosong atau tidak dibuat sama sekali.

  • Saya menggunakan server Ubuntu 14.04.03 LTS.


Saya akan menghindari ekspansi wildcard (mis. * .Gz) di jalur. cron mungkin diartikan sebagai * .gz, tidak memperluas semua file gz.
Archemar

Output apa yang Anda dapatkan jika Anda menjalankan pekerjaan tanpa tindakan/usr/bin/find /home/bkp/dbdump/*.gz -mtime +5
user9517

@Archemar. Mengapa wildcard tidak diperluas? cronperintah dijalankan melalui shell, dan shell memperluas wildcard.
Barmar

cronharus mengirim email dengan pesan kesalahan dan keluaran. Apakah Anda mendapatkan email seperti itu dari pekerjaan ini?
Barmar

@ Tetap bekerja seperti yang diharapkan.
TommyPeanuts

Jawaban:


6

Masalahnya adalah bahwa crontabitu tidak $PATHdiatur saat dijalankan. Anda benar-benar dapat menyediakannya dengan jalur dengan menambahkan ini ke bagian atas file yang dibuka melalui crontab -e:

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

(atau apa pun yang PATHAnda inginkan untuk digunakan). Ini berarti Anda dapat menghindari menentukan path lengkap ke perintah, langsung dari cron.

Ada beberapa masalah dengan perintah asli Anda. Anda pada dasarnya meminta shell untuk melakukan ekspansi wildcard, bukan find. Kedua, Anda tidak menyediakan jalur lengkap untuk rm; gunakan /bin/rmatau /usr/bin/rm, di mana pun ia berada di sistem Anda (lihat which rm).

Argumen pertama untuk menemukan adalah "lokasi untuk mencari", dan kemudian Anda menentukan "permintaan pencarian" dengan berbagai -<option>s. Jadi, format yang tepat dari perintah yang ingin Anda jalankan adalah:

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

atau

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

Jika Anda tidak menentukan PATHdefinisi seperti di atas, gunakan:

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

atau

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

1
Seharusnya sudah $PATHdiatur, tetapi itu akan menjadi standar sistem. Ini akan termasuk /usr/bindan /bin, jadi itu harus dapat menemukan rmperintah.
Barmar

Jadi saya mencoba meletakkan $ PATH di crontab (walaupun seperti yang disebutkan di tempat lain mungkin akan default ke jalur sistem jika tidak dinyatakan), dan memastikan semuanya memiliki jalur penuh. Saya juga menggunakan -nama "* .gz" alih-alih wildcard di jalur temukan. Tetapi tidak ada yang terjadi. Perintah itu sepertinya tidak berjalan dan tidak ada kesalahan yang dilemparkan.
TommyPeanuts

3

Coba ini sebagai gantinya

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete

Mengapa Anda mengarahkan stderr ke file? Secara default akan dikirim melalui email jika ada output.
kasperd

Ya memang benar bahwa secara default mengirim email apa pun ke spooler MAIL pengguna dan dapat dibaca menggunakan surat.
shad0VV

1
Untuk mendapatkan efek yang sama dengan perintah asli, Anda perlu menambahkan -maxdepth 1.
Niels Keurentjes

0

Jika saya memohon perintah find langsung dari crontab root dan bukan sebagai bagian dari skrip, maka itu berfungsi.

Script yang dimaksud menggunakan csh. Saya percaya bahwa lingkungan cron root pada Ubuntu akan menggunakan / bin / bash (atau / bin / dash?). Mungkin ini bertentangan dengan cara bagaimana perintah find dijalankan.

Apa pun itu, masalah utama yang dipecahkannya, meski agak tidak hati-hati.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.