Rm può rimuovere ricorsivamente directory vuote?


9

In una vecchia versione di Unix, il rmcomando avrebbe eliminato le directory se fossero vuote. Dalla pagina man di Research Unix Ottava Edizione per rm : "Se una voce è una directory, viene rimossa solo se vuota." Mi piace questo comportamento, quindi ho questo alias nel mio /etc/profile: alias rm='rm -d'sto usando la versione GNU coreutils di rm, in cui -ddice rmdi andare avanti e rimuovere le directory se sono vuote.

Fin qui tutto bene. Questo alias mi permette di usare rmcome ai vecchi tempi. Tuttavia, vorrei fare un ulteriore passo avanti. Mi piacerebbermper eliminare una directory anche se la directory contiene altre directory, purché le directory siano l'unica cosa presente. Non importa quanto sia profonda la struttura della directory, finché non ci sono file lì dentro, solo le directory vuote (una volta arrivate in fondo), vorrei rmrimuoverle tutte.

Potrebbe essere scritto come un alias che funzionerebbe comunque come normale rmed eliminerebbe qualsiasi file passato ad esso?


Che ne dici rmdir -p?
Kevin,

Grazie per il suggerimento Kevin, ma questo non è proprio il comportamento che sto cercando. Se corro mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, rimango ancora con a, a / b2 e a / b2 / c2. Quello che mi piacerebbe è passare solo al livello superiore (a in questo caso) rme rimuovere tutto al di sotto di esso.
WhiteHotLoveTiger

Risposte:


8

Vuoi attraversare un albero di directory e vedere se contiene qualcosa di diverso da una directory. Questo è al rmdi là delle capacità. Hai bisogno di altri strumenti come find. È possibile eliminare le directory vuote in una determinata directory in questo modo (anche le -depthdirectory principali che diventano vuote verranno eliminate):

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

Ecco una funzione che, per ogni argomento, elimina l'argomento se si tratta di un file non di directory o di un albero di directory che non contiene altro che directory. Nota che questa funzione non è atomica: se uno degli argomenti cambia mentre è in esecuzione, potresti finire con un messaggio di errore, ma è sicuro che non cancellerà nessuna non directory all'interno di una directory passata come argomento.

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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.