Vraag Hoe voorkom ik per ongeluk rm -rf / *?


Ik ben net weggerend rm -rf /* per ongeluk, maar ik bedoelde rm -rf ./* (let op de ster na de schuine streep).

alias rm='rm -i' en --preserve-root standaard redde me niet, zijn er daarom automatische voorzorgsmaatregelen?


Ik was niet root en annuleerde het commando onmiddellijk, maar er waren ergens ontspannen toestemmingen of iets omdat ik merkte dat mijn Bash-prompt al kapot was. Ik wil niet op permissies vertrouwen en niet root zijn (ik zou dezelfde fout kunnen maken met sudo), en ik wil niet op mysterieuze bugs jagen vanwege een ontbrekend bestand ergens in het systeem, dus back-ups en sudo zijn goed, maar ik zou iets beters willen hebben voor dit specifieke geval.


Over tweemaal nadenken en het brein gebruiken. Ik gebruik het eigenlijk! Maar ik gebruik het om een ​​complexe programmeertaak met 10 verschillende dingen op te lossen. Ik ben diep genoeg ondergedompeld in deze taak, er is geen hersenkracht meer over voor het controleren van vlaggen en paden, ik denk niet eens in termen van commando's en argumenten, ik denk in termen van acties als 'lege huidige richting', verschillende delen van mijn brein vertalen ze naar commando's en soms maakt het fouten. Ik wil dat de computer ze corrigeert, tenminste de gevaarlijke.


156
2017-12-02 17:09


oorsprong


Ter info, dat kan ook rm -rf . /mydir in plaats van rm -rf ./mydir en dood elke map waarin je zat. Ik merk dat dit vaker gebeurt. - user606723
Om een ​​geweeranalogie te gebruiken, zegt deze vraag, maak alsjeblieft het wapen wijs dat ik mik op mijn voet en niet op vuur, maar ik wil geen verantwoordelijkheid hebben voor het niet op de voet richten van het geweer op de eerste plaats. Geweren en computers zijn stom en als je iets stoms doet, dan krijg je deze resultaten. Als je de analogie van het geweer volgt, zal niets je ervan weerhouden jezelf pijn te doen, behalve waakzaamheid en oefening. - slillibri
@slillibri Behalve dat rm is geen pistool, het is een computerprogramma kon wees slim genoeg om te bepalen dat de gebruiker enkele belangrijke bestanden gaat verwijderen en een waarschuwing afgeeft (zoals het ook doet als je het probeert te doen rm -rf / zonder ster). - Valentin Nemcev
@slillibri-wapens hebben beveiligingen. Vragen hoe je betere beveiligingen kunt plaatsen op de rm opdracht is een volkomen legitieme vraag over sysadmin. - Gilles
sudo rm / bin / rm niet aanbevolen, maar zal de meeste rm's voorkomen :-) - Paul


antwoorden:


Een van de trucjes die ik volg is om te zetten # in het begin tijdens het gebruik van de rm commando.

root@localhost:~# #rm -rf /

Dit voorkomt onbedoelde uitvoering van rm op het verkeerde bestand / map. Na het verifiëren, verwijderen # vanaf het begin. Deze truc werkt, omdat in Bash een woord begint met # zorgt ervoor dat dat woord en alle resterende tekens op die regel worden genegeerd. Dus het commando wordt gewoon genegeerd.

OF

Als je een belangrijke map wilt voorkomen, is er nog een truc.

Maak een bestand met de naam -i in die map. Hoe kan zo'n vreemd bestand worden gemaakt? Gebruik makend van touch -- -i of touch ./-i

Probeer nu 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'? 

Hier de * zal uitbreiden -i naar de opdrachtregel, zodat uw commando uiteindelijk wordt rm -rf -i. Dus commando zal prompt voor verwijdering. Je kunt dit bestand in je plaatsen /, /home/, /etc/, enz.

OF

Gebruik --preserve-root als een optie om rm. In de rm opgenomen in nieuwer coreutils pakketten, deze optie is de standaard.

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

OF

Gebruik safe-rm

Fragment van de website:

Safe-rm is een veiligheidsinstrument bedoeld om onbedoelde verwijdering te voorkomen   van belangrijke bestanden door / bin / rm te vervangen door een wrapper, die controleert   de gegeven argumenten tegen een configureerbare zwarte lijst van bestanden en   mappen die nooit mogen worden verwijderd.

Gebruikers die proberen een van deze beveiligde bestanden of te verwijderen   mappen kunnen dit niet doen en krijgen een waarschuwing te zien   bericht in plaats daarvan:

$ rm -rf /usr
Skipping /usr

215
2017-12-02 23:36



safe-rm ziet er erg goed uit, kijk er nu in ... - Valentin Nemcev
safe-rm is netjes. Ook dat is een handige truc met de -i het dossier. Hah. Domme bash. - EricR
Verbazingwekkend wat voor bedrog wordt gedaan in Unix. - WernerCD
Het creërende bestand met de naam -i is absoluut puur geniaal. Ik had dat ongeveer een jaar geleden kunnen gebruiken toen ik per ongeluk een rm -rf / etc / * op VPS uitvoerde ... (gelukkig maak ik 's nachts snapshots, dus kon ik dit binnen 45 minuten herstellen). - David W
Het is geniaal. Tovenarij zou zijn touch -- -rf - Mircea Vutcovici


Jouw probleem:

Ik heb gewoon rm -rf / * per ongeluk uitgevoerd, maar ik bedoel rm -rf ./* (let op de ster na de schuine streep).

De oplossing: Doe dat niet! Gebruik het in de praktijk niet ./ aan het begin van een pad. De schuine strepen voegen geen waarde toe aan het commando en veroorzaken alleen verwarring.

./*betekent hetzelfde als *, dus het bovenstaande commando is beter geschreven als:

rm -rf *

Hier is een gerelateerd probleem. Ik zie vaak de volgende uitdrukking, waar iemand dat veronderstelde FOO is ingesteld op iets als /home/puppies. Ik zag dit juist vandaag, in de documentatie van een grote softwareleverancier.

rm -rf $FOO/

Maar als FOO is niet ingesteld, dit wordt geëvalueerd naar rm -rf /, die zal proberen om alle bestanden op uw systeem te verwijderen. De achterlopende schuine streep is overbodig, dus gebruik deze in de praktijk niet.

Het volgende zal hetzelfde doen en zal uw systeem minder snel beschadigen:

rm -rf $FOO

Ik heb deze tips op de harde manier geleerd. Toen ik veertien jaar geleden mijn eerste superuser-account had, rende ik per ongeluk rm -rf $FOO/ vanuit een shell-script en een systeem vernietigd. De vier andere sysadmins keken ernaar en zeiden: 'Yup. Iedereen doet dat een keer. Nu zijn hier je installatiemedia (36 diskettes). Ga het repareren. '

Andere mensen adviseren hier oplossingen zoals --preserve-root en safe-rm. Deze oplossingen zijn echter niet aanwezig voor alle Un * xe-varients en werken mogelijk niet op Solaris, FreeBSD en MacOSX. In aanvulling op, safe-rm vereist dat u extra pakketten installeert op elk Linux-systeem dat u gebruikt. Als je erop vertrouwt safe-rm, wat gebeurt er wanneer u een nieuwe baan begint en zij niet hebben? safe-rm geïnstalleerd? Deze tools zijn een kruk, en het is veel beter om te vertrouwen op bekende standaardwaarden en uw werkgewoonten te verbeteren.


42
2017-12-02 18:58



Mijn vriend vertelde me dat hij nooit gebruikt rm -rf *. Hij wijzigt altijd eerst de directory en gebruikt een specifiek doel. De reden is dat hij de geschiedenis van de shell veel gebruikt, en hij is bang dat een dergelijk bevel in zijn geschiedenis op het verkeerde moment opduikt. - haggai_e
@haggai_e: Goede tip. Toen ik Unix nieuw was, liep ik eens tegen een bug aan waar rm -rf * ook verwijderd . en ... Ik was root, en dit doorkruiste de naar onder directories zoals ../../..en was behoorlijk destructief. Ik probeer heel voorzichtig te zijn met rm -rf * sindsdien. - Stefan Lasiewski
rm -rf $FOO zal het niet helpen als dat nodig is rm -rf $FOO/$BAR. cd $FOO && rm -rf $BAR zal helpen, hoewel het veel langer is. - Victor Sergienko
@VictorSergienko, met bash, wat dacht je van specificeren ${FOO:?}, als in rm -rf ${FOO:?}/ en rm -rf ${FOO:?}/${BAR:?}. Het zal voorkomen dat het ooit vertaalt in rm -rf /. Ik heb wat meer info hierover in mijn antwoord hier. - A-B-B
@haggai_e: Ik vind dit een van de beste adviezen over dit onderwerp. Ik heb mijn vinger verbrand door te gebruiken rm -rf * in een for-lus die per ongeluk naar de verkeerde map is veranderd en uiteindelijk iets anders heeft verwijderd. Als ik een specifiek doelwit zou hebben gebruikt, zou het een kleinere kans hebben gehad om het verkeerde te verwijderen. - richk


Aangezien dit op "Serverfault" staat, zou ik dit willen zeggen:

Als u tientallen of meer servers hebt, met een vrij groot team van beheerders / gebruikers, iemand gaat naar rm -rf of chown de verkeerde map.

U zou een plan moeten hebben om de betreffende service met zo weinig mogelijk MTTR te laten herstellen.


30
2017-12-02 20:42



En u moet een VM of reservedoos gebruiken om herstelprocedures uit te voeren - ontdek wat niet werkte en verfijn het plan. We beginnen aan een tweewekelijkse reboot - omdat er stroomuitval is geweest in ons gebouw, en elke keer was het pijnlijk. DOOR enkele geplande shutdowns van alle racks te doen, hebben we het nu al na een paar dagen rennen teruggebracht tot ongeveer 3 uur - elke keer als we leren welke bits init.d-scripts moeten automatiseren / repareren voor enz. - Danny Staple
En probeer deze opdracht op een VM. Het is interessant! Maar maak eerst een snapshot. - Stefan Lasiewski


De beste oplossingen zijn het veranderen van je gewoontes om niet te gebruiken rm direct.

Een benadering is om te rennen echo rm -rf /stuff/with/wildcards* eerste. Controleer of de uitvoer van de jokertekens er redelijk uitziet en gebruik vervolgens de geschiedenis van de shell om de vorige opdracht uit te voeren zonder de echo.

Een andere benadering is om de echo commando's in gevallen waarin het overduidelijk is wat je gaat verwijderen. In plaats van alle bestanden in een map te verwijderen, verwijdert u de map en maakt u een nieuwe map. Een goede methode is om de bestaande map te hernoemen naar DELETE-foo, maak dan een nieuwe map aan foo met de juiste machtigingen en uiteindelijk verwijderen DELETE-foo. Een bijkomend voordeel van deze methode is dat de opdracht die is ingevoerd in uw geschiedenis is 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

Als je echt op het verwijderen van een aantal bestanden wilt omdat je de map moet behouden (omdat deze altijd moet bestaan, of omdat je niet de toestemming zou hebben om deze opnieuw te maken), verplaats je de bestanden naar een andere map en verwijder je die map .

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

(Raak dat alt+. sleutel.)

Een directory van binnen verwijderen zou aantrekkelijk zijn, omdat rm -rf . is kort en heeft dus een laag risico op typefouten. Typische systemen laten je dat helaas niet doen. Je kunt het doen rm -rf -- "$PWD" in plaats daarvan, met een hoger risico op typefouten, maar de meeste leiden tot het verwijderen van niets. Pas op dat dit een gevaarlijk bevel achterlaat in uw shell-geschiedenis.

Gebruik versiebeheer wanneer dat mogelijk is. Jij niet rm, u cvs rm of wat dan ook, en dat is onuitvoerbaar.

Zsh heeft opties om u te vragen voordat het wordt uitgevoerd rm met een argument dat alle bestanden in een map weergeeft: rm_star_silent (standaard ingeschakeld) prompts voor het uitvoeren rm whatever/*, en rm_star_wait (standaard uitgeschakeld) voegt een vertraging van 10 seconden toe, waarin u niet kunt bevestigen. Dit is van beperkt nut als je van plan was om alle bestanden in een bepaalde map te verwijderen, omdat je de prompt al verwacht. Het kan helpen om typfouten te voorkomen rm foo * voor rm foo*.

Er zweven veel meer oplossingen rond die betrekking hebben op het wijzigen van de rm commando. Een beperking van deze benadering is dat je op een dag op een machine met de echte zult zitten rm en je belt automatisch rm, veilig in uw verwachting van een bevestiging ... en vervolgens herstelt u back-ups.


23
2017-12-02 22:33



mv -t DELETE_ME -- * is een beetje meer waterdicht. - Tobu
@Giles Niet gebruiken rm direct is goed advies! Een nog beter alternatief is om gebruik de find commando. - aculich
En als je de map wilt behouden, kun je dat eenvoudig doen door te gebruiken find somedir -type f -delete waarin alle bestanden worden verwijderd somedir maar verlaat de map en alle submappen. - aculich


Je zou altijd een alias kunnen doen, zoals je al zei:

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"

Je zou het ook kunnen integreren met een commandolijn-twitterclient om je vrienden te waarschuwen over hoe je jezelf bijna hebt vernederd door je harde schijf te vernietigen met rm -fr /* als root.


18
2017-12-02 17:16



+1 voor telnet miku.acm.uiuc.edu - Ali
alias echo = "telnet miku.acm.uiuc.edu" - kubanczyk
Ik moet niet oud genoeg zijn ... wat is de betekenis van telnet miku.acm.uiuc.edu? - Kyle Strand
Probeer het en ontdek het. Het is niet-destructief. Als je zo paranoïde bent als je zou moeten zijn, voer dan een VM uit. - Naftuli Kay
-1 U kunt geen alias-opdrachten met spaties in hen opnemen, laat staan ​​/ *, wat een ongeldige naam is - xenithorb


Ja: werk niet als root en denk altijd twee keer na voordat je handelt.

Kijk ook eens naar zoiets https://launchpad.net/safe-rm.


15
2018-02-26 05:50



Genoemd werken als root in bewerking - Valentin Nemcev
@Valentin: o_O !! - Jonathan Rioux


De eenvoudigste manier om onbedoeld te voorkomen rm -rf /* is om alle gebruik van de te vermijden rm commando! Sterker nog, ik ben altijd in de verleiding geweest om weg te rennen rm /bin/rm om het commando volledig te verwijderen! Nee, ik ben niet grappig.

Gebruik in plaats daarvan de -delete optie van de find commando, maar eerst voordat ik de bestanden verwijder, raad ik aan een voorvertoning te bekijken van de bestanden die u wilt verwijderen:

find | less

Let op, in moderne versies van find als je de naam van een map weglaat, zal deze impliciet de huidige map gebruiken, dus het bovenstaande is het equivalent van:

find . | less

Zodra u zeker weet dat dit de bestanden zijn die u wilt verwijderen, kunt u de -delete keuze:

find path/to/files -delete

Dus, niet alleen find  veiliger in gebruik, het is ook expressiever, dus als u alleen bepaalde bestanden in een directoryhiërarchie wilt verwijderen die overeenkomen met een bepaald patroon, kunt u een expressie als deze gebruiken om een ​​voorbeeld te bekijken en vervolgens de bestanden verwijderen:

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

Er zijn veel goede redenen om te leren en te gebruiken find behalve gewoon een veiliger rm, dus je zult jezelf later bedanken als je de tijd neemt om te leren gebruiken find.


15
2017-12-03 22:44



Zeer interessante discussie. Ik vind je aanpak leuk en heb een klein fragment gemaakt. Het is super inefficiënt, omdat het hoogstens 3 keer vind, maar voor mij is dit een mooie start: github.com/der-Daniel/fdel - Daniel Hitzel


Er zit echt slecht advies in deze thread, gelukkig is het meeste ervan weggestemd.

Allereerst, als je root moet zijn, word dan root - sudo en de verschillende aliastrucs zullen je zwak maken. En erger nog, ze maken je onvoorzichtig. Leer de dingen op de juiste manier te doen, stop afhankelijk van aliassen om je te beschermen. Op een dag zal je wortel schieten op een doos die je trainingswielen niet heeft en iets opblazen.

Ten tweede - als je wortel schiet, zie jezelf als het besturen van een bus vol schoolkinderen. Soms kun je rocken op het nummer op de radio, maar soms moet je beide kanten op kijken, de dingen vertragen en al je spiegels dubbel controleren.

Derde - Je bijna nooit werkelijk moet rm -rf - waarschijnlijker dat je wilt mv something something.bak of mkdir _trash && mv something _trash/

Ten vierde - altijd ls je wildcard eerder rm - Er is niets geks om naar iets te kijken voordat het voorgoed wordt vernietigd.


14
2017-12-02 19:57



+1 voor gebruik van ls. - Sachin Divekar
@eventi Ik ben het ermee eens dat er een vreselijk advies en lelijke hacks in deze thread zitten. En het is absoluut een goed idee om naar iets te kijken voordat je het vernietigt, maar er is een nog betere manier om dat te doen met behulp van de find commando. - aculich
Ik zie niet hoe vinden eenvoudiger of veiliger is, maar ik vind je leuk find . -name '*~' voorbeeld. Mijn punt is dat ls zal dezelfde glob vermelden rm zal gebruiken. - eventi


Dit is standaard van mij specifiek voor regexps in de context van rm, maar het zou je in dit geval hebben gered.

Dat doe ik altijd echo foo*/[0-9]*{bar,baz}* ten eerste om te zien wat de regexp gaat evenaren. Zodra ik de uitvoer heb, ga ik terug met bewerkingen en wijzigingen in de opdrachtregel echo naar rm -rf. ik nooit, ooit gebruiken rm -rf op een niet geteste regexp.


