Comment prévenir rm -rf / * accidentel?

164

J'ai couru rm -rf /*accidentellement, mais je voulais dire rm -rf ./*(remarquez l'étoile après la barre oblique).

alias rm='rm -i'et --preserve-rootpar défaut ne m'a pas sauvé, y a-t-il des garanties automatiques pour ceci?


Je n'étais pas root et ai immédiatement annulé la commande, mais il y avait des autorisations assouplies quelque part ou quelque chose parce que j'ai remarqué que mon invite Bash était déjà dépassée. Je ne veux pas dépendre d'autorisations et ne pas être root (je pourrais faire la même erreur sudo), et je ne veux pas chasser de mystérieux bugs à cause d'un fichier manquant quelque part dans le système, donc, les sauvegardes et sudosont bonnes , mais je voudrais quelque chose de mieux pour ce cas particulier.


Penser à deux fois et utiliser le cerveau. Je l'utilise réellement! Mais je l’utilise pour résoudre une tâche de programmation complexe impliquant 10 choses différentes. Je suis immergé dans cette tâche assez profondément, il n'y a plus de puissance cérébrale pour vérifier les drapeaux et les chemins, je ne pense même pas en termes de commandes et d'arguments, je pense en termes d'actions telles que 'empty current dir', une partie différente de mon cerveau les traduit en commandes et parfois des erreurs sont commises. Je veux que l'ordinateur les corrige, au moins les plus dangereux.

Valentin Nemcev
la source
13
Pour votre information, vous pouvez aussi le faire au rm -rf . /mydirlieu de rm -rf ./mydiret tuer tout répertoire où vous étiez. Je trouve cela arrive plus souvent.
user606723
27
Pour utiliser une analogie avec une arme à feu, cette question dit s'il vous plaît faites en sorte que l'arme reconnaisse que je vise mon pied et non pas le feu, mais je ne veux pas avoir la responsabilité de ne pas viser mon arme avec le pied en premier lieu. Les armes à feu et les ordinateurs sont stupides et si vous faites une chose stupide, vous obtiendrez ces résultats. En suivant l’analogie du revolver, rien ne vous empêchera de vous blesser si ce n’est la vigilance et la pratique.
Slillibri
73
@slillibri Sauf que ce rmn'est pas une arme à feu, c'est un programme informatique, il pourrait être assez intelligent pour déterminer que l'utilisateur va supprimer certains fichiers importants et émettre un avertissement (comme c'est le cas si vous essayez de le faire rm -rf /sans étoile).
Valentin Nemcev
80
@slillibri Guns ont des sécurités. Il rmest tout à fait légitime que l'administrateur système pose la question de savoir comment améliorer les commandes.
Gilles
21
sudo rm / bin / rm non recommandé, mais empêchera la plupart des rm :-)
Paul

Réponses:

220

Une des astuces que je suis est de mettre #au début en utilisant la rmcommande.

[email protected]:~# #rm -rf /

Cela empêche l'exécution accidentelle de rmsur le mauvais fichier / répertoire. Une fois vérifié, supprimez #du début. Cette astuce fonctionne car, dans Bash, un mot commençant par le #mot est ignoré, ainsi que tous les caractères restants de cette ligne. Donc, la commande est simplement ignorée.

OU

Si vous voulez empêcher tout répertoire important, il y a encore une astuce.

Créez un fichier nommé -idans ce répertoire. Comment créer un fichier aussi étrange? Utiliser touch -- -ioutouch ./-i

Maintenant, essayez rm -rf *:

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

Ici, le *sera étendu -ià la ligne de commande, votre commande deviendra finalement rm -rf -i. Ainsi, la commande demandera avant le retrait. Vous pouvez mettre ce fichier dans votre /, /home/, /etc/, etc.

OU

Utiliser --preserve-rootcomme une option pour rm. Dans les rmnouveaux coreutilspackages inclus , cette option est la valeur par défaut.

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

OU

Utilisez safe-rm

Extrait du site web:

Safe-rm est un outil de sécurité destiné à empêcher la suppression accidentelle de fichiers importants en remplaçant / bin / rm par un wrapper, qui vérifie les arguments donnés par rapport à une liste noire configurable de fichiers et de répertoires qui ne doivent jamais être supprimés.

Les utilisateurs qui tentent de supprimer l'un de ces fichiers ou répertoires protégés ne pourront pas le faire et un message d'avertissement s'affichera à la place:

