Mengapa mungkin menghapus seluruh sistem file?

24

Setelah melakukan kesalahan yang terkenal dengan menghapus seluruh sistem file saya melalui sudo rm -rf /*, memulihkan dari kerusakan mengerikan yang telah saya lakukan dan mengatasi kenyataan bahwa saya baru saja kehilangan 6 tahun dari masa hidup saya, saya mulai bertanya-tanya mengapa bahkan mungkin untuk melakukan itu, dan apa yang bisa dilakukan untuk mencegah kesalahan ini terjadi.

Salah satu solusi yang disarankan kepada saya adalah mencabut akses root dari akun saya, tetapi itu tidak nyaman, karena banyak perintah memerlukan akses root dan ketika Anda harus menjalankan beberapa lusin perintah setiap hari, itu menjadi menjengkelkan.

Mencadangkan sistem Anda adalah cara yang jelas untuk dilakukan. Tetapi mengembalikan cadangan juga memerlukan beberapa waktu henti, dan tergantung pada sistem Anda bahwa waktu henti itu bisa berhari-hari atau berminggu-minggu, yang mungkin tidak dapat diterima dalam beberapa kasus.

Pertanyaan saya adalah: Mengapa tidak menerapkan konfirmasi ketika pengguna mencoba menghapus sistem file mereka? Sehingga ketika Anda benar-benar ingin melakukan itu, Anda cukup menekan Y atau masuk, dan jika Anda tidak setidaknya Anda tidak kehilangan segalanya.

Mister_Fix
sumber
20
"Kenapa itu bisa dilakukan?" Mengapa should't itu mungkin? Ada alasan yang sangat baik untuk menghapus isi hierarki direktori, dan ada banyak himpunan bagian /yang hampir sama buruknya untuk dihapus ( /etc/, misalnya). Ini bukan tugas rmuntuk memutuskan direktori mana yang dapat atau tidak dapat dengan mudah dihapus.
chepner
2
Judul mengatakan "Mengapa mungkin menghapus sistem?" sedangkan pertanyaan itu sendiri bertanya "Pertanyaan saya adalah: Mengapa tidak menerapkan konfirmasi ketika pengguna mencoba menghapus sistem file mereka?". Jadi ini membuat pertanyaan tidak jelas. Yang mana pertanyaan aktual Anda sehingga kami setidaknya tahu harus menjawab apa? Harap edit pos Anda untuk menjelaskan
Sergiy Kolodyazhnyy
3
Apa sebenarnya pertanyaannya di sini? Saya dapat melihat tiga: (1) Mengapa itu mungkin? (2) Bagaimana mencegahnya ?, dan (3) Mengapa tidak menerapkan konfirmasi? - Mereka bukan pertanyaan yang sama, yang pertama meminta alasan, yang kedua untuk alat. (Yang ketiga terkait dengan yang kedua, tetapi masih belum benar-benar sama. Konfirmasi bukan satu-satunya cara untuk mencegah sesuatu.)
ilkkachu
10
Jika Anda tidak meminta klarifikasi dari penulis pertanyaan, mohon jangan berkomentar sama sekali . Saya melihat banyak komentar selamat sendiri di sini, menjelaskan bagaimana ini adalah kesalahan OP karena tidak tahu apa arti bendera, atau karena tidak memiliki cadangan atau apa pun. Saya sangat senang mengetahui bahwa begitu banyak pengguna kami cukup bijak untuk memiliki cadangan dan tidak menjalankan perintah yang tidak mereka mengerti. Itu benar-benar hebat bagi mereka, tetapi pada dasarnya tidak membantu OP yang, mungkin, juga telah mempelajari pelajaran ini sekarang. Jadi mari kita berhenti berjemur dalam kecemerlangan kita sendiri dan jawab saja pertanyaannya.
terdon

Jawaban:

16

rmadalah alat sistem tingkat rendah. Alat-alat ini dibangun sesederhana mungkin karena harus ada pada sistem apa pun. rmdiharapkan memiliki perilaku terkenal, terutama yang berkaitan dengan konfirmasi konfirmasi sehingga dapat digunakan dalam skrip.

Menambahkan kasus khusus ke prompt rm /*tidak akan mungkin karena perintah rm tidak melihatnya dalam formulir ini. The *wildcard diperluas oleh shell sebelum dilewatkan ke rm, sehingga perintah yang sebenarnya yang membutuhkan kasus khusus akan menjadi sesuatu seperti rm /bin /boot /dev /etc /home /initrd.img /lib /lib64 /lost+found /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var /vmlinuz. Menambahkan kode untuk memeriksa kasus ini (yang mungkin akan berbeda pada linux yang berbeda) akan menjadi tantangan yang kompleks serta rentan terhadap kesalahan halus. Linux standar rmmemang memiliki perlindungan default terhadap kerusakan sistem dengan menolak untuk menghapus /tanpa --no-preserve-rootopsi.

Secara default ada tiga perlindungan terhadap penghapusan sistem Anda dengan cara ini:

  1. Izin - pengguna biasa tidak akan dapat menghapus file penting. Anda melewati ini dengan sudo
  2. Direktori - secara default rm tidak akan menghapus direktori. Anda melewati ini dengan flag -r
  3. File yang dilindungi tulis - secara default, rm akan meminta konfirmasi sebelum menghapus file yang dilindungi tulis (ini tidak akan menghentikan semua kerusakan, tetapi mungkin telah memberikan prompt sebelum sistem menjadi tidak dapat dipulihkan). Anda melewati perlindungan ini dengan flag -f

Untuk menghapus semua isi folder, daripada menjalankan rm /path/to/folder/*, lakukan rm -rf /path/to/folder, maka mkdir /path/to/folderkarena ini akan memicu --preserve-rootperlindungan serta menghapus dotfile dalam folder

Rhellen
sumber
3
"rm diharapkan memiliki perilaku yang terkenal" dan ini sebenarnya adalah salah satu alat yang ditentukan oleh standar POSIX. "he * wildcard diperluas oleh shell sebelum diteruskan ke rm" Tepatnya, jadi menambahkan pemeriksaan untuk semua jenis parameter, yang mungkin merupakan symlink ke direktori dan file aktual /akan membutuhkan banyak kombinasi dan pertimbangan, jadi itu tidak praktis. Dan kembali ke gagasan standar, menambahkan pemeriksaan seperti itu akan merusak perilaku yang konsisten
Sergiy Kolodyazhnyy
Itulah tepatnya mengapa safe-rmpembungkus rm: Dengan cara ini ia dapat memeriksa setiap argumen (alih-alih seluruh baris perintah acak), verifikasi itu tidak ada dalam daftar hitam yang dapat dikonfigurasi dan hanya kemudian memanggil rmdengan argumen yang diverifikasi. Itu tidak terlalu kompleks atau rentan terhadap kesalahan.
hidangan penutup
59

Meet safe-rmInstal safe-rm, "wrapper around the rmcommand untuk mencegah penghapusan yang tidak disengaja":

safe-rm mencegah penghapusan file penting secara tidak disengaja dengan mengganti rmdengan pembungkus yang memeriksa argumen yang diberikan terhadap daftar hitam file dan direktori yang dapat dikonfigurasi yang tidak boleh dihapus.

Pengguna yang mencoba menghapus salah satu file atau direktori yang dilindungi ini tidak akan dapat melakukannya dan akan ditampilkan pesan peringatan. ( man safe-rm)

Jika tautan instalasi di atas tidak berfungsi untuk Anda gunakan sudo apt install safe-rmsaja. Konfigurasi default sudah berisi direktori sistem, mari kita coba rm /*misalnya:

$ rm /*
safe-rm: skipping /bin
safe-rm: skipping /boot
safe-rm: skipping /dev
safe-rm: skipping /etc
safe-rm: skipping /home
safe-rm: skipping /lib
safe-rm: skipping /proc
safe-rm: skipping /root
safe-rm: skipping /sbin
safe-rm: skipping /sys
safe-rm: skipping /usr
safe-rm: skipping /var
…

Seperti yang Anda lihat, ini akan mencegah Anda menghapus /home, di mana saya kira file pribadi Anda disimpan. Namun, itu tidak mencegah Anda menghapus ~atau salah satu subdirektori jika Anda mencoba menghapusnya secara langsung. Untuk menambahkan ~/precious_photosdirektori cukup tambahkan path absolutnya dengan tilde diselesaikan ke safe-rmfile konfigurasi /etc/safe-rm.conf, misalnya:

echo /home/dessert/precious_photos | sudo tee -a /etc/safe-rm.conf

Untuk kasus-kasus di mana Anda menjalankan rmtanpa sudo1 dan -fbendera itu ide yang baik untuk menambahkanalias untuk shell Anda yang merek rm's -ibendera default. Dengan cara ini rmmeminta setiap file sebelum menghapusnya:

alias rm='rm -i'

Bendera yang sama bermanfaatnya adalah -I, hanya itu hanya memperingatkan "sekali sebelum menghapus lebih dari tiga file, atau ketika menghapus secara rekursif", yang "kurang mengganggu daripada -i, sambil tetap memberikan perlindungan terhadap sebagian besar kesalahan":

alias rm='rm -I'

Bahaya umum dari alias ini adalah bahwa Anda dengan mudah membiasakan diri untuk menyelamatkan Anda, yang mungkin menjadi bumerang buruk ketika menggunakan lingkungan yang berbeda.


1: sudoabaikan alias , satu dapat bekerja di sekitar bahwa dengan mendefinisikan alias sudo='sudo 'meskipun

pencuci mulut
sumber
25

Konfirmasi sudah ada, masalahnya ada -fdi perintah, yaitu --force; Ketika pengguna memaksa operasi, mereka seharusnya tahu apa yang mereka lakukan (jelas kesalahan selalu bisa ditambahkan).

Sebuah contoh:

 rm -r ./*
 rm: remove write-protected regular file './mozilla_mvaschetto0/WEBMASTER-04.DOC'? N
 rm: cannot remove './mozilla_mvaschetto0': Directory not empty
 rm: descend into write-protected directory './pulse-PKdhtXMmr18n'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-bolt.service-rZWMCb'? n
 rm: descend into write-protected directory './systemd-private-     890f5b31987b4910a579d1c49930a591-colord.service-4ZBnUf'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-fwupd.service-vAxdbk'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-minissdpd.service-9G8GrR'? 
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-ModemManager.service-s43zUX'? nn
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-rtkit-daemon.service-cfMePv'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-systemd-timesyncd.service-oXT4pr'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-upower.service-L0k9rT'? n

Ini berbeda dengan --forceopsi: Saya tidak akan mendapatkan konfirmasi dan file dihapus.

Masalahnya adalah untuk mengetahui perintah dan parameternya, bernavigasi lebih dalam pada manperintah (juga jika perintah ditemukan dalam tutorial) untuk contoh: pertama kali saya melihat perintah tar xzf some.tar.gzsaya bertanya pada diri sendiri, "apa xzfartinya? "

Kemudian saya membaca halaman manual tar dan menemukannya.

AtomiX84
sumber
Saya tidak berpikir itu relevan di sini. Pada titik di mana pertama kali rm meminta file yang dilindungi tulis atau apa pun, file itu mungkin sudah menghapus sejumlah besar file penting.
Jonas Schäfer
1
Jadi secara pribadi, saya selalu berpikir -fdiperlukan untuk menghapus folder. Saya bahkan membuka prompt untuk mengkonfirmasi dan mengeluh tetapi mengetahui bahwa hanya -rdiperlukan. Saya kira rm -rftelah menjadi norma karena sangat berguna dalam sebuah skrip (Anda tidak ingin skrip gagal hanya karena Anda mencoba menghapus hal-hal yang tidak ada) sehingga Anda sering melihatnya, tetapi saya kira kita perlu untuk waspada hanya menggunakan rm -rsebagai "default" kami ketika dalam sebuah shell (dapat dimengerti seharusnya tidak ada asumsi "default" yang tidak Anda mengerti, terutama dengan sudo, tetapi orang-orang akan menjadi orang dan setidaknya ini lebih aman).
Kapten Man
2
Rmdir adalah cara paling aman untuk menghapus folder
AtomiX84
rmtidak meminta konfirmasi secara default, hanya meminta direktori dan file yang dilindungi tulis. Jika Anda menjalankan perintah itu di komputer Anda, Anda mungkin menghapus banyak file Anda sendiri. Jika Anda perlu rmmeminta konfirmasi, Anda harus melewati -iparameter. Misalnya:rm -ir ./*
Dan
8

Berjalan tanpa cadangan berarti Anda harus sangat berhati-hati untuk tidak pernah melakukan kesalahan. Dan semoga perangkat keras Anda tidak pernah gagal. (Bahkan RAID tidak dapat menyelamatkan Anda dari kerusakan sistem file yang disebabkan oleh RAM yang rusak.) Jadi itulah masalah pertama Anda. (Yang saya anggap sudah Anda sadari dan akan melakukan backup di masa depan.)


Tetapi ada beberapa hal yang dapat Anda lakukan untuk mengurangi kemungkinan kesalahan seperti ini:

  • alias rm='rm -I'untuk meminta jika menghapus lebih dari 3 hal.
  • alias mv dan cp ke mv -idan cp -i(banyak kasus penggunaan normal untuk ini tidak melibatkan menimpa file tujuan).
  • alias sudo='sudo 'melakukan ekspansi alias pada argumen pertama kesudo

Saya menemukan rm -Ijauh lebih bermanfaat daripada rm -i. Ini biasanya tidak meminta selama penggunaan normal, jadi tetting diminta ketika Anda tidak berharap itu jauh lebih terlihat / peringatan yang lebih baik. Dengan -i(sebelum saya temukan -I), saya terbiasa mengetik \rmuntuk menonaktifkan ekspansi alias, setelah yakin saya mengetik perintah dengan benar.

Anda tidak ingin terbiasa mengandalkan rm -iatau -Ialias untuk menyelamatkan Anda . Itu adalah garis pengaman Anda yang Anda harap tidak pernah digunakan. Jika saya benar-benar ingin secara interaktif memilih yang cocok untuk dihapus, atau saya tidak yakin apakah glob saya cocok dengan beberapa file tambahan, saya mengetik secara manual rm -i .../*whatever*. (Juga kebiasaan yang baik jika Anda pernah berada di lingkungan tanpa alias Anda).

Bertahanlah dari meraba-raba Enterdengan mengetik ls -d /*foo*terlebih dahulu , lalu panah atas dan ubah itu menjadi rm -rsetelah Anda selesai mengetik. Jadi baris perintah tidak pernah berisi rm -rf ~/atau perintah berbahaya serupa di titik mana pun. Anda hanya "mempersenjatai" itu dengan mengubah lske rmdengan kontrol-a, alt-d untuk pergi ke awal baris dan menambahkan -ratau -fsetelah Anda selesai mengetik ~/some/sub/dir/bagian dari perintah.

Bergantung pada apa yang Anda hapus, jalankan yang ls -dpertama, atau tidak jika itu tidak menambah apa pun yang Anda lihat dengan penyelesaian-tab. Anda mungkin mulai dengan rm(tanpa -ratau -rf) jadi itu hanya control-a / control-right (atau alt + f) / space / -r.

(Biasakan untuk mem-bind / readbind mengedit keybindings kuat untuk bergerak dengan cepat, seperti panah kontrol atau alt + f / b untuk bergerak dengan kata-kata, dan membunuh seluruh kata dengan alt + backspace atau alt + d, atau control-w. Dan kontrol -u untuk membunuh ke awal baris. Dan control- / untuk membatalkan edit jika Anda melangkah terlalu jauh. Dan tentu saja panah atas sejarah yang dapat Anda cari dengan control-r / control-s.)

Hindari -rfkecuali Anda benar - benar membutuhkannya untuk membungkam diminta tentang menghapus file read-only.

Luangkan waktu ekstra untuk berpikir sebelum menekan return on a sudocommand. Terutama jika Anda tidak memiliki cadangan lengkap, atau sekarang akan menjadi waktu yang buruk untuk mengembalikannya.

Peter Cordes
sumber
6

Yah jawaban singkatnya adalah tidak menjalankan perintah seperti itu.

Ceritanya adalah bagian dari penyesuaian. Pada dasarnya ada dua faktor yang berperan di sini. Salah satunya adalah kenyataan bahwa Anda bebas untuk memodifikasi semua file.

Yang kedua adalah bahwa perintah rm menawarkan gula sintaksis yang bermanfaat untuk menghapus semua file di bawah folder.

Secara efektif ini dapat dinyatakan kembali sebagai prinsip sederhana dari mesin Unix. Semuanya adalah file . Untuk membuat masalah lebih baik, ada kontrol akses, tetapi ini ditimpa oleh penggunaan Anda

sudo

Saya kira Anda bisa menambahkan alias atau fungsi untuk memastikan bahwa ini tidak pernah dapat dijalankan.

HaoZeke
sumber
4

Jika penggunaan ruang file sistem Anda tidak besar (dan hari ini 'luar biasa' berarti 'ratusan gigabyte atau lebih') buat beberapa mesin virtual, dan selalu bekerja di dalamnya. Pemulihan hanya akan memerlukan menggunakan instance cadangan.

Atau Anda bisa membuat chroot jail, dan bekerja di dalamnya. Anda masih memerlukan beberapa pemulihan jika dibuang, tetapi itu akan lebih mudah dengan sistem yang berjalan (melampirkan) untuk bekerja.

Loren Rosen
sumber
Ini mungkin jawaban yang paling efektif, karena dapat melindungi dari kerusakan, bahkan skrip pihak ketiga. Anda hanya perlu khawatir tentang malware yang sebenarnya.
PyRulez
Memikirkan sudut lain. Ada baiknya bertanya mengapa Anda perlu melakukan penghapusan rekursif di tempat pertama. Mungkin yang benar-benar diperlukan adalah beberapa skrip untuk menghapus proyek, dll.
Loren Rosen
"Perlu ditanyakan mengapa kamu harus melakukan penghapusan rekursif sejak awal." Yah, hanya karena tidak ada perintah built in tidak berarti Anda masih tidak dapat membuat kesalahan. Skrip pihak ketiga mungkin menghapus file satu per satu dari beberapa direktori. Dan ada cara lain untuk merusak sistem yang hanya menyentuh satu file. Namun, mengganti rmdengan safe-rmmembantu, setidaknya.
PyRulez
Gagasan saya dengan skrip adalah bahwa ia akan memiliki gagasan bawaan tentang 'proyek' atau serupa. Mungkin Anda akan memiliki file kosong di root proyek yang disebut .project_root, atau, jika sistem file mendukungnya, atribut pada direktori itu sendiri. Kemudian, skrip akan naik pohon file mencari root proyek, dan mengeluh itu direktori saat ini tidak ada dalam proyek. Atau, jika semua proyek tinggal di tempat yang sama, skrip dapat meminta Anda menyebutkan nama proyek. Anda masih dapat menghapus proyek yang salah, tetapi tidak menghancurkan seluruh sistem.
Loren Rosen
... juga, varian chrootakan menggunakan sesuatu seperti Docker (yang saya pikir sebenarnya menggunakan di chrootbawah selimut). Untuk file lain yang hanya perlu Anda baca, pasang sistem file read-only.
Loren Rosen
3

rmadalah perintah Unix yang sangat tua dan kemungkinan tidak dirancang dengan ramah pengguna. Ia mencoba melakukan dengan tepat apa yang diminta, ketika ia memiliki izin. Jebakan bagi banyak pengguna baru adalah mereka sering melihat kode dengan sudodan tidak banyak berpikir tentang menggunakannya. Fungsi yang langsung mengubah file seperti rm, dd, chroot, dll memerlukan perawatan yang ekstrim digunakan.

Saat ini saya suka menggunakan trash(tanpa sudo) dari trash-cli . Berfungsi seperti Recycle Bin dari Windows, di mana Anda dapat dengan mudah mengambil file yang terhapus secara tidak sengaja. Ubuntu sudah memiliki folder Trash dan fungsionalitas pindah-ke-sampah yang dibangun ke dalam File.

Bahkan kemudian Anda mungkin membuat kesalahan jadi pastikan untuk membuat cadangan seluruh sistem file Anda.

qwr
sumber