Bagaimana saya mencegah rm -rf / * yang tidak disengaja?


164

Saya hanya berlari rm -rf /*secara tidak sengaja, tapi maksud saya rm -rf ./*(perhatikan bintang setelah tebasan).

alias rm='rm -i'dan --preserve-rootsecara default tidak menyelamatkan saya, jadi apakah ada perlindungan otomatis untuk ini?


Saya tidak melakukan root dan membatalkan perintah dengan segera, tetapi ada beberapa izin santai di suatu tempat atau sesuatu karena saya perhatikan bahwa Bash prompt saya sudah putus. Saya tidak ingin mengandalkan izin dan tidak menjadi root (saya bisa membuat kesalahan yang sama dengan sudo), dan saya tidak ingin mencari bug misterius karena ada satu file yang hilang di suatu tempat dalam sistem, jadi, backup dan sudobagus , tapi saya ingin sesuatu yang lebih baik untuk kasus khusus ini.


Tentang berpikir dua kali dan menggunakan otak. Sebenarnya saya menggunakannya! Tapi saya menggunakannya untuk menyelesaikan beberapa tugas pemrograman kompleks yang melibatkan 10 hal berbeda. Saya tenggelam dalam tugas ini cukup dalam, tidak ada kekuatan otak yang tersisa untuk memeriksa bendera dan jalur, saya bahkan tidak berpikir dalam hal perintah dan argumen, saya pikir dalam hal tindakan seperti 'direktori kosong saat ini', bagian yang berbeda dari otak saya menerjemahkannya ke perintah dan terkadang membuat kesalahan. Saya ingin komputer memperbaikinya, setidaknya yang berbahaya.


13
FYI, Anda juga dapat melakukan rm -rf . /mydiralih - alih rm -rf ./mydirdan membunuh direktori apa pun yang Anda masuki. Saya menemukan ini terjadi lebih sering.
user606723

27
Untuk menggunakan analogi senjata, pertanyaan ini mengatakan tolong buat pistol mengenali bahwa saya membidik kaki saya dan tidak menembak, tetapi saya tidak ingin memiliki tanggung jawab untuk tidak mengarahkan senjata ke kaki saya. Senjata, dan komputer, bodoh dan jika Anda melakukan hal bodoh maka Anda akan mendapatkan hasil ini. Mengikuti analogi senjata, tidak ada yang bisa mencegah Anda melukai diri sendiri kecuali kewaspadaan dan latihan.
slillibri

73
@ Slillibri Kecuali itu rmbukan pistol, ini adalah program komputer, bisa jadi cukup pintar untuk menentukan bahwa pengguna akan menghapus beberapa file penting dan mengeluarkan peringatan (seperti yang sebenarnya terjadi jika Anda mencoba melakukannya rm -rf /tanpa bintang).
Valentin Nemcev

80
@slillibri Guns punya pengaman. Bertanya bagaimana cara menempatkan pengaman yang lebih baik pada rmperintah adalah pertanyaan sysadmin yang sah.
Gilles

21
sudo rm / bin / rm tidak direkomendasikan, tetapi akan mencegah sebagian besar rm :-)
Paul

Jawaban:


220

Salah satu trik yang saya ikuti adalah memasukkannya #di awal sambil menggunakan rmperintah.

root@localhost:~# #rm -rf /

Ini mencegah eksekusi tidak sengaja rmpada file / direktori yang salah. Setelah diverifikasi, hapus #dari awal. Trik ini berfungsi, karena dalam Bash, sebuah kata yang dimulai dengan #menyebabkan kata itu dan semua karakter yang tersisa pada baris itu diabaikan. Jadi perintah itu diabaikan begitu saja.

ATAU

Jika Anda ingin mencegah direktori penting, ada satu trik lagi.

Buat file dengan nama -idalam direktori itu. Bagaimana bisa file aneh seperti itu dibuat? Menggunakan touch -- -iatautouch ./-i

Sekarang coba rm -rf *:

sachin@sachin-ThinkPad-T420:~$ touch {1..4}
sachin@sachin-ThinkPad-T420:~$ touch -- -i
sachin@sachin-ThinkPad-T420:~$ ls
1  2  3  4  -i
sachin@sachin-ThinkPad-T420:~$ rm -rf *
rm: remove regular empty file `1'? n
rm: remove regular empty file `2'? 

Di sini *akan berkembang -ike baris perintah, sehingga akhirnya perintah Anda menjadi rm -rf -i. Dengan demikian perintah akan meminta sebelum dihapus. Anda dapat meletakkan file ini dalam /, /home/, /etc/, dll

ATAU

Gunakan --preserve-rootsebagai opsi untuk rm. Dalam paket yang rmtermasuk dalam coreutilspaket yang lebih baru , opsi ini adalah default.

--preserve-root
              do not remove `/' (default)

ATAU

Gunakan safe-rm

Kutipan dari situs web:

Safe-rm adalah alat keamanan yang dimaksudkan untuk mencegah penghapusan file penting secara tidak disengaja dengan mengganti / bin / rm dengan 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:

$ rm -rf /usr
Skipping /usr

10
safe-rm terlihat sangat bagus, sekarang sedang mencari ...
Valentin Nemcev

45
safe-rm rapi. Juga itu trik bagus dengan -ifile. Hah. Pesta konyol.
EricR

5
Hebat apa tipu daya dilakukan di unix.
WernerCD

4
File yang dibuat bernama -i benar-benar jenius. Saya bisa menggunakannya sekitar setahun yang lalu ketika saya secara tidak sengaja menjalankan rm -rf / etc / * di VPS ... (untungnya, saya mengambil snapshot malam, sehingga dapat memulihkan dalam waktu kurang dari 45 menit).
David W

9
Itu jenius. Sihir akan menjaditouch -- -rf
Mircea Vutcovici

46

Masalahmu:

Saya hanya menjalankan rm -rf / * secara tidak sengaja, tapi maksud saya rm -rf ./* (perhatikan bintang setelah tebasan).

Solusinya: Jangan lakukan itu! Sebagai praktik, jangan gunakan ./di awal jalan. Garis miring tidak menambah nilai perintah dan hanya akan menyebabkan kebingungan.

./*artinya sama dengan *, jadi perintah di atas lebih baik ditulis sebagai:

rm -rf *

Inilah masalah terkait. Saya sering melihat ungkapan berikut, di mana seseorang menganggap itu FOOdiatur ke sesuatu seperti /home/puppies. Saya melihat ini hanya hari ini sebenarnya, dalam dokumentasi dari vendor perangkat lunak utama.

rm -rf $FOO/

Tetapi jika FOOtidak disetel, ini akan dievaluasi rm -rf /, yang akan berusaha menghapus semua file di sistem Anda. Garis miring tidak perlu, jadi karena soal latihan jangan menggunakannya.

Hal berikut ini akan melakukan hal yang sama, dan kecil kemungkinannya merusak sistem Anda:

rm -rf $FOO

Saya sudah belajar tips ini dengan cara yang sulit. Ketika saya memiliki akun pengguna super pertama saya 14 tahun yang lalu, saya secara tidak sengaja berlari rm -rf $FOO/dari dalam shell script dan menghancurkan sebuah sistem. Keempat sysadmin lainnya melihat ini dan berkata, 'Yup. Setiap orang melakukannya sekali. Sekarang, ini media instal Anda (36 floppy disk). Perbaiki itu. '

Orang lain di sini merekomendasikan solusi seperti --preserve-rootdan safe-rm. Namun, solusi ini tidak ada untuk semua varian Un * xe dan mungkin tidak berfungsi pada Solaris, FreeBSD & MacOSX. Selain itu, safe-rmmengharuskan Anda menginstal paket tambahan di setiap sistem Linux yang Anda gunakan. Jika Anda mengandalkan safe-rm, apa yang terjadi ketika Anda memulai pekerjaan baru dan mereka belum safe-rmmenginstal? Alat-alat ini adalah penopang, dan jauh lebih baik untuk mengandalkan default yang diketahui dan meningkatkan kebiasaan kerja Anda.


19
Teman saya bilang dia tidak pernah menggunakan rm -rf *. Dia selalu mengubah direktori terlebih dahulu, dan menggunakan target tertentu. Alasannya adalah bahwa dia banyak menggunakan sejarah shell, dan dia khawatir bahwa memiliki perintah seperti itu dalam sejarahnya mungkin muncul pada waktu yang salah.
haggai_e

@haggai_e: Tip yang bagus. Ketika saya masih baru di Unix, saya pernah berlari ke bug di mana rm -rf *juga dihapus .dan ... Saya adalah root, dan ini melintasi direktori yang lebih rendah seperti ../../.., dan sangat destruktif. Saya berusaha sangat berhati-hati rm -rf *sejak saat itu.
Stefan Lasiewski

2
rm -rf $FOOtidak akan membantu jika Anda perlu rm -rf $FOO/$BAR. cd $FOO && rm -rf $BARakan membantu, meskipun jauh lebih lama.
Victor Sergienko

5
@ Viktorergienko, dengan bash, bagaimana dengan menentukan ${FOO:?}, seperti dalam rm -rf ${FOO:?}/dan rm -rf ${FOO:?}/${BAR:?}. Ini akan mencegahnya dari menerjemahkan rm -rf /. Saya punya beberapa info tentang ini dalam jawaban saya di sini .
Acumenus

@haggai_e: Saya menemukan ini salah satu saran terbaik tentang topik ini. Saya membakar jari saya dengan menggunakan rm -rf *for for yang berubah secara tidak sengaja ke direktori yang salah dan akhirnya menghapus sesuatu yang lain. Jika saya akan menggunakan target tertentu, itu akan memiliki peluang jauh lebih kecil untuk menghapus hal yang salah.
richk

30

Karena ini di "Serverfault", saya ingin mengatakan ini:

Jika Anda memiliki lusinan atau lebih server, dengan tim admin / pengguna yang besar, seseorang akan rm -rfatau chownsalah direktori.

Anda harus memiliki rencana untuk membuat cadangan layanan yang terpengaruh dengan MTTR seminimal mungkin.


4
Dan Anda harus menggunakan VM atau kotak cadangan untuk mempraktikkan pemulihan - cari tahu apa yang tidak berhasil dan sempurnakan rencana tersebut. Kami masuk ke reboot dua minggu - karena ada pemadaman listrik di gedung kami, dan setiap kali itu menyakitkan. DENGAN melakukan beberapa penutupan yang direncanakan dari semua rak, kami telah memotongnya dari beberapa hari berlarian menjadi sekitar 3 jam sekarang - setiap kali kami belajar bit mana yang akan mengotomatiskan / memperbaiki skrip init.d untuk dll.
Danny Staple

Dan coba perintah ini pada VM. Ini menarik! Tapi ambil snapshot dulu.
Stefan Lasiewski

23

Solusi terbaik melibatkan mengubah kebiasaan Anda agar tidak digunakan rmsecara langsung.

Salah satu pendekatan adalah menjalankan echo rm -rf /stuff/with/wildcards*terlebih dahulu. Periksa apakah output dari wildcard terlihat masuk akal, kemudian gunakan riwayat shell untuk mengeksekusi perintah sebelumnya tanpa echo.

Pendekatan lain adalah membatasi echoperintah untuk kasus-kasus di mana sangat jelas apa yang akan Anda hapus. Daripada menghapus semua file dalam direktori, hapus direktori dan buat yang baru. Metode yang baik adalah mengubah nama direktori yang ada menjadi DELETE-foo, kemudian membuat direktori baru foodengan izin yang sesuai, dan akhirnya menghapus DELETE-foo. Manfaat samping dari metode ini adalah bahwa perintah yang dimasukkan dalam riwayat Anda adalah rm -rf DELETE-foo.

cd ..
mv somedir DELETE-somedir
mkdir somedir                 # or rsync -dgop DELETE-somedir somedir to preserve permissions
ls DELETE-somedir             # just to make sure we're deleting the right thing
rm -rf DELETE-somedir

Jika Anda benar-benar bersikeras menghapus banyak file karena Anda memerlukan direktori untuk tetap (karena itu harus selalu ada, atau karena Anda tidak akan memiliki izin untuk membuatnya kembali), pindahkan file ke direktori yang berbeda, dan hapus direktori itu. .

mkdir ../DELETE_ME
mv * ../DELETE_ME
ls ../DELETE_ME
rm -rf ../DELETE_ME

(Tekan tombol Alt+ itu ..)

Menghapus direktori dari dalam akan menarik, karena rm -rf .pendek maka risiko typosnya rendah. Sayangnya, sistem tipikal tidak membiarkan Anda melakukan itu. Anda dapat melakukannya rm -rf -- "$PWD"sebagai gantinya, dengan risiko kesalahan pengetikan yang lebih tinggi tetapi kebanyakan dari mereka tidak menghapus apa pun. Berhati-hatilah karena ini meninggalkan perintah berbahaya dalam riwayat shell Anda.

Kapan pun Anda bisa, gunakan kontrol versi. Anda tidak rm, Anda cvs rmatau apa pun, dan itu tidak dapat diurungkan.

Zsh memiliki opsi untuk meminta Anda sebelum menjalankan rmdengan argumen yang mencantumkan semua file dalam direktori: rm_star_silent(diaktifkan secara default) meminta sebelum mengeksekusi rm whatever/*, dan rm_star_wait(dinonaktifkan secara default) menambahkan penundaan 10 detik yang tidak dapat Anda konfirmasi. Ini adalah penggunaan terbatas jika Anda bermaksud untuk menghapus semua file di beberapa direktori, karena Anda sudah akan mengharapkan prompt. Hal ini dapat membantu mencegah kesalahan ketik seperti rm foo *untuk rm foo*.

Ada banyak solusi yang beredar yang melibatkan mengubah rmperintah. Keterbatasan pendekatan ini adalah bahwa suatu hari Anda akan berada di mesin dengan yang asli rmdan Anda akan secara otomatis memanggil rm, aman dengan harapan Anda akan konfirmasi ... dan selanjutnya Anda akan memulihkan cadangan.


mv -t DELETE_ME -- *sedikit lebih mudah.
Tobu

@ Giles Tidak menggunakan rmsecara langsung adalah saran yang bagus! Alternatif yang lebih baik lagi adalah menggunakan findperintah .
aculich

Dan jika Anda memerlukan direktori untuk tetap, Anda dapat melakukannya dengan cukup sederhana dengan menggunakan find somedir -type f -deleteyang akan menghapus semua file somedirtetapi akan meninggalkan direktori dan semua subdirektori.
aculich

19

Anda selalu dapat melakukan alias, seperti yang Anda sebutkan:

what_the_hell_am_i_thinking() {
   echo "Stop." >&2
   echo "Seriously." >&2
   echo "You almost blew up your computer." >&2
   echo 'WHAT WERE YOU THINKING!?!?!' >&2
   echo "Please provide an excuse for yourself below: " 
   read 
   echo "I'm sorry, that's a pathetic excuse. You're fired."
   sleep 2
   telnet nyancat.dakko.us
}

alias rm -fr /*="what_the_hell_am_i_thinking"

Anda juga dapat mengintegrasikannya dengan klien twitter commandline untuk memberi tahu teman Anda tentang bagaimana Anda hampir mempermalukan diri sendiri dengan menghapus hard disk Anda dengan rm -fr /*sebagai root.


3
+1 untuk telnet miku.acm.uiuc.edu
Ali

1
alias echo = "telnet miku.acm.uiuc.edu"
kubanczyk

Saya tidak boleh cukup tua ... apa pentingnya telnet miku.acm.uiuc.edu?
Kyle Strand

Cobalah dan cari tahu. Itu tidak merusak. Jika Anda paranoid seperti seharusnya, jalankan dalam VM.
Naftuli Kay

3
-1 Anda tidak dapat alias perintah dengan spasi di dalamnya apalagi / * yang merupakan nama tidak valid
xenithorb


15

Cara paling sederhana untuk mencegah kecelakaan rm -rf /*adalah dengan menghindari semua penggunaan rmperintah! Bahkan, saya selalu tergoda untuk lari rm /bin/rmuntuk menyingkirkan perintah sepenuhnya! Tidak, saya tidak bercanda.

Alih-alih menggunakan -deleteopsi findperintah , tetapi terlebih dahulu sebelum menghapus file, saya sarankan melihat dulu file apa yang akan Anda hapus:

find | less

Catatan, dalam versi modern findjika Anda meninggalkan nama direktori, itu akan secara implisit menggunakan direktori saat ini, jadi di atas adalah setara dengan:

find . | less

Setelah Anda yakin ini adalah file yang ingin Anda hapus, Anda dapat menambahkan -deleteopsi:

find path/to/files -delete

Jadi, tidak hanya find lebih aman untuk digunakan, itu juga lebih ekspresif , jadi jika Anda ingin menghapus hanya file tertentu dalam hierarki direktori yang cocok dengan pola tertentu Anda bisa menggunakan ekspresi seperti ini untuk melihat dulu, lalu hapus file-file:

find path/to/files -name '*~' | less
find path/to/files -name '*~' -delete

Ada banyak alasan bagus untuk belajar dan menggunakan findselain lebih aman rm, jadi Anda akan berterima kasih pada diri sendiri nanti jika Anda meluangkan waktu untuk belajar menggunakannya find.


Diskusi yang sangat menarik. Saya suka pendekatan Anda dan membuat cuplikan kecil. Ini sangat tidak efisien, karena panggilannya menemukan paling banyak 3 kali, tetapi bagi saya ini adalah awal yang bagus: github.com/der-Daniel/fdel
Daniel Hitzel

14

Ada beberapa saran yang sangat buruk di utas ini, untungnya sebagian besar telah ditolak.

Pertama-tama, ketika Anda perlu menjadi root, menjadi root-sudo dan berbagai trik alias akan membuat Anda lemah. Dan lebih buruk lagi, mereka akan membuat Anda ceroboh. Belajarlah untuk melakukan hal-hal dengan cara yang benar, berhenti bergantung pada alias untuk melindungi Anda. Suatu hari Anda akan mendapatkan root pada kotak yang tidak memiliki roda pelatihan Anda dan meledakkan sesuatu.

Kedua - ketika Anda memiliki root, anggap diri Anda mengendarai bus yang penuh dengan anak-anak sekolah. Kadang-kadang Anda bisa mendengarkan lagu di radio, tetapi di lain waktu Anda harus melihat kedua arah, memperlambat segalanya, dan memeriksa ulang semua cermin Anda.

Ketiga - Anda hampir tidak pernah benar - benar harus rm -rf- lebih mungkin Anda mau mv something something.bakataumkdir _trash && mv something _trash/

Keempat - selalu lswildcard Anda sebelumnya rm- Tidak ada yang gila melihat sesuatu sebelum menghancurkannya selamanya.


2
+1 untuk penggunaan ls.
Sachin Divekar

@eventi Saya setuju bahwa ada beberapa saran buruk dan peretasan buruk di utas ini. Dan jelas merupakan ide yang bagus untuk melihat sesuatu sebelum menghancurkannya, tetapi ada cara yang lebih baik untuk melakukannya menggunakan findperintah .
aculich

Saya gagal melihat bagaimana menemukan itu lebih sederhana atau lebih aman, tapi saya suka find . -name '*~'contoh Anda . Maksud saya adalah bahwa lsakan mencantumkan glob yang sama yang rmakan digunakan.
eventi

11

Ini adalah standar milik saya khusus untuk regexps dalam konteks rm, tetapi akan menyelamatkan Anda dalam kasus ini.

Saya selalu melakukan yang echo foo*/[0-9]*{bar,baz}*pertama, untuk melihat apa yang akan cocok dengan regexp. Setelah saya memiliki output, saya kemudian kembali dengan pengeditan baris perintah dan ubah echoke rm -rf. Saya tidak pernah menggunakan rm -rfregexp yang belum diuji .