$ rm -rf /usr
Skipping /usr
Sachin Divekar
la source
10
safe-rm a l'air très bien, en regardant maintenant ...
Valentin Nemcev
45
safe-rm est soigné. C'est aussi un truc astucieux avec le -ifichier. Hah. Silly Bash.
EricR
5
Incroyable quel genre de tromperie est faite dans Unix.
WernerCD
4
Le fichier de création nommé -i est un pur génie. J'aurais pu l'utiliser il y a environ un an lorsque j'ai accidentellement lancé une application rm -rf / etc / * sur VPS ... (heureusement, je prends des instantanés nocturnes, ce qui m'a permis de restaurer en moins de 45 minutes).
David W
9
C'est du génie. La sorcellerie seraittouch -- -rf
Mircea Vutcovici
46

Ton problème:

Je viens de lancer rm -rf / * accidentellement, mais je voulais dire rm -rf ./* (remarquez l'étoile après la barre oblique).

La solution: ne faites pas ça! En pratique, n'utilisez pas ./au début d'un chemin. Les barres obliques n'ajoutent aucune valeur à la commande et ne feront que créer de la confusion.

./*signifie la même chose que *, alors la commande ci-dessus est mieux écrite ainsi:

rm -rf *

Voici un problème connexe. Je vois souvent l'expression suivante, où quelqu'un a supposé que FOOc'est réglé sur quelque chose comme /home/puppies. En fait, je l’ai vu juste aujourd’hui dans la documentation d’un grand éditeur de logiciels.

rm -rf $FOO/

Mais si FOOn'est pas défini, cela sera évalué à rm -rf /, ce qui tentera de supprimer tous les fichiers de votre système. Le slash final n'est pas nécessaire, donc ne l'utilisez pas en pratique.

Les éléments suivants feront la même chose et risquent moins de corrompre votre système:

rm -rf $FOO

J'ai appris ces astuces à la dure. Lorsque j’avais mon premier compte superutilisateur il ya 14 ans, j’ai accidentellement couru à rm -rf $FOO/partir d’un script shell et détruit un système. Les 4 autres administrateurs ont examiné la situation et ont déclaré: «Ouais. Tout le monde le fait une fois. Maintenant, voici votre support d'installation (36 disquettes). Va le réparer.

D'autres personnes recommandent des solutions telles que --preserve-rootet safe-rm. Cependant, ces solutions ne sont pas présentes pour tous les Un-xe-varients et risquent de ne pas fonctionner sous Solaris, FreeBSD et MacOSX. De plus, safe-rmvous devez installer des packages supplémentaires sur chaque système Linux que vous utilisez. Si vous comptez sur safe-rm, que se passe-t-il lorsque vous commencez un nouvel emploi et que l' safe-rminstallation n'est pas installée? Ces outils sont une béquille, et il est bien préférable de s’appuyer sur les défauts connus et d’améliorer vos habitudes de travail.

Stefan Lasiewski
la source
19
Mon ami m'a dit qu'il n'utilise jamais rm -rf *. Il change toujours le répertoire en premier et utilise une cible spécifique. La raison en est qu'il utilise beaucoup l'historique du shell et il craint qu'une telle commande dans son histoire n'apparaisse au mauvais moment.
haggai_e
@haggai_e: Bon conseil. Quand j’étais nouveau sur Unix, j’ai couru un jour un bogue qui a rm -rf *également été supprimé .et ... J'étais root, et cela a traversé les répertoires inférieurs comme ../../.., et était assez destructif. J'essaie d'être très prudent avec rm -rf *depuis.
Stefan Lasiewski
2
rm -rf $FOOne vous aidera pas si vous en avez besoin rm -rf $FOO/$BAR. cd $FOO && rm -rf $BARaidera, même si c'est beaucoup plus long.
Victor Sergienko
5
@VictorSergienko, avec bash, que diriez-vous de spécifier ${FOO:?}, comme dans rm -rf ${FOO:?}/et rm -rf ${FOO:?}/${BAR:?}. Cela l'empêchera de se traduire jamais rm -rf /. J'ai plus d'informations à ce sujet dans ma réponse ici .
Acumenus
@haggai_e: Je trouve que c'est l'un des meilleurs conseils sur ce sujet. Je me suis brûlé les doigts en utilisant rm -rf *une boucle for qui, par erreur, avait été remplacée par le mauvais répertoire et a fini par supprimer autre chose. Si j'avais utilisé une cible spécifique, il aurait eu beaucoup moins de chances de supprimer la mauvaise chose.
richk
30

Puisqu'il s'agit de "Serverfault", j'aimerais dire ceci:

Si vous avez des dizaines de serveurs ou plus, avec une grande équipe d'administrateurs / utilisateurs, quelqu'un se connecte rm -rfou chownle mauvais répertoire.

Vous devriez avoir un plan pour restaurer le service affecté avec le moins possible de MTTR.

Pas maintenant
la source
4
Et vous devriez utiliser une machine virtuelle ou une boîte de rechange pour vous exercer à la récupération. Trouvez ce qui n'a pas fonctionné et peaufinez votre plan. Nous commençons un redémarrage bimensuel - car il y a eu des coupures de courant dans notre bâtiment et cela a été douloureux à chaque fois. En faisant quelques arrêts planifiés de tous les racks, nous avons passé de quelques jours à environ 3 heures - à chaque fois que nous apprenons quels bits automatiser / réparer les scripts init.d, etc.
Danny Staple
Et essayez cette commande sur une VM. C'est intéressant! Mais prenez un instantané en premier.
Stefan Lasiewski
23

Les meilleures solutions impliquent de changer vos habitudes pour ne pas les utiliser rmdirectement.

Une approche consiste à exécuter en echo rm -rf /stuff/with/wildcards*premier. Vérifiez que la sortie des caractères génériques semble raisonnable, puis utilisez l’historique du shell pour exécuter la commande précédente sans le fichier echo.

Une autre approche consiste à limiter la echocommande aux cas dans lesquels il est évident que vous allez supprimer ce que vous allez supprimer. Plutôt que de supprimer tous les fichiers d'un répertoire, supprimez-le et créez-en un nouveau. Une bonne méthode consiste à renommer le répertoire existant en DELETE-foo, puis à créer un nouveau répertoire fooavec les autorisations appropriées et enfin à le supprimer DELETE-foo. Un avantage supplémentaire de cette méthode est que la commande qui est entrée dans votre historique est 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

Si vous insistez vraiment pour supprimer un groupe de fichiers parce que vous avez besoin de conserver le répertoire (parce qu'il doit toujours exister ou parce que vous n'avez pas l'autorisation de le recréer), déplacez les fichiers dans un autre répertoire et supprimez ce répertoire. .

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

(Appuyez sur cette touche Alt+ ..)

Supprimer un répertoire de l'intérieur serait intéressant, car il rm -rf .est court et présente donc un faible risque de fautes de frappe. Les systèmes typiques ne vous permettent pas de le faire, malheureusement. Vous pouvez au rm -rf -- "$PWD"lieu de cela, avec un risque plus élevé de fautes de frappe, mais la plupart d'entre eux conduisent à ne rien enlever. Attention, cela laisse une commande dangereuse dans l'historique de votre shell.

Chaque fois que vous le pouvez, utilisez le contrôle de version. Vous ne le faites pas rm, vous cvs rmou quoi que ce soit, et c'est impossible.

Zsh dispose d'options pour vous inviter avant de lancer rmun argument répertoriant tous les fichiers d'un répertoire: rm_star_silent(activé par défaut) avant d'exécuter rm whatever/*, et rm_star_wait(désactivé par défaut) ajoute un délai de 10 secondes pendant lequel vous ne pouvez pas confirmer. Ceci est d'une utilité limitée si vous souhaitez supprimer tous les fichiers de certains répertoires, car vous attendez déjà l'invite. Cela peut aider à prévenir les fautes de frappe comme rm foo *pour rm foo*.

Il y a beaucoup plus de solutions flottantes qui impliquent de changer la rmcommande. Une des limites de cette approche est qu’un jour, vous serez sur une machine avec le réel rmet que vous appellerez automatiquement rm, en toute sécurité dans l’attente d’une confirmation… et que vous restaurerez ensuite les sauvegardes.

Gilles
la source
mv -t DELETE_ME -- *est un peu plus infaillible.
Tobu
@Giles Ne pas utiliser rmdirectement est un bon conseil! Une alternative encore meilleure consiste à utiliser la findcommande .
Aculich
Et si vous avez besoin que le répertoire reste, vous pouvez le faire tout simplement en utilisant find somedir -type f -deletequi supprimera tous les fichiers somedirmais laissera le répertoire et tous les sous-répertoires.
Aculich
19

Vous pouvez toujours faire un alias, comme vous l'avez mentionné:

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"

Vous pouvez également l'intégrer à un client twitter en ligne de commande pour avertir vos amis de la façon dont vous vous êtes presque humilié en effaçant votre disque dur en rm -fr /*tant que root.

Naftuli Kay
la source
3
+1 pour telnet miku.acm.uiuc.edu
Ali
1
alias echo = "telnet miku.acm.uiuc.edu"
kubanczyk
Je ne dois pas être assez old school ... quelle est la signification de telnet miku.acm.uiuc.edu?
Kyle Strand
Essayez-le et découvrez. C'est non destructif. Si vous êtes aussi paranoïaque que vous devriez l'être, exécutez-le sur une machine virtuelle.
Naftuli Kay
3
-1 Vous ne pouvez pas aliaser les commandes contenant des espaces, sans parler de / * qui est un nom invalide
xenithorb
15

Oui: ne travaillez pas en tant que root et réfléchissez toujours à deux fois avant d'agir.

Regardez aussi quelque chose comme https://launchpad.net/safe-rm .

Sven
la source
Mentionné travaillant en tant que root dans le montage
Valentin Nemcev
@Valentin: o_O !!
Jonathan Rioux
15

Le moyen le plus simple d'éviter les accidents rm -rf /*est d'éviter toute utilisation de la rmcommande! En fait, j'ai toujours été tenté de courir rm /bin/rmpour me débarrasser complètement de la commande! Non, je ne suis pas facétieux.

Utilisez plutôt l' -deleteoption de la findcommande , mais avant de supprimer les fichiers, je vous recommande de prévisualiser les fichiers que vous souhaitez supprimer:

find | less

Notez que dans les versions modernes de findsi vous omettez le nom d'un répertoire, celui-ci utilisera implicitement le répertoire actuel, de sorte que ce qui précède est l'équivalent de:

find . | less

Une fois que vous êtes sûr que ce sont les fichiers que vous souhaitez supprimer, vous pouvez alors ajouter l' -deleteoption:

find path/to/files -delete

Ainsi, non seulement l'utilisation est find sécurisée, mais également l'expression . Si vous souhaitez supprimer uniquement certains fichiers d'une hiérarchie de répertoires correspondant à un modèle particulier, vous pouvez utiliser une expression comme celle-ci pour afficher un aperçu, puis supprimez les fichiers:

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

Il y a beaucoup de bonnes raisons d'apprendre et d'utiliser en findplus juste un moyen sûr rm, donc vous vous remercierez plus tard si vous prenez le temps d'apprendre à utiliser find.

aculich
la source
Discussion très intéressante. J'aime votre approche et fait un petit extrait. C'est super inefficace, puisqu'il appelle au plus 3 fois, mais pour moi c'est un bon début: github.com/der-Daniel/fdel
Daniel Hitzel
14

Il y a de très mauvais conseils dans ce fil, heureusement, la plupart ont été rejetés.

Tout d’abord, lorsque vous devez être root, devenez root - sudo et les diverses astuces de pseudonymes vous affaibliront. Et pire, ils vont vous rendre imprudent. Apprenez à bien faire les choses, arrêtez de vous fier à des alias pour vous protéger. Un jour, vous allez vous planter dans une boîte qui n’a pas vos roues d’entraînement et qui fait sauter quelque chose.

Deuxièmement, lorsque vous avez la racine, pensez à vous-même comme conduisant un bus rempli d'écoliers. Parfois, vous pouvez écouter la chanson à la radio, mais d'autres fois, vous devez regarder dans les deux sens, ralentir les choses et vérifier tous vos miroirs.

Troisièmement - vous n’avez pratiquement jamais vraiment à le faire rm -rf- plus probablement vous voulez mv something something.bakoumkdir _trash && mv something _trash/

Quatrième - toujours lsvotre wildcard avant rm- Il n'y a rien de fou à regarder quelque chose avant de le détruire pour toujours.

événements
la source
2
+1 pour l'utilisation de ls.
Sachin Divekar
@ eventi Je suis d'accord qu'il y a quelques conseils terribles et hacks laids dans ce fil. Et c'est certainement une bonne idée de regarder quelque chose avant de le détruire, mais il existe un moyen encore meilleur de le faire en utilisant la findcommande .
Aculich
Je ne vois pas en quoi la recherche est plus simple ou plus sûre, mais j'aime votre find . -name '*~'exemple. Mon point est que lslistera le même glob qui rmutilisera.
eventi
11

Ceci est standard pour les expressions rationnelles dans le contexte de rm, mais cela vous aurait sauvé dans ce cas.

Je le fais toujours en echo foo*/[0-9]*{bar,baz}*premier, pour voir ce que l'expression rationnelle va correspondre. Une fois que j'ai la sortie, je reviens avec l'édition en ligne de commande et passe echoà rm -rf. Je n'utilise jamais, jamais, rm -rfsur une expression rationnelle non testée .

