Quelle est la raison pour laquelle rmdir (1) et rm (1) coexistent?
17
J'utilise BSD et Linux tous les jours, je n'ai jamais eu de circonstance où je dois utiliser rmdir (1) plutôt que rm (1). Quel est le but de l'existence de rmdir?
La raison principale est probablement historique. De retour dans les vieux, les vieux jours, il n'y avait pas rmdir(2)et les mkdir(2)appels système (nous discutons 7e édition UNIX ™ ici), et rmdir(1)était ( la nécessité) d' un programme de racine de SUID qui a utilisé l' unlink(2)appel système pour supprimer les répertoires.
La rmcommande (un programme non SUID normal) a appelé la rmdir(1)commande pour supprimer les répertoires vides. Il ne pouvait pas le faire lui-même; qui nécessitait des privilèges root. Ainsi, la rmdir(1)commande (voir ici pour son code source dans Unix V7) existait pour supprimer les répertoires vides, et la rmcommande ne supprimait pas elle-même les répertoires vides.
Pour utiliser rmpour supprimer des répertoires, vous devez donner l' -roption.
Il y a aussi un argument de symétrie. Vous avez besoin d'une commande mkdir(1)pour créer des répertoires; il semble raisonnable d'avoir une commande rmdir(1)pour annuler ce qui mkdir(1)s'est produit. De plus , ils sont (ces jours -ci ) exercisors simples des les rmdir(2)et mkdir(2)appels système - oui, de retour dans la 7ème édition UNIX, mkdir(1)était également un programme de racine de SUID, en utilisant l' mknod(2)appel pour créer un nœud de répertoire et l' link(2)appel à créer .et ..entrées dans le répertoire .
Agréable. Je viens de vérifier une copie de 3BSD que j'ai ici et il n'y a pas non plus de documentation pour un appel système rmdir, et rmdir (1) est toujours implémenté en utilisant unlink.
Andy Ross
4
Un inconvénient majeur du système de liaison et de dissociation mknod + était que la création d'un répertoire n'était pas une opération atomique, vous pourriez donc vous retrouver avec un répertoire partiellement complet. Il y avait beaucoup de programmes conçus pour vérifier les systèmes de fichiers pour les incohérences qui se sont produites; fsck(1)est celui qui a survécu.
Jonathan Leffler
@Jonathan, ramenant des souvenirs de Xenix sur celui-ci. Beurk! Oui, de très mauvaises choses pourraient arriver.
Fiasco Labs
6
"rm" ne fonctionne pas sur les répertoires. Vous devez soit utiliser rmdir, soit spécifier le commutateur -r pour une suppression récursive. La raison est historique: unlinket rmdirsont des appels système séparés et ont été dès les premiers jours d'Unix.
Un effet secondaire heureux est que vous êtes légèrement moins susceptible de supprimer accidentellement un répertoire lorsque vous avez l'intention de supprimer uniquement un fichier.
Je vous remercie. J'ai remarqué que "rm -r" et "rmdir" ont la même quantité de touches. Rmdir existe-t-il uniquement pour des raisons historiques (.. étant compatible avec des programmes Unix vieux de plusieurs décennies)?
2
En fait, dans les premiers jours d'Unix, rmdir(2)ni mkdir(2)n'existait en tant qu'appel système; l'utilisateur rootpourrait utiliser l' mknod(2)appel pour créer un nœud d'annuaire et l' link(2)appel pour créer les entrées .et ..dans l'annuaire; et rootpourrait utiliser l' unlink(2)appel pour supprimer les entrées du répertoire.
Jonathan Leffler
3
De plus, rmdir ne supprime que les répertoires vides . Si vous voulez vous assurer de ne supprimer aucun fichier supplémentaire dans un répertoire, rmdirc'est plus sûr que rm -r(sauf si vous avez un alias rm tel que vous devez toujours confirmer ce que vous supprimez, c'est- alias rm='rm -i'à- dire dans ~ / .bashrc ou tout ce que vous utilisez ).
En outre, rmdiril est facile de supprimer des répertoires vides avec des expressions globales (caractères génériques). Par exemple, pour supprimer tous les répertoires vides /tmpsans toucher aux fichiers ou répertoires contenant du contenu:
Pensez à utiliser rmdir /tmp/*. Si le /tmprépertoire est vraiment volumineux, cela peut manquer d'espace pour les arguments un peu plus rapidement en raison des cinq caractères supplémentaires par nom, mais cela ne nécessite pas de cdvous déplacer dans la hiérarchie du répertoire. Il convient également d'envisager rmdir /tmp/* 2>/dev/nulld'éviter de voir des messages d'erreur (il y en aura généralement beaucoup, et presque tous ne seront pas pertinents pour cette tâche à accomplir).
Réponses:
La raison principale est probablement historique. De retour dans les vieux, les vieux jours, il n'y avait pas
rmdir(2)
et lesmkdir(2)
appels système (nous discutons 7e édition UNIX ™ ici), etrmdir(1)
était ( la nécessité) d' un programme de racine de SUID qui a utilisé l'unlink(2)
appel système pour supprimer les répertoires.Les manuels UNIX de la 7e édition sont disponibles en ligne à http://cm.bell-labs.com/7thEdMan (dernière vérification 2017-04-23); Ils sont également disponibles sur http://plan9.bell-labs.com/7thEdMan (dernière vérification 2017-04-23). Il semble également y avoir au moins une source alternative en ligne - http://wolfram.schneider.org/bsd/7thEdManVol2/ - pour les articles du Volume 2, avec un lien vers le site FreeBSD pour les commandes et les appels système du Volume 1 .
La
rm
commande (un programme non SUID normal) a appelé larmdir(1)
commande pour supprimer les répertoires vides. Il ne pouvait pas le faire lui-même; qui nécessitait des privilèges root. Ainsi, larmdir(1)
commande (voir ici pour son code source dans Unix V7) existait pour supprimer les répertoires vides, et larm
commande ne supprimait pas elle-même les répertoires vides.Pour utiliser
rm
pour supprimer des répertoires, vous devez donner l'-r
option.Il y a aussi un argument de symétrie. Vous avez besoin d'une commande
mkdir(1)
pour créer des répertoires; il semble raisonnable d'avoir une commandermdir(1)
pour annuler ce quimkdir(1)
s'est produit. De plus , ils sont (ces jours -ci ) exercisors simples des lesrmdir(2)
etmkdir(2)
appels système - oui, de retour dans la 7ème édition UNIX,mkdir(1)
était également un programme de racine de SUID, en utilisant l'mknod(2)
appel pour créer un nœud de répertoire et l'link(2)
appel à créer.
et..
entrées dans le répertoire .la source
fsck(1)
est celui qui a survécu."rm" ne fonctionne pas sur les répertoires. Vous devez soit utiliser rmdir, soit spécifier le commutateur -r pour une suppression récursive. La raison est historique:
unlink
etrmdir
sont des appels système séparés et ont été dès les premiers jours d'Unix.la source
rmdir(2)
nimkdir(2)
n'existait en tant qu'appel système; l'utilisateurroot
pourrait utiliser l'mknod(2)
appel pour créer un nœud d'annuaire et l'link(2)
appel pour créer les entrées.
et..
dans l'annuaire; etroot
pourrait utiliser l'unlink(2)
appel pour supprimer les entrées du répertoire.De plus, rmdir ne supprime que les répertoires vides . Si vous voulez vous assurer de ne supprimer aucun fichier supplémentaire dans un répertoire,
rmdir
c'est plus sûr querm -r
(sauf si vous avez un alias rm tel que vous devez toujours confirmer ce que vous supprimez, c'est-alias rm='rm -i'
à- dire dans ~ / .bashrc ou tout ce que vous utilisez ).la source
En outre,
rmdir
il est facile de supprimer des répertoires vides avec des expressions globales (caractères génériques). Par exemple, pour supprimer tous les répertoires vides/tmp
sans toucher aux fichiers ou répertoires contenant du contenu:la source
rmdir /tmp/*
. Si le/tmp
répertoire est vraiment volumineux, cela peut manquer d'espace pour les arguments un peu plus rapidement en raison des cinq caractères supplémentaires par nom, mais cela ne nécessite pas decd
vous déplacer dans la hiérarchie du répertoire. Il convient également d'envisagerrmdir /tmp/* 2>/dev/null
d'éviter de voir des messages d'erreur (il y en aura généralement beaucoup, et presque tous ne seront pas pertinents pour cette tâche à accomplir).