5
OK, apa yang saya cari? Apakah Anda menyatakan bahwa sintaks regexp untuk pencocokan file berbeda (dan kadang-kadang disebut dengan nama yang berbeda) dari yang digunakan dalam mis perl? Atau hal lain yang saya lewatkan? Saya minta maaf atas kelambatan pemikiran saya, ini hal pertama Sabtu pagi di sini!
MadHatter

9
Hal-hal ini yang Anda panggil "regexp" sebenarnya gumpalan. Itu bukan sintaks regex yang berbeda; itu bukan regex.
bukzor

1
Argumen itu tentu bisa dibuat; Namun, dari artikel wikipedia tentang ekspresi reguler, saya menemukan bahwa "Banyak sistem komputasi modern menyediakan karakter wildcard dalam mencocokkan nama file dari sistem file. Ini adalah kemampuan inti dari banyak shell baris perintah dan juga dikenal sebagai globbing" - perhatikan penggunaan "juga dikenal sebagai", yang menurut saya menunjukkan bahwa token panggilan yang mengandung karakter metachar untuk mencocokkan satu atau lebih nama file regexps tidak salah. Saya setuju bahwa globbing adalah istilah yang lebih baik karena itu tidak berarti apa-apa selain penggunaan ekspresi reguler dalam pencocokan nama file.
MadHatter