Chapelier Fou
la source
5
OK, qu'est-ce que je cherche? Souhaitez-vous indiquer que la syntaxe de l'expression rationnelle pour la correspondance de fichiers est différente (et parfois appelée par un nom différent) de celle utilisée par exemple dans perl? Ou un autre point que j'ai manqué? Je m'excuse pour la lenteur de mes pensées, c'est samedi matin à la première heure!
MadHatter
9
Ces choses que vous appelez "regexp" sont en fait des globes. Ce n'est pas une syntaxe de regex différente; ce n'est pas une regex.
bukzor
1
Cet argument pourrait certainement être avancé. Cependant, dans l'article de Wikipédia sur les expressions régulières, je trouve que "De nombreux systèmes informatiques modernes fournissent des caractères génériques dans les noms de fichiers correspondants d'un système de fichiers. Il s'agit d'une fonctionnalité essentielle de nombreux shells de ligne de commande, également appelée" globbing "- notez le utilisation de "également connu sous le nom", ce qui me semble indiquer que les jetons d'appel contenant des métacaractères pour correspondre à un ou plusieurs noms de fichier regexps ne sont pas faux. Je conviens que «globbing» est un meilleur terme car il ne signifie rien d’autre que l’utilisation d’expressions régulières dans la recherche du nom de fichier.
MadHatter
1
@MadHatter En outre, la segmentation, bien que visuellement assez similaire, est très différente sémantiquement des expressions régulières. Dans une expression rationnelle, le sens de *a une définition très précise appelée Kleene Star, un opérateur unaire qui correspond à zéro ou plusieurs éléments de l'ensemble auquel il s'applique (dans le cas d'expressions régulières, le caractère ou l'ensemble de caractères précédant le Kleene Star), alors que les globules *correspondent à tout ce qui suit. Ils sont sémantiquement très différents même s’ils semblent avoir une syntaxe similaire.
Aculich
9

