Kann rm leere Verzeichnisse rekursiv entfernen?

9

In einer alten Version von Unix rmlöschte der Befehl Verzeichnisse, wenn sie leer waren. In der Manpage der Research Unix Eighth Edition für rm : "Wenn ein Eintrag ein Verzeichnis ist, wird er nur entfernt, wenn er leer ist." Ich mag dieses Verhalten, daher habe ich diesen Alias ​​in meinem /etc/profile: alias rm='rm -d'Ich verwende die GNU-Coreutils-Version von rm, in der -dangewiesen wird rm, Verzeichnisse zu entfernen, wenn sie leer sind.

So weit, ist es gut. Dieser Alias ​​ermöglicht es mir, rmwie früher zu verwenden. Ich möchte jedoch noch einen Schritt weiter gehen. ich würde gernermein Verzeichnis zu löschen, auch wenn das Verzeichnis andere Verzeichnisse enthält, solange nur Verzeichnisse vorhanden sind. Es spielt keine Rolle, wie tief die Verzeichnisstruktur reicht, solange sich keine Dateien darin befinden. Ich möchte nur rmalle Verzeichnisse entfernen, sobald Sie ganz unten sind .

Könnte dies als Alias ​​geschrieben werden, der weiterhin als regulärer Alias ​​fungiert rmund alle an ihn übergebenen Dateien löscht?

WhiteHotLoveTiger
quelle
Wie wäre es rmdir -p?
Kevin
Vielen Dank für den Vorschlag Kevin, aber das ist nicht ganz das Verhalten, das ich suche. Wenn ich renne mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, habe ich immer noch a, a / b2 und a / b2 / c2. Ich möchte nur die oberste Ebene (in diesem Fall a) übergeben rmund alles darunter entfernen lassen.
WhiteHotLoveTiger

Antworten:

8

Sie möchten einen Verzeichnisbaum durchlaufen und prüfen, ob er etwas anderes als ein Verzeichnis enthält. Dies geht über rmdie Möglichkeiten hinaus. Sie benötigen andere Tools wie find. Sie können die leeren Verzeichnisse unter einem bestimmten Verzeichnis auf diese Weise löschen ( -depthbewirkt, dass auch leere übergeordnete Verzeichnisse gelöscht werden):

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

Hier ist eine Funktion, die für jedes Argument das Argument löscht, wenn es sich um eine Nicht-Verzeichnisdatei oder einen Verzeichnisbaum handelt, der nichts anderes als Verzeichnisse enthält. Beachten Sie, dass diese Funktion nicht atomar ist: Wenn sich eines der Argumente während der Ausführung ändert, wird möglicherweise eine Fehlermeldung angezeigt. Es ist jedoch sicher, dass kein Nichtverzeichnis in einem als Argument übergebenen Verzeichnis gelöscht wird.

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 - hör auf böse zu sein'
quelle