1
@MadHatter Juga, globbing, meskipun secara visual agak mirip, sangat berbeda secara semantik dari ekspresi reguler. Dalam suatu regex makna *memiliki definisi yang sangat tepat yang disebut Kleene Star yang merupakan operator unary yang cocok dengan nol atau lebih elemen dari set yang diterapkan (dalam kasus ekspresi reguler, karakter atau set karakter sebelum Kleene Star), sedangkan dalam globbing *cocok apa pun dalam pola yang mengikuti. Mereka secara semantik sangat berbeda bahkan jika mereka tampaknya memiliki sintaksis yang sama.
aculich

9

Solusi untuk masalah ini adalah dengan mengambil cadangan reguler. Kapan saja Anda menghasilkan sesuatu yang Anda tidak ingin kehilangan risiko, buatlah cadangannya. Jika Anda menemukan cadangan secara teratur terlalu menyakitkan, maka sederhanakan prosesnya sehingga tidak menyakitkan.

Misalnya, jika Anda bekerja pada kode sumber, gunakan alat seperti gituntuk mencerminkan kode dan menyimpan riwayat di komputer lain. Jika Anda mengerjakan dokumen, minta skrip yang menyimpan rsyncdokumen Anda ke komputer lain.


Sistem file copy-on-write seperti btrfs dapat membantu juga. Anda dapat dengan mudah mengatur rotasi snapshot otomatis sederhana yang berjalan secara lokal (selain cadangan eksternal).
malthe