La solution à ce problème consiste à effectuer des sauvegardes régulières. Chaque fois que vous produisez quelque chose que vous ne voulez pas risquer de perdre, sauvegardez-le. Si vous trouvez que la sauvegarde régulière est trop pénible, simplifiez le processus pour le rendre moins douloureux.

Par exemple, si vous travaillez sur le code source, utilisez un outil gitpermettant de dupliquer le code et de conserver l'historique sur une autre machine. Si vous travaillez sur des documents, utilisez un script qui rsyncles transfère sur une autre machine.

David Schwartz
la source
Un système de fichiers de copie sur écriture tel que btrfs peut également vous aider. Vous pouvez facilement configurer une simple rotation automatisée d'instantané qui s'exécute localement (en plus d'une sauvegarde externe).
Malthe
6

Il semble que le meilleur moyen de réduire ce risque est d’avoir une suppression en deux étapes comme la plupart des interfaces graphiques. Autrement dit, remplacez rm par quelque chose qui déplace les éléments dans un répertoire de la corbeille (sur le même volume). Ensuite, nettoyez cette corbeille après un délai suffisant pour constater toute erreur.

Un tel utilitaire, trash-cli, est présenté ici sous Unix StackExchange .

noisette
la source
C'est la première chose que j'installe sur chaque machine. Il devrait s'agir de l'outil de suppression par défaut, avec rm utilisé uniquement lorsque vous devez absolument supprimer quelque chose pour le moment. Je suis triste que cela ne soit pas encore parti, mais un jour, ça ira. Probablement après une instance très publique de rm causant un énorme problème auquel les sauvegardes n'auraient pas pu remédier. Probablement quelque chose où le temps nécessaire pour récupérer joue un facteur énorme.
Gerry
+1 Après avoir utilisé linux pendant 20 ans, je pense toujours qu'il devrait exister une sorte de comportement de poubelle rm.
Shovas
3

Un facteur clé important pour éviter ce type d'erreur est de ne pas se connecter avec un compte root. Lorsque vous vous connectez à l'aide d'un utilisateur normal non privilégié, vous devez utiliser sudopour chaque commande. Donc, vous devriez être plus prudent.

Khaled
la source
4
Je ne suis pas convaincu que Sudo empêcherait quelque chose comme ça. Vous pouvez créer la même faute de frappe que OP, même si vous tapez "sudo" avant "rm".
cjc
1
Mentionné travaillant en tant que root dans le montage
Valentin Nemcev
Si vous n'êtes toujours pas convaincu de l'utilisation sudoet des sauvegardes. Consultez cette page: forum.synology.com/wiki/index.php/… . Il parle de créer une corbeille. J'espère que cela t'aides!
Khaled
1
@Khaled J'utilise sudo et des sauvegardes, je veux juste quelque chose de mieux pour ce problème spécifique
Valentin Nemcev
3

Lorsque je supprime un répertoire de manière récursive, je place le -ret, le -fcas échéant, à la fin de la commande, par exemple rm /foo/bar -rf. Ainsi, si j’appuie accidentellement trop tôt sur Entrée, sans avoir encore saisi le chemin complet, la commande n’est pas récursive, elle est donc probablement inoffensive. Si je bosse Entrée en essayant de taper la barre oblique après /foo, j'ai écrit rm /fooplutôt que rm -rf /foo.

Cela fonctionne bien sur les systèmes utilisant GNU coreutils, mais les utilitaires de certains autres Unix ne permettent pas de placer les options à la fin de cette façon. Heureusement, je n'utilise pas de tels systèmes très souvent.

Wyzard
la source
2

Cela peut être compliqué, mais vous pouvez configurer des rôles dans SELinux de sorte que même si l’utilisateur devient root via sudo su - (ou tout simplement su), la possibilité de supprimer des fichiers peut être limitée (vous devez vous connecter directement en tant que root pour supprimer des dossiers). Si vous utilisez AppArmor, vous ferez peut-être quelque chose de similaire .

Bien entendu, l’autre solution serait de vous assurer que vous avez des sauvegardes. :)

