Rm peut-il supprimer récursivement des répertoires vides?

9

Dans une ancienne version d'Unix, la rmcommande supprimait les répertoires s'ils étaient vides. À partir de la page de manuel Research Unix Eighth Edition pour rm : "Si une entrée est un répertoire, elle n'est supprimée que si elle est vide." J'aime ce comportement, j'ai donc cet alias dans mon /etc/profile: alias rm='rm -d'j'utilise la version GNU coreutils de rm, dans laquelle on -ddit rmd'aller de l'avant et de supprimer les répertoires s'ils sont vides.

Jusqu'ici tout va bien. Cet alias me permet d'utiliser rmcomme autrefois. Cependant, je voudrais aller plus loin. J'aimeraisrmpour supprimer un répertoire même s'il contient d'autres répertoires, tant que les répertoires sont la seule chose qui s'y trouve. Peu importe la profondeur de la structure des répertoires, tant qu'il n'y a pas de fichiers, juste des répertoires vides (une fois que vous êtes en bas), je voudrais rmtous les supprimer.

Pourrait-il être écrit comme un alias qui fonctionnerait toujours comme le normal rmet supprimerait tous les fichiers qui lui sont passés?

WhiteHotLoveTiger
la source
Et alors rmdir -p?
Kevin
Merci pour la suggestion Kevin, mais ce n'est pas tout à fait le comportement que je recherche. Si je cours mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, je reste avec a, a / b2 et a / b2 / c2. Ce que j'aimerais, c'est passer uniquement le niveau supérieur (a dans ce cas) rmet supprimer tout ce qui se trouve en dessous.
WhiteHotLoveTiger

Réponses:

8

Vous voulez parcourir une arborescence de répertoires et voir si elle contient autre chose qu'un répertoire. Cela dépasse rmles capacités de. Vous avez besoin d'autres outils tels que find. Vous pouvez supprimer les répertoires vides sous un répertoire donné de cette façon ( -depthles répertoires parents qui deviennent vides sont également supprimés):

find "$x" -depth -type d -exec rmdir {} +

Voici une fonction qui, pour chaque argument, supprime l'argument s'il s'agit d'un fichier non répertoire ou d'une arborescence répertoire ne contenant rien d'autre que des répertoires. Notez que cette fonction n'est pas atomique: si l'un des arguments change pendant son exécution, vous pouvez vous retrouver avec un message d'erreur, mais il est sûr en ce qu'il ne supprimera aucun non-répertoire dans un répertoire passé en argument.

rm () {
  ret=0
  for x; do
    case $x in -*) x=./$x;; esac
    if [ -d "$x" ]; then
      if [ -n "$(find "$x" ! -type d | head -n 1)" ]; then
        echo 1>&2 "$x: non-empty directory tree"
        ret=2
      else
        find "$x" -depth -exec rmdir {} +
        if [ -d "$x" ]; then ret=2; fi
      fi
    else
      command rm "$x" || [ $ret -gt 1 ] || ret=2
    fi
  done
  return $ret
}
Gilles 'SO- arrête d'être méchant'
la source