6

Sepertinya cara terbaik untuk mengurangi risiko ini adalah dengan menghapus dua tahap seperti kebanyakan GUI. Artinya, ganti rm dengan sesuatu yang memindahkan sesuatu ke direktori tempat sampah (pada volume yang sama). Kemudian bersihkan sampah itu setelah waktu yang cukup berlalu untuk melihat adanya kesalahan.

Salah satu utilitas tersebut, trash-cli, dibahas di Unix StackExchange, di sini .


Ini hal pertama yang saya instal di setiap mesin. Itu harus menjadi alat penghapusan default, dengan rm hanya digunakan ketika Anda harus benar-benar menghapus sesuatu sekarang. Saya sedih itu belum lepas landas, tetapi suatu hari akan. Mungkin setelah contoh rm yang sangat umum menyebabkan masalah besar yang tidak bisa diatasi dengan cadangan. Mungkin sesuatu di mana waktu yang diperlukan untuk memulihkan memainkan faktor yang sangat besar.
Gerry

+1 Setelah menggunakan linux selama 20 tahun, saya masih berpikir harus ada semacam perilaku tempat sampah rm.
Shovas

3

Salah satu faktor kunci penting untuk menghindari kesalahan seperti itu adalah tidak login menggunakan akun root. Saat Anda masuk menggunakan pengguna biasa yang tidak memiliki hak istimewa, Anda perlu menggunakan sudountuk setiap perintah. Jadi, Anda harus lebih berhati-hati.