Rilindo
la source
2

Évitez d'utiliser globbing . Dans Bash, vous pouvez définir noglob. Mais encore une fois, lorsque vous passez à un système où noglobaucun paramètre n’est défini, vous pouvez l’oublier et procéder comme si de rien n’était.

Définir noclobberpour empêcher mvet cpdétruire les fichiers aussi.

Utilisez un navigateur de fichiers pour la suppression. Certains navigateurs de fichiers proposent une corbeille (par exemple, Konqueror ).

Une autre façon d’éviter les dérapages est la suivante. En ligne de commande, je echo filenamepattern >> xxx. Ensuite, je modifie le fichier avec Vim ou vi pour vérifier quels fichiers doivent être supprimés (surveillez les caractères de modèle de nom de fichier dans les fichiers.), Puis je %s/^/rm -f/transforme chaque ligne en une commande de suppression. Source xxx. De cette façon, vous voyez tous les fichiers qui vont être supprimés avant de le faire.

Déplacez les fichiers dans un répertoire 'attique' ou une archive. Ou utilisez le contrôle de version (comme dit avant moi).

Andrej Panjkov
la source
+1 pour utiliser une méthode de prévisualisation de vos fichiers avant de les supprimer, mais il existe des moyens plus simples et plus sûrs de le faire en utilisant la findcommande .
Aculich
2

