Rm -rf * supprimera-t-il tous les fichiers / dossiers du répertoire actuel?

20

Est-ce que rm -rf *supprimer tous les fichiers / dossiers dans le répertoire courant? Je veux m'assurer que le caractère générique *ne montera pas dans les répertoires supérieurs et effacera tout mon système de fichiers. :RÉ

Je me souviens faire chmod 777 .* -Rà des chmodfichiers cachés et chmoded tout mon système de fichiers. Évidemment, j'étais sur le compte root.

Olivier Lalonde
la source
1
C'est pourquoi je ferais rm -rf ./*et spécifierais explicitement le répertoire courant ... mais Ankur semble dire que cela n'a pas d'importance de toute façon.
mpen
@Mark: quelle est la différence entre .. et ./ ..? Vous pouvez essayer de cd ./ .. et voir où vous vous retrouvez :)
Johan
@Johan: Aucune différence ... Je suppose que cela a plus de sens dans ma tête folle: D
mpen
@Mark: erreur facile à faire :)
Johan

Réponses:

15

Non, si vous n'avez pas beaucoup modifié votre shell, cela ne supprimera pas les fichiers ou répertoires commençant par a .. Pour les supprimer également, vous pouvez soit les répertorier explicitement

rm -rf .file .dir

ou utilisez les bons motifs globaux (merci Chris)

rm -rf .[^.]* ..?*

EDIT Le point ici est que vous ne pouvez pas utiliser .*pour faire correspondre des fichiers comme .file, car .*ou .*?correspondra également à ..ou .. .[^.]*correspond à des fichiers comme .file, tandis que ..?*correspond à des fichiers comme ..foo( *correspond à zéro ou plusieurs caractères et ?correspond exactement à un).

Benjamin Bannier
la source
1
Vous avez également besoin de quelque chose comme ..?*pour intercepter les entrées qui commencent par «..» (par exemple ..foo).
Chris Johnsen
@Chris: OK, j'ai commencé cette folie pointilleuse, vous avez raison;)
Benjamin Bannier
ce n'est pas seulement d'utiliser les «bons» motifs globaux, c'est aussi la quantité d'articles assortis. dans les répertoires contenant une énorme quantité de fichiers, le shell n'est probablement pas en mesure de donner 50 000 fichiers en un tour rm. donc, supprimer le contenu d'un répertoire avec * n'est pas le moyen le plus sage, à mon humble avis.
akira
Je pense que l'explication xargsdépasse un peu la portée de cette question. On pourrait par exemple commencer à y penser lorsque le shell se plaint de la longueur des listes d'arguments.
Benjamin Bannier
1
Je pense que ce n'est pas hors de portée car je pense que OP ne sait pas comment atteindre son problème / solution ultime: supprimer tout le contenu du répertoire. OP ne fait que faire la «mauvaise» chose générale en ayant déjà en tête une solution (une mauvaise) et en demandant pourquoi cette solution pose problème. la meilleure approche serait: "comment supprimer tous les fichiers d'un répertoire sans supprimer le répertoire lui-même?" La solution d'OP causera des problèmes en raison de la nature même du fonctionnement de la globalisation.
akira
12

Si vous souhaitez supprimer un répertoire et tout son contenu, vous pouvez chdiraccéder au répertoire parent et à rm -rfce répertoire par son nom, en contournant toute la question de globalisation. Si vous souhaitez supprimer le contenu mais conserver le répertoire, il est plus simple de tout supprimer puis de recréer le répertoire.

Il est complexe de trouver un glob qui correspondra à toutes les entrées de répertoire possibles enregistrées. et ..; il est facile de trouver une réponse simple (par exemple, * .??*) qui fonctionnera presque toujours dans la pratique. C'est OK pour une utilisation interactive, car il est facile à retenir et les moments où cela ne fonctionne pas peuvent être capturés avec un post-rm ls -a. Pour un script, il est plus facile de supprimer tout et de recréer le répertoire vide.

mpez0
la source
1
C'est ce que je suggérerais aussi: jeter le répertoire et c'est fait
akira
Même toi ce n'est pas la réponse c'est une bonne idée.
Johan
10

Puisque je pense que cette question concerne davantage ce que * fait (et non rm), essayons une autre approche.


Si vous n'êtes pas sûr de ce que fait le *, vous pouvez d'abord "tester" en utilisant une commande inoffensive comme echo. Avant d'exécuter cela, essayez de deviner ce qu'ils afficheront si vous les exécutez dans votre répertoire personnel.

echo *
echo .*

Mais d'abord, créons un terrain de jeu afin que nous puissions jouer avec les étoiles et voir avec quoi nous nous retrouvons.