4
Saya tidak yakin sudo akan mencegah hal seperti ini. Anda dapat membuat kesalahan ketik yang sama dengan OP, bahkan jika Anda mengetik "sudo" sebelum "rm".
cjc

1
Disebutkan bekerja sebagai root dalam edit
Valentin Nemcev

Jika Anda masih tidak yakin tentang penggunaan sudodan cadangan. Lihat halaman ini: forum.synology.com/wiki/index.php/… . Ini berbicara tentang membuat tempat sampah. Semoga ini membantu!
Khaled

1
@Khaled Saya menggunakan sudo dan cadangan, saya hanya ingin sesuatu yang lebih baik untuk masalah khusus ini
Valentin Nemcev

3

Ketika saya menghapus direktori secara rekursif, saya meletakkan -r, dan -fjika berlaku, di akhir perintah, misalnya rm /foo/bar -rf. Dengan begitu, jika saya secara tidak sengaja menekan Enter terlalu dini, tanpa mengetikkan keseluruhan path, perintah itu tidak berulang sehingga kemungkinan tidak berbahaya. Jika saya menabrak Enter saat mencoba mengetikkan slash setelah /foo, saya telah menulis rm /foodaripada rm -rf /foo.

Itu bekerja dengan baik pada sistem yang menggunakan GNU coreutils, tetapi utilitas pada beberapa Unix lain tidak memungkinkan opsi untuk ditempatkan di akhir seperti itu. Untungnya, saya tidak terlalu sering menggunakan sistem seperti itu.