Le ZSH me demande (par défaut) avant d’effectuer une rm -rf *.

math
la source
1

En dehors de chattr, il n'y a pas beaucoup de garanties de laisser root exécuter une telle commande. C'est pourquoi les groupes appropriés et les commandes soigneuses sont importants lors de l'exécution de privilèges.

La prochaine fois; définissez les fichiers que vous souhaitez supprimer - omettez «f» dans rm -rf, ou utilisez-le findet transmettez-le àxargs rm

mince
la source
Il est bon que vous suggériez l’utiliser find, mais je recommande une méthode plus sûre pour l’utiliser dans ma réponse . Il n'y a aucun besoin d'utiliser xargs rmpuisque toutes les versions modernes findont l' -deleteoption . En outre, pour utiliser en toute sécurité, xargs rmvous devez également utiliser find -print0et xargs -0 rmsinon, vous aurez des problèmes lorsque vous rencontrez des problèmes tels que des noms de fichiers avec des espaces.
Aculich
Mon point n'était pas sur les nuances à propos de xargs mais plutôt sur trouver d'abord, sans supprimer de fichiers, puis continuer ..
thinice
Oui, je pense que la délimitation des fichiers en utilisant findest une bonne suggestion, mais les nuances xargssont importantes si vous suggérez de les utiliser, sinon cela crée de la confusion et de la frustration lorsque vous rencontrez des fichiers avec des espaces (évitez-les en utilisant l' -deleteoption).
Aculich
1

Certains alias de sécurité pour d'autres commandes, afin d'éviter des catastrophes similaires, se trouvent ici :

# 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'

Remarquez la majuscule -I, elle est différente de -i:

invite une fois avant de supprimer plus de trois fichiers ou lors d’une suppression récursive. Moins intrusif que -i, tout en offrant une protection contre la plupart des erreurs

Valentin Nemcev
la source
Bien que l'option I ne répète pas ce que vous allez supprimer.
Calmarius
1

J'utilise habituellement le -vdrapeau pour voir ce qui est supprimé et avoir une chance de le faire ^Crapidement si j'ai le moindre doute. Pas vraiment un moyen d' empêcher les mauvais rm« s, mais cela peut être utile de limiter les dommages en cas quelque chose se passe mal.

a3nm
la source
1

Mon processus de suppression sur les machines Unix est le suivant.

  • Tapez ls /path/to/intented/file_or_directorydans la fenêtre du terminal, puis appuyez sur return(ou Tab, si vous le souhaitez) pour voir la liste des fichiers.

Si tout va bien,

  • cliquez sur la up arrowclé à récupérer à ls /path/to/intented/file_or_directorypartir de l'historique du terminal.

  • remplacer lspar rmou rm -rou rm -rf, selon les besoins. Personnellement, je n'aime pas utiliser le -fdrapeau.

Ce processus de validation empêche également l'exécution prématurée de la rmcommande, quelque chose qui m'est arrivé, avant que je ne commence à suivre ce processus.

Mohit Ranka
la source
Prévisualiser les fichiers avant de les supprimer est une bonne idée, et il existe un moyen encore plus sûr et plus expressif de le faire à l'aide de la commande find telle que je l'explique dans ma réponse .
Aculich
1

Si vous n'êtes pas d'humeur à acquérir de nouvelles habitudes pour le moment, il .bashrc/.profileest judicieux d'ajouter des tests pour vérifier si vous êtes sur le point de faire quelque chose de stupide. Je pensais que dans une fonction Bash, je pouvais rechercher un motif susceptible de gâcher ma journée et voici ce qui suit:

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
}

