¿Puede rm eliminar recursivamente directorios vacíos?

9

En una versión anterior de Unix, el rmcomando eliminaría directorios si estuvieran vacíos. De la página de manual de Research Unix Octava Edición para rm : "Si una entrada es un directorio, se elimina solo si está vacía". Me gusta este comportamiento, así que tengo este alias en mi /etc/profile: alias rm='rm -d'estoy usando la versión de GNU coreutils de rm, en la que me -ddice rmque continúe y elimine los directorios si están vacíos.

Hasta aquí todo bien. Este alias me permite usar rmcomo en los viejos tiempos. Sin embargo, me gustaría ir un paso más allá. me gustaríarmpara eliminar un directorio incluso si el directorio contiene otros directorios, siempre que los directorios sean lo único que hay. No importa cuán profunda sea la estructura del directorio, siempre que no haya ningún archivo allí, solo directorios vacíos (una vez que llegue al final), me gustaría rmeliminarlos a todos.

¿Podría esto escribirse como un alias que todavía funcionaría como el normal rmy eliminaría cualquier archivo que se le pase?

WhiteHotLoveTiger
fuente
¿Qué tal rmdir -p?
Kevin
Gracias por la sugerencia de Kevin, pero este no es el comportamiento que estoy buscando. Si corro mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, todavía me quedan a, a / b2 y a / b2 / c2. Lo que me gustaría es pasar solo el nivel superior (a en este caso) rmy eliminar todo lo que esté debajo.
WhiteHotLoveTiger

Respuestas:

8

Desea atravesar un árbol de directorios y ver si contiene algo más que un directorio. Esto está más allá de rmlas capacidades. Necesita otras herramientas como find. Puede eliminar los directorios vacíos en un directorio dado de esta manera (también -depthhace que los directorios principales que se vuelven vacíos se eliminen):

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

Aquí hay una función que, para cada argumento, elimina el argumento si es un archivo que no es de directorio o un árbol de directorio que no contiene nada más que directorios. Tenga en cuenta que esta función no es atómica: si uno de los argumentos cambia mientras se está ejecutando, puede terminar con un mensaje de error, pero es seguro porque no eliminará ningún directorio que no sea un directorio dentro de un directorio pasado como argumento.

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- deja de ser malvado'
fuente