2

Ini mungkin rumit, tetapi Anda dapat mengatur peran dalam SELinux sehingga bahkan jika pengguna menjadi root melalui sudo su - (atau plain su), kemampuan untuk menghapus file dapat dibatasi (Anda harus login langsung sebagai root untuk menghapus file). Jika Anda menggunakan AppArmor, Anda mungkin melakukan hal serupa .

Tentu saja, solusi lain adalah memastikan bahwa Anda memiliki cadangan. :)


2

Hindari menggunakan globbing . Di Bash, Anda dapat mengatur noglob. Tetapi sekali lagi, ketika Anda pindah ke sistem di mana noglobtidak diatur, Anda mungkin lupa itu dan melanjutkan seolah-olah itu.

Atur noclobberuntuk mencegah mvdan cpdari menghancurkan file juga.

Gunakan browser file untuk dihapus. Beberapa browser file menawarkan trashcan (misalnya, Konqueror ).

Cara lain untuk menghindari globbing adalah mengikuti. Di baris perintah, saya echo filenamepattern >> xxx. Kemudian saya mengedit file dengan Vim atau vi untuk memeriksa file mana yang akan dihapus, (perhatikan karakter pola nama file di filenmates.) Dan kemudian gunakan %s/^/rm -f/untuk mengubah setiap baris menjadi perintah hapus. Sumber xxx. Dengan cara ini Anda melihat setiap file yang akan dihapus sebelum melakukannya.

Pindahkan file ke direktori atau loteng 'loteng'. Atau gunakan kontrol versi (seperti yang dikatakan sebelumnya).


+1 untuk menggunakan beberapa metode pratinjau file Anda sebelum Anda menghapusnya, namun ada cara yang lebih sederhana dan lebih aman untuk melakukannya menggunakan findperintah .
aculich

2

ZSH bertanya kepada saya (sebagai standar) sebelum melakukan a rm -rf *.


1

Di luar chattr, tidak ada banyak perlindungan dari membiarkan root menjalankan perintah seperti itu. Itu sebabnya kelompok yang tepat dan perintah yang cermat penting ketika menjalankan hak istimewa.

Lain kali; keluarkan file yang Anda rencanakan untuk dihapus - hilangkan 'f' dari rm -rf, atau gunakan finddan berikan kepadaxargs rm


Baik Anda menyarankan menggunakan find, tetapi saya sarankan cara yang lebih aman menggunakannya dalam jawaban saya . Tidak perlu menggunakan xargs rmkarena semua versi modern findmemiliki -deleteopsi . Selain itu, untuk menggunakan dengan aman, xargs rmAnda juga perlu menggunakan find -print0dan xargs -0 rmjika tidak, Anda akan mengalami masalah ketika Anda menemukan hal-hal seperti nama file dengan spasi.
aculich


Ya, saya pikir membatasi penggunaan file findadalah saran yang bagus, namun nuansa xargspenting jika Anda menyarankan menggunakannya, jika tidak maka akan menimbulkan kebingungan dan frustrasi ketika menemukan file dengan spasi (yang dihindari dengan menggunakan -deleteopsi).
aculich

1

Beberapa alias keselamatan untuk perintah lain, untuk mencegah bencana serupa, ditemukan di sini :

# safety features
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -I'                    # 'rm -i' prompts for every file
alias ln='ln -i'
alias chown='chown --preserve-root'
alias chmod='chmod --preserve-root'
alias chgrp='chgrp --preserve-root'

Perhatikan huruf besar -I, berbeda dengan -i:

meminta satu kali sebelum menghapus lebih dari tiga file, atau ketika menghapus secara rekursif. Kurang mengganggu daripada -i, sambil tetap memberikan perlindungan terhadap sebagian besar kesalahan


Meskipun opsi I tidak akan mengulang apa yang akan Anda hapus.
Calmarius

1

Saya biasanya menggunakan -vbendera untuk melihat apa yang sedang dihapus dan memiliki kesempatan untuk ^Ccepat jika saya memiliki sedikit keraguan. Sebenarnya bukan cara untuk mencegah hal buruk rm, tetapi ini dapat berguna untuk membatasi kerusakan jika terjadi kesalahan.


1

Proses penghapusan saya pada mesin berbasis Unix adalah sebagai berikut.

  • Ketik ls /path/to/intented/file_or_directoryjendela terminal dan kemudian tekan return(atau Tab, seperti yang diinginkan), untuk melihat daftar file.

Jika semuanya terlihat baik,

  • klik up arrowtombol untuk membawa ls /path/to/intented/file_or_directorydari riwayat terminal lagi.

  • ganti lsdengan rmatau rm -ratau rm -rf, sesuai kebutuhan. Saya pribadi tidak suka menggunakan -fbendera.