La bonne chose à ce sujet est que ce n'est que Bash.

Ce n'est clairement pas assez générique dans cette forme, mais je pense que cela a du potentiel, alors merci de poster quelques idées ou commentaires.

kln
la source
C'est bien que vous essayiez de prévisualiser vos fichiers avant de les supprimer, mais cette solution est trop compliquée. Vous pouvez plutôt accomplir cela très simplement de manière plus générique à l'aide de la findcommande . En outre, je ne comprends pas pourquoi vous dites "la bonne chose à ce sujet est qu'il ne s'agit que de Bash"? Il est recommandé d' éviter les bash-isms dans les scripts .
Aculich
Pour nous empêcher de "rm -rf / *" ou "rm -rf dir / *" lorsque nous voulons dire "rm -rf ./*" et "rm -rf dir / *", nous devons détecter les modèles "/ *" et "*" (simplistiquement). Cependant, nous ne pouvons pas simplement transmettre tous les arguments de la ligne de commande à grep en recherchant un motif préjudiciable, car bash développe les arguments génériques avant de les transmettre (star sera étendu à tout le contenu d’un dossier). Nous avons besoin de la chaîne d'argument "raw". Cette opération est effectuée avec set -f avant d'appeler la fonction "myrm", à laquelle est ensuite transmise la chaîne d'argument brut et grep recherche des modèles prédéfinis. *
kln
Je comprends ce que vous essayez de faire avec set -fce qui est équivalent set -o noglobdans Bash, mais cela n’explique toujours pas votre déclaration selon laquelle "la bonne chose à ce sujet est qu’il s’agit uniquement de Bash". Au lieu de cela, vous pouvez éliminer le problème entièrement et de manière générique pour n’importe quel shell en n’utilisant pas rmdu tout, mais en utilisantfind plutôt la commande . Avez-vous réellement essayé cette suggestion pour voir comment elle se compare à ce que vous suggérez ici?
Aculich
@aculich par seulement bash je veux dire pas de dépendances python ou perl, tout peut être fait en bash. Une fois que je modifie mon .bashrc je peux continuer à travailler sans avoir à casser de vieilles habitudes. Chaque fois que j'invoque rm bash, je m'assure que je ne fais pas une bêtise. Il me suffit de définir certains modèles pour lesquels je souhaite être alerté. Comme "*" qui supprimerait tout ce qui se trouve dans le dossier actuel. Chaque fois, ce sera exactement ce que je veux, mais avec un peu plus de travail, vous pouvez ajouter de l’interactivité à "myrm".
Kln
@aculich OK gotcha.Non je ne l'ai pas essayé.Je pense que cela nécessite des changements importants dans le flux de travail. Je viens de vérifier ici sur Mac OS X que mon .bash_history vaut 500 et que 27 de ces commandes sont rm. Et ces jours-ci, je n'utilise pas très souvent un terminal.
Kln
1

Malheureusement, je ne peux pas laisser un commentaire ci-dessus en raison d'un karma insuffisant, mais je voulais avertir les autres que le safe-rm n'est pas une panacée pour les cauchemars effacés par suppression de masse.

Les éléments suivants ont été testés sur une machine virtuelle Linux Mint 17.1 (avertissant ceux qui ne sont pas familiers avec ces commandes: ne le faites pas! En fait, même ceux qui sont familiers avec ces commandes ne devraient / ne feraient probablement jamais cela pour éviter une perte de données catastrophique):