11
2017-12-02 19:05



Vergelijk alsjeblieft: linuxmanpages.com/man3/regex.3.php  linuxmanpages.com/man3/glob.3.php - bukzor
OK, waar ben ik naar op zoek? Maak je het punt dat de regexp-syntaxis voor bestandsafstemming anders is (en soms wordt genoemd met een andere naam) dan die in bijv. Perl wordt gebruikt? Of een ander punt dat ik heb gemist? Mijn excuses voor mijn trage gedachte, het is het eerste wat hier zaterdagochtend is! - MadHatter
Deze dingen die je "regexp" noemt, zijn in feite globs. Het is geen andere regex-syntaxis; het is geen regex. - bukzor
Dat argument zou zeker kunnen worden gemaakt; nochtans, van het Wikipedia-artikel over reguliere expressies, vind ik dat "Veel moderne computersystemen jokertekens leveren in overeenkomende bestandsnamen van een bestandssysteem.Dit is een kernvermogen van veel command-line shells en is ook bekend als globbing" - let op gebruik van "ook bekend als", wat mij lijkt aan te geven dat het aanroepen van tokens die metacharacters bevatten om overeen te komen met een of meer regexps van bestandsnamen, niet verkeerd is. Ik ben het ermee eens dat globbing een betere term is, omdat het niets anders betekent dan het gebruik van reguliere expressies bij het matchen van bestandsnamen. - MadHatter
@MadHatter Controleren om te zien welke bestanden overeenkomen voordat u ze verwijdert, is een goed advies, maar er is een veiligere en expressievere manier om het met de find commando. - aculich


De oplossing voor dit probleem is het maken van regelmatige back-ups. Telkens wanneer u iets produceert dat u niet wilt verliezen, moet u het ondersteunen. Als u merkt dat regelmatig een back-up maken te pijnlijk is, vereenvoudig dan het proces zodat het niet pijnlijk is.

Als u bijvoorbeeld werkt aan broncode, gebruikt u een hulpprogramma als git om de code te spiegelen en de geschiedenis op een andere machine te bewaren. Als je aan documenten werkt, zorg dan voor een script rsyncs uw documenten naar een andere machine.


9
2017-12-03 23:02



Een copy-on-write-bestandssysteem zoals btrfs kan ook helpen. U kunt eenvoudig een eenvoudige automatische snapshotrotatie instellen die lokaal wordt uitgevoerd (naast externe back-up). - malthe