Apakah `rm -rf` bukan atom?

11

Saya baru saja menemukan kesalahan yang membingungkan:

rm: cannot remove `xxx/app/cache/prod': Directory not empty

yang disebabkan oleh perintah berikut:

rm -rf $cache_dir/*

dimana $cache_dirdidefinisikan sebagaixxx/app/cache

Jadi saya melihatnya seperti: rmmenghapus semuanya dalam cache/proddir, lalu tepat sebelum mencoba untuk menghapus cache/proddirektori - program lain membuat file / direktori di dalamnya sehingga menyebabkan rmkegagalan.

Apakah asumsi saya benar?

zerkms
sumber
7
Asumsi Anda benar - rm -rbukan atom. Jika Anda ingin memastikan bahwa tidak ada lagi file yang dibuat di direktori saat rm -rfsedang berjalan, Anda bisa mengganti nama terlebih dahulu, lalu menghapus direktori yang diubah namanya.
Johnny
@ Johnny: ya, itulah yang sebenarnya sudah saya implementasikan :-)
zerkms
Meskipun itu pun tidak sepenuhnya aman. Jika suatu aplikasi saat ini beroperasi di luar direktori itu, itu hanya akan berjalan dengan bergerak dan tetap beroperasi secara normal.
Patrick
Ini tidak ada hubungannya dengan rm -rfmenjadi aman utas: jika Anda menjalankannya beberapa kali secara bersamaan di direktori yang sama, direktori tersebut akan dihapus. Ini tentang rm -rtidak menjadi atom.
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles: tergantung: "Sepotong kode aman untuk thread jika hanya memanipulasi struktur data bersama dengan cara yang menjamin eksekusi yang aman oleh banyak utas pada saat yang sama". Jadi jika kita menganggap "utas" sebagai rmdoa, kita dapat berbicara tentang keamanan utas. Tapi bagaimanapun, itu tidak mengubah apa pun
zerkms

Jawaban:

7

Pesan kesalahan yang diberikan adalah "Direktori tidak kosong" ( ENOTEMPTY), mengingat ini asumsi Anda terdengar benar, bahwa itu adalah kondisi ras di mana program membuat file di direktori itu sebelum rmmencoba untuk menghapus direktori, memberikan ENOTEMPTYkesalahan yang diharapkan dari yang mendasarinya rmdir(2).

CATATAN: Untuk berada di sisi aman Anda bisa memindahkan / mengganti nama direktori ke nama baru, dan kemudian jalankan penghapusan direktori ini.

slm
sumber
2
Jawaban ini salah, Anda dapat menghapus entri direktori bahkan ketika file sedang digunakan, dan kemudian menghapus direktori. Pengujian sederhana mkdir x; cat > x/a &; tail -f x/a &; rm -r xmenunjukkan bahwa direktori dapat dihapus bahkan ketika file sedang digunakan, terlepas dari apakah mereka terbuka untuk membaca atau menulis.
wingedsubmariner
1
Ya, file masih ada, tetapi ini tidak ada hubungannya dengan mengapa menghapus direktori tidak berhasil. Pernyataan ini dalam jawaban Anda secara khusus salah: "Sistem tidak akan menghapus direktori yang memiliki file di dalamnya yang dibuka dalam mode baca / tulis". Ada beberapa hal baik dalam jawaban Anda, hanya saja tidak berkaitan dengan pertanyaan :)
wingedsubmariner
1
Juga, berhati-hatilah untuk tidak membingungkan deskriptor file dengan file. Deskriptor file tidak pernah dihapus, hanya ditutup.
wingedsubmariner
1
Paragraf pertama Anda mungkin perlu beberapa pekerjaan juga. Anda benar tentang penghapusan file yang tidak terjadi ketika file masih terbuka, hanya saja begitu file telah dihapus tautannya dari direktori itu, mereka tidak mencegah direktori tersebut dihapus. Ya, ini berarti UNIX memungkinkan file ada yang tidak ada di direktori mana pun, seaneh yang tampak pada awalnya.
wingedsubmariner
1
Saya benar-benar hanya dapat memikirkan dua alasan mengapa penghapusan akan gagal, apakah intuisi OP benar dan file baru dibuat, atau itu adalah kesalahan izin. rmmengeluh tentang kesalahan izin, jadi saya pikir kita bisa menghilangkannya. Saya tidak cukup percaya diri untuk mengirim jawaban.
wingedsubmariner