Mengapa menemukan dengan -delete menghapus file di direktori / save / saya ketika menemukan tanpa menghapus tidak dapat menemukannya?


20

Saya ingin menghapus semua file di pohon direktori saat ini, kecuali yang ada di save. Saya menjalankan perintah ini:

 find . \( -name save -prune \) -o -type f -ls | grep /save/

dan tidak menemukannya. Tetapi ketika saya menjalankan perintah ini:

 find . \( -name save -prune \) -o -type f -delete

Semua file di / save / sudah tidak ada. Apa yang saya lewatkan?


4
Aduh ... saya belajar sesuatu hari ini (terima kasih untuk Anda). Dan saya merekomendasikan yang sederhana mv save/ ../some/safer/locationsebelum perintah penghapusan "generik" (... tapi tentu saja, sebelum posting Anda, saya akan melakukan pemeriksaan yang sama dan mengalami masalah yang sama!). Sekarang, cari "undelete" yang bagus untuk sistem file tempat file ^^
Olivier Dulac

3
Rasa sakit saya adalah pencegahan Anda.
Otheus

1
1000 terima kasih untukmu. Kode (sering?) Berfungsi dengan cara yang misterius ...
Olivier Dulac


@lesmana saya mengubah jawaban Anda di sana. Sayangnya, versi penemuan saya tidak memberi saya peringatan yang bagus :(
Otheus

Jawaban:


26

-deletemenyiratkan -depthbahwa tidak bekerja dengan -prune( -depthdimulai dengan daun). Ada peringatan tentang hal itu di manual versi GNU ( -deleteadalah ekstensi FreeBSD sekarang juga didukung oleh GNU finddan beberapa implementasi lainnya).

info find --index-search=-delete

Penggunaan tindakan '-delete' pada baris perintah secara otomatis mengaktifkan opsi '-depth' (* note find Expressions: :). Ini bisa mengejutkan jika Anda sebelumnya hanya menguji dengan '-print', jadi biasanya yang terbaik adalah ingat untuk menggunakan '-depth' secara eksplisit.

info find --index-search=-prune

Karena '-delete' menyiratkan '-depth', menggunakan '-prune' dalam kombinasi dengan '-delete' dapat mengakibatkan penghapusan lebih banyak file daripada yang Anda inginkan.

Di sini, Anda memiliki pilihan untuk menggunakan rm:

find . -name save -prune -o -type f -exec rm -f {} +

(berpotensi tidak aman jika ada direktori yang dapat ditulisi oleh orang lain di sana, karena orang dapat membuat Anda menghapus file di luar pohon direktori saat ini dengan mengganti direktori dengan symlink saat Anda menjalankan perintah itu).

Alternatif yang lebih aman:

find . -name save -prune -o -type f -execdir rm -f -- {} \;

Itu tidak memiliki masalah yang disebutkan di atas tetapi berarti menjalankan satu rmper file. The --diperlukan untuk pelaksanaan FreeBSD, bukan GNU yang awalan nama file dengan ./.

Atau, seperti yang disarankan oleh Costas:

LC_ALL=C find . ! -name save ! -path '*/save/*' -type f -delete

(tapi itu masih sia-sia masuk ke savedirektori)

Apakah LC_ALL=Cada sehingga *cocok dengan urutan byte (bahkan yang tidak membentuk karakter yang valid di lokal saat ini). Perhatikan bahwa ini akan memengaruhi bahasa pesan kesalahan (Bahasa Inggris alih-alih bahasa pengguna).


Dengan apa masalah keamanan di sini rm?
jrw32982 mendukung Monica

@ jrw32982, lihat edit dengan tautan ke manual menemukan GNU
Stéphane Chazelas
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.