Bagaimana rm -r pergi menghapus secara rekursif? Dalam urutan apa?

30

Apakah ada urutan operasi rm? Saya tampil rmdi direktori besar dan ingin tahu di mana saya harus melihat untuk melihat apa yang mungkin telah dihapus. Apakah rmbekerja pada file pertama, lalu direktori? Atau didasarkan pada beberapa informasi dalam tabel inode?

Spesifikasi: rm dari sistem GNU coreutils 8.22: Arch Linux yang berjalan pada sistem file beagleboneblack yang beroperasi adalah HDD Seagate eksternal (ext4) menggunakan USB 2.0.

Backstory:

Saya melakukan beberapa pembersihan direktori dan melakukan

cp -r A/ B/ C/ Dest/

Tanpa disadari, saya menindaklanjutinya

rm -r A/ B/ C/ Dest/

ketika saya bermaksud hanya melakukan

rm -r A/ B/ C/

Saya menangkap ini dan menekan Ctrl+ Csebelum terlalu lama berlalu. Secara khusus, itu <3 detik karena saya menggunakan timeperintah bersamaan dengan rm& cp. Saya masuk dan memeriksa bahwa Dest/itu tidak ada, tetapi lihatlah itu utuh dan tampaknya tidak terpengaruh. Ini agak mengejutkan karena A/ B/ C/cukup kecil. Mungkin total 100-200 MB. Dest/Namun, hanya malu 1TB. Melakukan lspada Dest / menunjukkan bahwa ada kedua file dan direktori di kedua ujung alfabet (misalnya AFile.txt.... .... Zoo.txt).

Apakah saya beruntung dan membatalkan rmsebelum terjadi malapetaka pada direktori Dest / saya? Apakah rmbenar-benar lambat (untungnya!)?

Jika tidak, bagaimana cara rmmenghilangkan hal-hal secara rekursif sehingga saya bisa menebak apa yang mungkin hilang?

Saya tidak benar-benar berharap untuk memulihkan apa yang mungkin hilang, hanya ingin tahu apa yang berpotensi terhempas.

N Klosterman
sumber

Jawaban:

34

rm -rbekerja pada masing-masing argumen pada gilirannya. Jika argumen adalah direktori, itu daftar direktori (dengan opendirdan readdirfungsi atau metode yang setara), dan beroperasi pada setiap entri secara bergantian. Jika sebuah entri adalah direktori, ia mengeksplorasi entri itu secara rekursif.

Ini adalah persis metode yang sama aplikasi lain gunakan untuk direktori melintasi rekursif - find, ls -Rf, dll

Urutan traversal tidak dapat diprediksi. Pada kebanyakan filesystem, urutan dapat direproduksi selama tidak ada file yang ditambahkan, dihapus, atau diganti namanya dalam direktori (urutannya secara teori bisa acak dan berubah setiap waktu, tetapi saya tidak bisa memikirkan sistem file di mana itu terjadi). Pada beberapa filesystem, urutan secara umum dapat disimpulkan dari nama file atau dari urutan di mana file dibuat atau kombinasi keduanya, tetapi Anda perlu mengetahui detail halus dari filesystem, dan itu dapat bervariasi tergantung pada versi driver. Urutan traversal bukanlah sesuatu yang bisa Anda andalkan.

Catat itu lsatau echo *lakukan sortir file dalam urutan leksikografis dari namanya. finddan ls -fjangan disortir.

Satu hal yang dapat Anda andalkan adalah bahwa argumen ditangani secara berurutan. Jadi, jika C/masih ada sebagian, itu berarti itu Dest/tidak tersentuh. Jika C/hilang, Anda dapat mengetahui di mana file telah dihapus Dest/dengan memeriksa waktu modifikasi direktori dan membandingkannya dengan waktu C/dihapus atau waktu salinan berakhir. File pertama yang akan dihapus bisa berupa file langsung di dalam Dest/atau di suatu tempat jauh di dalam hierarki tergantung pada apakah entri pertama Dest/yang rmkebetulan dilalui adalah direktori atau tidak.

Kecepatan rmsebagian besar masalah berapa banyak file yang ada untuk dihapus. Dibutuhkan file yang sangat besar untuk memiliki dampak nyata pada waktu penghapusan. Sebagian besar pekerjaan ini menghapus setiap entri direktori secara bergantian. Data file tidak terhapus, menghapus konten file hanya perlu menandai blok yang digunakan sebagai gratis, yang relatif cepat.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
2
The -fpilihan untuk lsdidokumentasikan sebagai setara dengan -aU, di mana -acara daftar semua file dan -Usarana unsorted. Saya samar-samar ingat menemukan versi lsdi mana -ftidak bekerja (saya pikir itu didefinisikan sebagai sesuatu yang lain) tetapi -aUberhasil.
G-Man Mengatakan 'Reinstate Monica'
2
@ G-Man POSIX mendefinisikan -f(sebagai ekstensi XSI ); memang memiliki efek lain di luar tidak disortir. Ini kembali ke V7, jadi Anda akan kesulitan menemukan implementasi tanpa terpisah dari, anehnya, BusyBox. -Ukarena hanya disortir adalah fitur GNU, saya tidak berpikir itu ada di tempat lain.
Gilles 'SANGAT berhenti menjadi jahat'
@Tim No. Anda dapat menguji dengan menjalankan ls -Udi direktori. Ini adalah urutan yang sama yang rm -rakan berfungsi di direktori itu. Perhatikan bahwa menambahkan atau menghapus file dapat mengubah urutan file lainnya.
Gilles 'SANGAT berhenti menjadi jahat'
Terima kasih. (1) "menambah atau menghapus file dapat mengubah urutan file lainnya.", Jadi setelah penghapusan sebagian secara tidak disengaja, ls -Utidak membantu untuk mengetahui apakah dir yang masih hidup tidak tersentuh? (2) -U berarti "daftar entri dalam urutan direktori". Apakah -U berarti urutan entri direktori dalam direktori?
Tim
5

Seperti yang dikatakan Gilles, Anda biasanya tidak dapat memprediksi urutan penghapusan dalam direktori, hanya saja direktori tingkat atas akan diproses dalam urutan pada baris perintah.

Namun, Anda juga dijamin akan menghapus hierarki direktori dari bawah ke atas, karena Unix hanya membolehkan direktori dihapus jika kosong. Jadi untuk menghapus direktori, pertama-tama harus menghapus semua yang ada di dalamnya. Jika berisi subdirektori, ia harus menghapus isinya terlebih dahulu, dan seterusnya.

Barmar
sumber