Version textuelle (condensée):

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

Version de l'image (complète):

entrez la description de l'image ici

Miles Wolbe
la source
1

J'aime l'approche Windows de la corbeille.

Je crée habituellement un répertoire nommé "/ tmp / recyclebin" pour tout ce que je dois supprimer:

mkdir /tmp/recyclebin

Et n'utilisez jamais rm -rf, j'utilise toujours:

mv target_folder /tmp/recyclebin

Puis, plus tard, je vide la corbeille à l’aide d’un script ou manuellement.

Basilic a
la source
0

Hehe (non testé et un peu facétieusement!):

$ 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

Puis:

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

De manière réaliste, vous devriez faire une pause mentale avant d'exécuter ce type d'opération avec un glob, que vous soyez en tant que root, avec une annonce "sudo", etc. Vous pouvez exécuter un "ls" sur le même glob, etc., mais, mentalement, vous devriez vous arrêter un instant, assurez-vous de taper ce que vous voulez, assurez-vous de ce que vous voulez réellement, etc. Je suppose que c'est quelque chose que l'on apprend principalement en détruisant quelque chose la première année Un SA, de la même manière que le brûleur brûlant est un bon enseignant en vous disant que quelque chose sur le poêle peut être chaud.

Et assurez-vous d'avoir de bonnes sauvegardes!

cjc
la source
J'essaie de réfléchir à deux fois avant de faire des choses dangereuses, mais d'une manière ou d'une autre, cela ne fonctionne pas toujours, j'ai déjà détruit des choses à cause d'inattention comme celle-ci.
Valentin Nemcev
0

En outre, non pas comme une sauvegarde, mais comme moyen de savoir quels fichiers ont été supprimés avant que vous n’ayez appuyé sur ^ C, vous pouvez utiliser la locatebase de données (bien sûr, seulement si elle a été installée et a survécu rm)

Je l'ai appris de ce blog

Valentin Nemcev
la source
0

Utilisez simplement ZFS pour stocker les fichiers dont vous avez besoin pour résister à une suppression accidentelle et disposez d'un démon qui:

  • fait régulièrement des instantanés de ce système de fichiers
  • supprime les instantanés anciens / inutiles.

Si des fichiers sont supprimés, écrasés, corrompus, quoi que ce soit, restaurez simplement votre système de fichiers sur un clone du dernier bon instantané et vous avez terminé.

jlliagre
la source
0

pas tellement une réponse, mais un pourboire, je ne le fais rm (dir) -rfpas toujours, rm -rf (dir)c.-à-d. ne faites pas le nucléaire jusqu'au dernier moment possible.

Cela permet d’atténuer les situations dans lesquelles vous avez inséré le nom du répertoire de telle sorte que la suppression reste valide, telle que le glissement et la frappe de la touche Entrée.

Sirex
la source
Intelligent, mais ne fonctionnerait pas sous BSD rm, où les options doivent précéder les noms de fichiers.
Svenper
Ouais. Je l'ai découvert en utilisant Apple récemment. Le correctif consiste à installer les outils GNU et à définir des alias pour tout :) et / ou, de préférence, à jeter la pomme dans une corbeille. :)
Sirex
1
si je le pouvais, je le ferais en une nanoseconde. C'est des ordures par rapport à linux.
Sirex
0

Je pense que ceci est une astuce de prévention puissante, avec * un raccourci d’extension dans le shell:

D'abord, tapez rm -rf *ou rm -rf your/path/*, NE PAS taper de Enterclé. (bien sûr, vous devriez avoir l'habitude de ne pas appuyer sur Entrée rapidement / accidentellement lorsque vous l'utilisez rm -rf)

Ensuite, appuyez sur Alt-Shift-8(ie Alt-Shift-*) pour développer explicitement le caractère générique "*" dans bash. Cela évite également de ressaisir une commande "rm -rf *" lors de la navigation dans l'historique.

Enfin, après avoir vérifié que l’extension contient les bons fichiers / répertoires, appuyez sur Entrée.

Terminé.

Johnny Wong
la source
0

Si cela aide quelqu'un pour son propre cas:

1. Utiliser rmsafe:

Il déplace les fichiers dans un dossier "corbeille" et vous avez toujours la possibilité de les ramener avec un simple mv:

$ rmsafe /path/to/important/files

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

2. Utiliser safe:

Vous pouvez définir un alias pour rmutiliser safe:

$ alias rm="safe rm"

Maintenant, si vous courez, rm /*vous obtenez ceci en réponse:

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

et je crois que vous ne taperez pas y!

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

Alexar
la source