Proses validasi ini juga mencegah eksekusi rmperintah yang prematur , sesuatu yang telah terjadi pada saya, sebelum saya mulai mengikuti proses ini.


Mempratinjau file terlebih dahulu sebelum menghapusnya adalah ide yang baik, dan ada cara yang lebih aman dan lebih ekspresif untuk melakukannya menggunakan find seperti yang saya jelaskan dalam jawaban saya .
aculich

1

Jika Anda tidak berminat untuk mendapatkan kebiasaan baru sekarang, .bashrc/.profileadalah tempat yang baik untuk menambahkan beberapa tes untuk memeriksa apakah Anda akan melakukan sesuatu yang bodoh. Saya membayangkan dalam fungsi Bash saya bisa memahami pola yang mungkin merusak hari saya dan muncul dengan ini:

alias rm='set -f; myrm' #set -f turns off wildcard expansion need to do it outside of           
                        #the function so that we get the "raw" string.
myrm() {
    ARGV="$*"
    set +f #opposite of set -f
    if echo "$ARGV" | grep -e '-rf /*' \
                           -e 'another scary pattern'
    then
        echo "Do Not Operate Heavy Machinery while under the influence of this medication"
        return 1
    else
        /bin/rm $@
    fi
}

Hal yang baik tentang itu adalah bahwa itu hanya Bash.

Jelas itu tidak cukup generik dalam bentuk itu, tapi saya pikir itu berpotensi, jadi tolong posting beberapa ide atau komentar.


Sebaiknya Anda mencoba melihat pratinjau file Anda sebelum menghapusnya, namun solusi ini terlalu rumit. Anda bisa melakukannya dengan sangat sederhana dengan cara yang lebih umum menggunakan findperintah . Juga, saya tidak mengerti mengapa Anda mengatakan "hal yang baik tentang itu adalah hanya Bash"? Disarankan untuk menghindari bash-isme dalam skrip .
aculich

Untuk mencegah kita dari "rm -rf / *" atau "rm -rf dir / *" ketika kita berarti "rm -rf ./*" dan "rm -rf dir / *" kita harus mendeteksi pola "/ *" dan "*" (disederhanakan). Tetapi kita tidak bisa hanya meneruskan semua argumen baris perintah melalui grep mencari beberapa pola yang berbahaya, karena bash memperluas argumen wildcard sebelum meneruskannya (bintang akan diperluas ke semua konten folder). Kita membutuhkan string argumen "mentah". Itu dilakukan dengan set -f sebelum kita memanggil fungsi "myrm" yang kemudian melewati string argumen mentah dan grep mencari pola yang telah ditentukan. *
kln

Saya mengerti apa yang Anda coba lakukan dengan set -fyang setara set -o noglobdi Bash, tapi itu masih tidak menjelaskan pernyataan Anda bahwa "Hal yang baik tentang itu adalah bahwa itu hanya Bash". Alih-alih, Anda dapat menghilangkan masalah sepenuhnya dan dengan cara yang umum untuk setiap shell dengan tidak menggunakan rmsama sekali, melainkan menggunakan findperintah . Sudahkah Anda benar-benar mencoba saran itu untuk membandingkannya dengan apa yang Anda sarankan di sini?
aculich

@aculich dengan hanya bash Maksudku tidak ada python atau dependensi perl, semuanya bisa dilakukan dalam bash. Setelah saya mengubah .bashrc saya, saya dapat terus bekerja tanpa harus menghentikan kebiasaan lama. Setiap kali saya memohon rm bash akan memastikan saya tidak melakukan sesuatu yang bodoh. Saya hanya perlu mendefinisikan beberapa pola yang ingin saya beri tahu. Seperti "*" yang akan menghapus semua yang ada di folder saat ini. Setiap sekarang dan lagi itu akan menjadi apa yang saya inginkan tetapi dengan sedikit lebih banyak interaktivitas kerja dapat ditambahkan ke "myrm".
kln

@aculich OK gotcha. Tidak. Saya belum mencobanya. Saya pikir itu memerlukan perubahan alur kerja yang signifikan. Baru diperiksa di Mac OS X .bash_history saya adalah 500 dan 27 dari perintah itu adalah rm. Dan hari ini saya tidak terlalu sering menggunakan terminal.
kln

1

Sayangnya, saya tidak dapat meninggalkan komentar di atas karena karma yang tidak mencukupi, tetapi saya ingin memperingatkan yang lain bahwa safe-rm bukanlah obat mujarab untuk mimpi buruk penghapusan massal yang tidak disengaja.

Berikut ini diuji dalam mesin virtual Linux Mint 17.1 (peringatan bagi mereka yang tidak terbiasa dengan perintah ini: JANGAN LAKUKAN INI! Sebenarnya, bahkan mereka yang akrab dengan perintah ini seharusnya / mungkin tidak akan pernah melakukan ini untuk menghindari kehilangan data bencana):

Versi teks (kental):

$ cd /
$ sudo safe-rm -rf *
$ ls
bash: /bin/ls: No such file or directory

Versi gambar (penuh):

masukkan deskripsi gambar di sini


1

Saya suka pendekatan windows dari recycle bin.

Saya biasanya membuat direktori bernama "/ tmp / recyclebin" untuk semua yang perlu saya hapus:

