Perché è possibile eliminare l'intero file system?


24

Dopo aver commesso il famigerato errore di eliminare il mio intero file system tramite sudo rm -rf /*, recuperando l'orrendo danno che avevo fatto e aver affrontato il fatto che ho appena perso 6 anni di durata della mia vita, ho iniziato a chiedermi perché è persino possibile farlo, e cosa si potrebbe fare per evitare che si verifichi questo errore.

Una soluzione che mi è stata suggerita è quella di revocare l'accesso root dal mio account, ma è scomodo, perché molti comandi richiedono l'accesso root e quando devi eseguire alcune dozzine di comandi ogni giorno, diventa fastidioso.

Il backup del sistema è la strada ovvia da percorrere. Ma il ripristino di un backup richiede anche dei tempi di inattività e, a seconda del sistema, i tempi di inattività potrebbero essere giorni o settimane, il che potrebbe essere inaccettabile in alcuni casi.

La mia domanda è: perché non implementare una conferma quando l'utente tenta di eliminare il proprio filesystem? In modo che quando vuoi davvero farlo, premi semplicemente Y o invii, e se non lo fai almeno non perdi tutto.



20
"Perché è persino possibile farlo?" Perché non dovrebbe essere possibile? Ci sono delle buone ragioni per eliminare il contenuto di una gerarchia di directory e ci sono molti sottoinsiemi /che sarebbero quasi altrettanto negativi da eliminare ( /etc/ad esempio). Semplicemente non è compito di rmdecidere quali directory possono o non possono essere facilmente eliminate.
Chepner,

2
Il titolo dice "Perché è possibile eliminare il sistema?" mentre la domanda stessa chiede "La mia domanda è: perché non implementare una conferma quando l'utente tenta di eliminare il proprio filesystem?". Quindi questo rende la domanda poco chiara. Qual è la tua vera domanda, così almeno sappiamo a cosa rispondere? Modifica il tuo post per chiarire
Sergiy Kolodyazhnyy il

3
Qual è effettivamente la domanda qui? Posso vederne tre: (1) Perché è possibile? (2) Come evitare di farlo? E (3) Perché non implementare una conferma? - Non sono la stessa domanda, il primo chiede un ragionamento, il secondo per gli strumenti. (Il terzo è legato al secondo, ma non è ancora lo stesso. Una conferma non è l'unico modo per prevenire qualcosa.)
ilkkachu

10
Se non stai chiedendo chiarimenti all'autore della domanda, ti preghiamo di non commentare affatto . Vedo molti commenti di auto-congratulazioni qui, che spiegano come questo sia colpa dell'OP per non sapere cosa significano le bandiere o per non avere un backup o altro. Sono molto felice di sapere che molti dei nostri utenti sono abbastanza saggi da avere backup e non eseguire comandi che non capiscono. È assolutamente fantastico per loro, ma fondamentalmente inutile per l'OP che, presumibilmente, ha anche imparato questa lezione ormai. Quindi smettiamola di crogiolarci nel nostro stesso splendore e rispondiamo alla domanda.
terdon,

Risposte:


16

rmè uno strumento di sistema di basso livello. Questi strumenti sono costruiti nel modo più semplice possibile in quanto devono essere presenti su qualsiasi sistema. rmci si aspetta che abbia un comportamento ben noto, in particolare per quanto riguarda i messaggi di conferma in modo che possa essere utilizzato negli script.

L'aggiunta di un caso speciale da richiedere rm /*non sarebbe possibile in quanto il comando rm non lo vede in questo modulo. Il *carattere jolly viene espanso dalla shell prima di essere passato a rm, quindi il comando effettivo che necessita di un caso speciale sarebbe qualcosa di simile 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. Aggiungere il codice per verificare questo caso (che probabilmente sarà diverso su Linux diversi) sarebbe una sfida complessa oltre ad essere soggetta a errori sottili. Lo standard linux rmha una protezione predefinita contro la distruzione del sistema rifiutando di rimuovere /senza l' --no-preserve-rootopzione.

Per impostazione predefinita, esistono tre protezioni contro l'eliminazione del sistema in questo modo:

  1. Autorizzazioni: gli utenti normali non saranno in grado di rimuovere file importanti. Hai aggirato questo con sudo
  2. Directory: per impostazione predefinita rm non rimuoverà le directory. Lo hai aggirato con il flag -r
  3. Scrivi file protetti: per impostazione predefinita, rm chiederà conferma prima di eliminare un file protetto da scrittura (ciò non avrebbe fermato tutto il danno, ma potrebbe aver fornito un prompt prima che il sistema diventasse irrecuperabile). Hai ignorato questa protezione con il flag -f

Per rimuovere tutto il contenuto di una cartella, anziché eseguirlo rm /path/to/folder/*, eseguire rm -rf /path/to/folder, mkdir /path/to/folderpoiché ciò attiverà la --preserve-rootprotezione e rimuoverà tutti i dotfile nella cartella


3
"Si prevede che rm abbia un comportamento ben noto" ed è in effetti uno degli strumenti specificati dallo standard POSIX. "Il carattere jolly * viene espanso dalla shell prima di essere passato a rm" Esatto, quindi aggiungere controlli per tutti i tipi di parametri, che possono essere collegamenti simbolici a directory e file effettivi /richiederebbe molte combinazioni e considerazioni, quindi non è pratico. E tornando all'idea degli standard, l'aggiunta di tali controlli romperebbe il comportamento coerente
Sergiy Kolodyazhnyy,

Questo è esattamente il motivo per cui safe-rmè un wrapper rm: in questo modo può controllare ogni singolo argomento (anziché l'intera riga di comando casuale), verificare che non sia sulla lista nera configurabile e solo successivamente chiamare rmcon gli argomenti verificati. Questo non è né molto complesso né soggetto a errori.
dessert

59

Incontra safe-rmInstalla safe-rm, il "wrapper attorno al rmcomando per prevenire eliminazioni accidentali":

safe-rm impedisce la cancellazione accidentale di file importanti sostituendoli rmcon un wrapper che verifica gli argomenti forniti rispetto a una lista nera configurabile di file e directory che non devono mai essere rimossi.

Gli utenti che tentano di eliminare uno di questi file o directory protetti non saranno in grado di farlo e verrà invece visualizzato un messaggio di avviso. ( man safe-rm)

Se il link di installazione sopra non funziona per te, basta usare sudo apt install safe-rminvece. La configurazione predefinita contiene già le directory di sistema, proviamo rm /*ad esempio:

$ 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
…

Come vedi, questo ti impedirebbe di eliminare /home, dove suppongo che i tuoi file personali siano memorizzati. Tuttavia, non ti impedisce di eliminare ~o nessuna delle sue sottodirectory se provi a eliminarle direttamente. Per aggiungere la ~/precious_photosdirectory basta aggiungere il suo percorso assoluto con la tilde risolta nel safe-rmfile di configurazione di /etc/safe-rm.conf, ad esempio:

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

Per i casi in cui corri rmsenza sudo1 e il -fflag è una buona idea aggiungere unalias per la tua shell che rende rmil -iflag predefinito. In questo modo rmrichiede ogni file prima di eliminarlo:

alias rm='rm -i'

Un flag altrettanto utile è -I, solo che avverte solo "una volta prima di rimuovere più di tre file, o quando si rimuove in modo ricorsivo", che è "meno invadente di -i, pur fornendo protezione contro la maggior parte degli errori":

alias rm='rm -I'

Il pericolo generale di questi alias è che si prende facilmente l'abitudine di fare affidamento su di essi per salvarti, il che può ritorcersi male quando si utilizza un ambiente diverso.


1: sudoignora gli alias , si può aggirare ciò definendo alias sudo='sudo 'però


25

La conferma è già lì, il problema è -fnel comando, cioè --force; Quando l'utente forza un'operazione si suppone che sappiano cosa stanno facendo (ovviamente un errore potrebbe sempre aggiungere).

Un esempio:

 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

È diverso con l' --forceopzione: non riceverò alcuna conferma e i file verranno eliminati.

Il problema è conoscere il comando e i suoi parametri, navigare di più nel mandi un comando (anche se il comando si trova in un tutorial) per esempi: la prima volta che ho visto il comando tar xzf some.tar.gzmi chiedo "cosa xzfsignifica? "

Poi ho letto la manpage tar e l'ho scoperta.


Non penso che sia rilevante qui. Nel momento in cui rm richiede per la prima volta un file protetto da scrittura o qualunque altro file, potrebbe già aver eliminato un sacco di file importanti.
Jonas Schäfer,

1
Quindi, personalmente, ho sempre pensato che -ffosse necessario eliminare le cartelle. Ho anche aperto un prompt per confermare e lamentarmi, ma ho imparato che -rè solo necessario. Suppongo rm -rfsia diventata la norma poiché è così utile in uno script (non vuoi che lo script fallisca solo perché stai cercando di eliminare cose che non esistono), quindi lo vedi spesso, ma suppongo che abbiamo bisogno essere vigili sul solo usare rm -rcome "default" quando ci si trova in una shell (comprensibilmente non dovrebbero esserci presupposti "predefiniti" che non si capiscono, specialmente con sudo, ma le persone saranno persone e almeno questo è più sicuro).
Captain Man,

2
Rmdir è il modo più sicuro per eliminare una cartella
AtomiX84,

rmnon richiede conferma per impostazione predefinita, richiede solo directory e file protetti da scrittura. Se hai eseguito quel comando sul tuo computer, probabilmente hai eliminato molti dei tuoi file. Se è necessario rmchiedere conferma, è necessario passare il -iparametro. Ad esempio:rm -ir ./*
Dan,

8

L'esecuzione senza backup significa che devi stare molto attento a non commettere errori. E spero che il tuo hardware non si guasta mai. (Anche RAID non può salvarti dalla corruzione del filesystem causata da RAM difettosa.) Questo è il tuo primo problema. (Che presumo tu abbia già realizzato e che eseguirà backup in futuro.)


Ma ci sono cose che puoi fare per ridurre la probabilità di errori come questo:

  • alias rm='rm -I'per richiedere se si eliminano più di 3 cose.
  • alias mv e cp in mv -ie cp -i(molti casi d'uso normali per questi non comportano la sovrascrittura di un file di destinazione).
  • alias sudo='sudo 'per fare l'espansione dell'alias sul primo argomento disudo

Trovo che rm -Isia molto più utile di rm -i. Di solito non viene richiesto durante il normale utilizzo, quindi tetting viene richiesto quando non ti aspettavi che fosse un avviso molto più evidente / migliore. Con -i(prima di scoprire -I), mi sono abituato a digitare \rmper disabilitare l'espansione dell'alias, dopo essere stato sicuro di aver digitato correttamente il comando.

Non vuoi prendere l'abitudine di fare affidamento rm -io -Ialias per salvarti . È la tua linea di sicurezza che speri non venga mai utilizzata. Se in realtà voglio selezionare in modo interattivo quali corrispondenze eliminare, o non sono sicuro che il mio glob possa corrispondere ad alcuni file extra, scrivo manualmente rm -i .../*whatever*. (Anche una buona abitudine nel caso in cui ti trovi in ​​un ambiente senza i tuoi alias).

Difenditi Enterdalla diteggiatura del grasso digitando ls -d /*foo*prima , quindi freccia in alto e modificalo in rm -rdopo aver finito di digitare. Quindi la riga di comando non contiene mai rm -rf ~/o simili comandi pericolosi in nessun punto. Devi solo "armarlo" cambiando lsin rmcon control-a, alt-d per andare all'inizio della riga e aggiungendo il -ro il -fdopo che hai finito di digitare la ~/some/sub/dir/parte del comando.

A seconda di ciò che stai eliminando, esegui effettivamente il ls -dprimo o no se ciò non aggiungerà nulla a ciò che vedi con il completamento della scheda. Potresti iniziare con rm(senza -ro -rf) quindi è solo control-a / control-right (o alt + f) / space / -r.

(Abituati a bash / readline le potenti combinazioni di tasti per spostarti rapidamente, come control-arrow o alt + f / b per muoverti di parole e uccidere intere parole con alt + backspace o alt + d, o control-w. E controllo -u per uccidere all'inizio della riga. E control- / per annullare una modifica se fai un passo troppo in là. E, naturalmente, la cronologia su-freccia che puoi cercare con control-r / control-s.)

Evitare a -rfmeno che non sia effettivamente necessario per silenziare le richieste di rimozione dei file di sola lettura.

Prenditi del tempo extra per pensare prima di premere Invio su un sudocomando. Soprattutto se non si dispone di backup completi, o ora sarebbe un brutto momento per ripristinare da loro.


6

Bene, la risposta breve è non eseguire un tale comando.

La lunga storia è che fa parte della personalizzazione. Essenzialmente ci sono due fattori in gioco qui. Uno è il fatto che sei libero di modificare tutti i file.

Il secondo è che il comando rm offre l'utile zucchero sintattico per eliminare tutti i file in una cartella.

In effetti questo potrebbe essere ribadito come un semplice principio di macchine Unix. Tutto è un file . Per migliorare le cose, ci sono controlli di accesso, ma questi vengono ignorati dal tuo utilizzo di

sudo

Suppongo che potresti aggiungere un alias o una funzione per assicurarti che questo non possa mai essere eseguito.


4

Se l'utilizzo dello spazio dei file di sistema non è immenso (e al giorno d'oggi "immenso" significa "centinaia di gigabyte o più") crea alcune istanze di macchine virtuali e lavora sempre all'interno di una. Il ripristino implicherebbe semplicemente l'utilizzo di un'istanza di backup.

Oppure potresti creare una prigione chroot e lavorare al suo interno. Avresti ancora bisogno di un po 'di recupero se venisse spazzato via, ma sarebbe più facile con un sistema in esecuzione (chiuso) su cui lavorare.


Questa è probabilmente la risposta più efficace, poiché può proteggere da eventuali danni, anche da script di terze parti. Dovresti solo preoccuparti del vero malware.
PyRulez,

Pensato ad un altro angolo. Vale la pena chiedersi perché è necessario effettuare eliminazioni ricorsive in primo luogo. Forse ciò che è veramente necessario sono alcuni script per rimuovere un progetto, ecc.
Loren Rosen,

"Vale la pena chiedersi perché è necessario effettuare eliminazioni ricorsive in primo luogo." Bene, solo perché non c'è un comando integrato non significa che non puoi ancora fare un errore. Script di terze parti potrebbero eliminare i file uno a uno da alcune directory. E ci sono altri modi per bloccare il sistema che toccano solo un file. Tuttavia, sostituendo rmcon safe-rmaiuti, almeno.
PyRulez,

La mia idea con la sceneggiatura era che avrebbe incorporato una nozione di "progetto" o simile. Forse avresti un file vuoto nella radice del progetto chiamato .project_rooto, se il file system lo supporta, un attributo nella directory stessa. Quindi, lo script saliva la struttura dei file alla ricerca della radice del progetto e si lamentava che la directory corrente non era in un progetto. Oppure, se i progetti vivono tutti nello stesso posto, lo script potrebbe richiedere di nominare un progetto. Potresti comunque eliminare il progetto sbagliato, ma non distruggere l'intero sistema.
Loren Rosen,

... inoltre, una variante chrootsarebbe quella di usare qualcosa come Docker (che penso effettivamente utilizzi chrootsotto le coperte). Per altri file che devi solo leggere, monta un file system di sola lettura.
Loren Rosen,

3

rmè un comando Unix molto vecchio e probabilmente non è stato progettato pensando alla facilità d'uso. Cerca di fare esattamente quello che gli viene chiesto, quando ha i permessi. Una trappola per molti nuovi utenti è che spesso vedono il codice con sudoe non pensano molto ad usarlo. Le funzioni che modificano direttamente i file come rm, dd, chroot, ecc richiedono la massima attenzione in uso.

Oggi mi piace usare trash(senza sudo) da trash-cli . Funziona come il Cestino di Windows, in quanto è possibile recuperare facilmente i file eliminati accidentalmente. Ubuntu ha già una cartella Cestino e funzionalità di spostamento nel cestino integrate in File.

Anche in questo caso potresti commettere errori, quindi assicurati di fare il backup dell'intero filesystem.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.