mkdir ~/star_test/
cd ~/star_test/
>.file1
>file2

Maintenant, dans ce dir, nous avons ceci:

cj@zap:~/star_test$ ls -1a
.
..
.file1
file2

Notez maintenant ce que le * développe en utilisant la commande echo:

cj@zap:~/star_test$ echo *
file2
cj@zap:~/star_test$ echo .*
. .. .file1

Voyons donc ce qui se passe avec la commande rm

cj@zap:~/star_test$ rm -rf *
cj@zap:~/star_test$ ls -1a
.
..
.file1

Comme vous le voyez, il n'a supprimé que le fichier2, car * ne s'est étendu qu'au fichier2. Si vous tapez rm -rf. *, Ce serait la même chose que d'écrire

rm -rf . .. .file1

Et pour être honnête, ça n'a pas l'air sympa;)

J'espère que cela clarifie la partie * de votre question.


Mise à jour: Cependant, comme le souligne Ankur Goel, il existe une sorte de protection intégrée à rm (un peu inhabituel pour les commandes shell :)

Créons un nouveau terrain de jeu:

cd ~/star_test/
mkdir -p test1/test2/test3
sudo chown root.root test1
cd test1/test2/test3/
>.file1
>file2

Alors maintenant, nous avons à nouveau cela, mais avec test1 appartenant à root comme protection si rm commence à devenir fou.

cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2  .file1
cj@zap:~/star_test/test1/test2/test3$ echo .*
. .. .file1

Supprimons donc tout:

cj@zap:~/star_test/test1/test2/test3$ rm -rf .*
rm: cannot remove directory `.'
rm: cannot remove directory `..'
cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2

Et il semble que rm n'ait pas été supprimé. et .. même si on le lui avait dit !!!

Donc, après cette longue réponse, il s'avère sûr de tout supprimer dans un répertoire avec ceci:

rm -rf * .*

Mais je l'utiliserais avec précaution, car je ne suis pas sûr que toutes les implémentations de rm se comportent comme ça!

Johan
la source
7

Oui. rm -rf supprimera uniquement les fichiers et dossiers du répertoire en cours et ne remontera pas dans l'arborescence des fichiers. rm ne suivra pas non plus les liens symboliques et ne supprimera pas les fichiers vers lesquels ils pointent, vous ne supprimez donc pas accidentellement d'autres parties de votre système de fichiers.

Ankur Goel
la source
1

Si vous ne voulez pas monter d'un niveau comme le dit mpez0 et rm -rfce dossier spécifique, il existe un moyen de travailler sur tous les répertoires / fichiers sauf .et ..dans le dossier actuel en faisant:

rm -rf $(ls -A)

Bien sûr, si l'un des répertoires / fichiers contient l'un des caractères de la IFSvariable spéciale du shell (par exemple, espace, tabulation, nouvelle ligne), vous pouvez d'abord changer l'IFS, exécuter la commande, puis restaurer l'IFS.

tzot
la source
0

Un moyen beaucoup plus simple de vider un dossier entier, en évitant également les problèmes de «trop d'arguments» abordés dans cette réponse , consiste simplement à supprimer et à recréer le répertoire lui-même. Pour vous assurer que cela fonctionne correctement lorsque vous êtes dans un répertoire de liens symboliques, utilisez les lignes suivantes:

cd ..
rm -rf $(readlink -f yourdir) #remove the directory, treat the case of a symlink
                        # by using readlink, to recreate the linked-to directory
mkdir $(readlink -f yourdir) # recreate the directory to have it empty
cd yourdir

(Si vous utilisez à la yourdirplace de $(readlink -f yourdir)vous ne remplaceriez le lien que lorsque l'emplacement d'origine reste plein)

Tobias Kienzler
la source
1
Cela peut casser des choses en fonction de l'inode du dossier et jeter les autorisations, atime / mtime / ctime / btime, les attributs étendus et les listes de contrôle d'accès.
Daniel Beck
@DanielBeck merci, bons points. Bien que je me demande, qu'est-ce qui reposerait valablement sur l'inode en dehors des liens physiques (sur les répertoires, qui sont de toute façon fortement déconseillés)? Mais les autorisations, etc. sont importantes. Donc, dans le cas le plus général, on devrait probablement utiliser xargs...
Tobias Kienzler
OS X contient un mécanisme qui peut gérer les fichiers et dossiers déplacés tout en conservant l'association. Plus visible dans le menu Ouvrir les documents récents . AFAICT, il utilise des inodes pour accomplir cela en interne. Plus d'infos . Je ne serais pas surpris si d'autres systèmes implémentaient quelque chose de similaire, par exemple dans les API pour les programmes GUI.
Daniel Beck