mkdir /tmp/recyclebin

Dan tidak pernah menggunakan rm -rf, saya selalu menggunakan:

mv target_folder /tmp/recyclebin

Kemudian, saya mengosongkan recyclebin menggunakan skrip aa atau secara manual.


0

Hehe (belum diuji dan agak jenaka!):

$ cat /usr/local/bin/saferm

#! /bin/bash

/bin/ls -- "$@"

echo "Those be the files you're about to delete."
echo "Do you want to proceed (y/N)?"

read userresponse

if [ "$userresponse" -eq "y" ]; then

  echo "Executing...."
  /bin/rm -- "$@"

fi

Lalu:

alias rm="/usr/local/bin/saferm"

Secara realistis, Anda harus memiliki jeda mental sebelum menjalankan operasi semacam itu dengan bola dunia, apakah Anda menjalankannya sebagai root, menambahkan "sudo" ke dalamnya, dll. Anda dapat menjalankan "ls" pada bola yang sama, dll., tetapi, secara mental, Anda harus berhenti sebentar, pastikan Anda mengetik apa yang Anda inginkan, memastikan apa yang Anda inginkan sebenarnya adalah apa yang Anda inginkan, dll. Saya kira ini adalah sesuatu yang terutama dipelajari dengan menghancurkan sesuatu di tahun pertama sebagai sebuah Unix SA, seperti halnya pembakar panas adalah guru yang baik dalam memberi tahu Anda bahwa sesuatu di atas kompor mungkin panas.

Dan pastikan Anda memiliki cadangan yang bagus!


Saya mencoba berpikir dua kali sebelum melakukan hal-hal berbahaya, tetapi entah bagaimana itu tidak selalu berhasil, saya telah menghancurkan sesuatu di masa lalu karena kurangnya perhatian seperti ini.
Valentin Nemcev

0

Juga, bukan sebagai perlindungan, tetapi sebagai cara untuk mengetahui file apa yang dihapus sebelum Anda menekan ^ C, Anda dapat menggunakan locatedatabase (tentu saja hanya jika itu diinstal dan selamat rm)

Saya sudah mempelajarinya dari posting blog ini


0

Cukup gunakan ZFS untuk menyimpan file yang Anda butuhkan untuk menolak penghapusan tidak disengaja dan memiliki daemon yang:

  • secara teratur membuat snapshot dari sistem file ini
  • menghapus foto yang lebih lama / tidak perlu.

Jika file dihapus, ditimpa, rusak, apa pun, cukup kembalikan sistem file Anda ke klon snapshot bagus terakhir dan Anda selesai.


0

tidak begitu banyak jawaban tetapi tip, saya selalu rm (dir) -rftidak rm -rf (dir)yaitu: jangan pergi nuklir sampai saat-saat terakhir yang mungkin.

Ini membantu mengurangi situasi di mana Anda menemukan nama dir sedemikian rupa sehingga itu masih merupakan penghapusan yang valid, seperti tergelincir dan menekan tombol enter.


Cerdas, tetapi tidak akan berfungsi pada BSD rm, di mana opsi harus datang sebelum nama file.
svenper

ya. Saya menemukan bahwa menggunakan apel baru-baru ini. Cara mengatasinya adalah menginstal alat gnu dan mengatur alias untuk semuanya :) dan / atau lebih baik melempar apel ke tempat sampah. :)
Sirex


1
jika saya diizinkan untuk melakukannya, dalam nanodetik. Ini sampah dibandingkan dengan linux.
Sirex

0

Saya pikir ini adalah tip pencegahan yang kuat, dengan * jalan pintas ekspansi di shell:

Pertama, ketik rm -rf *atau rm -rf your/path/*, JANGAN mengetikkan Enterkunci. (tentu saja, Anda harus memiliki kebiasaan peduli untuk tidak menekan Enter dengan cepat / tidak sengaja saat menggunakan rm -rf)

Lalu, tekan Alt-Shift-8(mis. Alt-Shift-*) Untuk memperluas wildcard "*" secara eksplisit di bash. Ini juga menghindari memasukkan kembali perintah "rm -rf *" saat menavigasi sejarah.

Akhirnya, setelah memeriksa ekspansi memiliki file / direktori yang tepat, tekan Enter.

Selesai.


0

Dalam hal ini membantu seseorang di luar sana untuk kasus mereka sendiri:

1. Gunakan rmsafe:

Ini memindahkan file ke folder "trash" dan Anda selalu memiliki kesempatan untuk membawanya kembali dengan sederhana mv:

$ rmsafe /path/to/important/files

Sumber: https://github.com/pendashteh/rmsafe

2. Gunakan safe:

Anda dapat mengatur alias untuk rmmenggunakan brankas:

$ alias rm="safe rm"

Sekarang jika Anda menjalankan rm /*Anda mendapatkan ini sebagai respons:

$ rm /*
Are you sure you want to 'rm /bin /boot /data /dev /etc /home /initrd.img /lib /lib64 /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var'? [y/n]

dan saya yakin Anda tidak akan mengetik y!

Sumber: https://github.com/pendashteh/safe

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.