Saat menjalankan `rm -rf`, apakah mungkin untuk mengecualikan subdirektori tertentu?

4

Saya secara rutin menggunakan bind mounts untuk membantu membuat ruang tersedia di banyak lokasi tanpa harus memiliki beberapa volume logis / partisi fisik / LUN, dll.

Sebagai contoh, saya mungkin memasang LV 200G di /space. Dari sana, saya akan membuat subdirektori seperti var_opt dan var_log yang kemudian saya bisa ikat mount ke /var/opt dan /var/logmasing-masing.

Ketika melakukan pembersihan pada direktori 'space', apakah mungkin mengecualikan direktori dari rm -rf berlari di dalam /space?

Contoh:

# pwd
/space
# rm -rf * {except-for-var_opt-and-var_log}

Apakah ada cara berbeda atau lebih baik (tetapi juga sederhana) untuk mencapai apa yang saya coba lakukan yang belum saya pikirkan?

warren
sumber

Jawaban:

1

Mungkin dengan menemukan + xargs + rm kombinasi?

find /space ! -iregex '(var_opt|var_log)' | xargs rm -f

atau sesuatu dalam nada itu. Tentu saja, mungkin bijaksana untuk menginstruksikan xargs terlebih dahulu untuk mengeksekusi sesuatu yang lebih tidak berbahaya, seperti gema, sebelum mengubahnya ke ...

Janne Pikkarainen
sumber
tidak memikirkan itu! ide bagus :)
warren
4
Jangan gunakan xargs (kecuali dengan -0 )! Ia mengharapkan input dikutip dengan cara yang sangat aneh itu find tidak menghasilkan. Jadi perintah ini akan gagal total jika ada nama file yang mengandung spasi atau \'". Sebaliknya, gunakan -exec: temukan / ruang! -iregex '(var_opt | var_log)' -exec rm {} + . Or since -iregex` khusus untuk menemukan GNU, gunakan -delete tindakan: find /space ! -iregex '(var_opt|var_log)' -delete.
Gilles
11

Sederhana secara konseptual, dan memiliki risiko kesalahan yang rendah:

mkdir TO_DELETE
mv * TO_DELETE
mv TO_DELETE/var_opt TO_DELETE/var_log .
rm -rf TO_DELETE

Anda juga dapat menggunakan gumpalan diperpanjang ksh:

rm -rf !(var_opt|var_log)

Ini juga tersedia dalam bash jika Anda mengaktifkannya:

shopt -s extglob
rm -rf !(var_opt|var_log)

Ditto dalam zsh:

setopt ksh_glob
rm -rf !(var_opt|var_log)

Zsh juga memiliki gumpalan diperpanjang sendiri:

setopt extended_glob
rm -rf ^var_(opt|log)
Gilles
sumber
2

Jika nama file input Anda dihasilkan oleh pengguna, Anda harus berurusan dengan nama file mengejutkan yang mengandung spasi, ', atau "dalam nama file.

Penggunaan xargs dapat menyebabkan kejutan tidak menyenangkan karena masalah pemisah .

GNU Parallel tidak memiliki masalah itu.

find /space ! -iregex '(var_opt|var_log)' | parallel -X rm -f

Tonton video intro untuk GNU Parallel untuk belajar lebih banyak.

Ole Tange
sumber
1

Jika direktori yang ingin Anda pertahankan sebenarnya adalah mountpoints, Anda mungkin dapat menggunakannya --one-file-system dalam GNU rm.

Saya belum menyelidiki bagaimana ini diterapkan, tetapi saya menduga ini tidak akan melakukan apa yang Anda inginkan jika bind mount berasal dari dalam sistem file yang sama, jadi hati-hati! rm tidak punya --no-act opsi, tetapi Anda dapat pipa yes no | rm -ir . sebagai contoh.

Toby Speight
sumber