Pode rm recursivamente remover diretórios vazios?

9

Em uma versão antiga do Unix, o comando rm excluiria os diretórios se estivessem vazios. A partir de página man do Research Unix Oitava edição para rm : "Se uma entrada for um diretório, ela será removida apenas se vazio ". Eu gosto deste comportamento, então eu tenho esse alias no meu /etc/profile : alias rm='rm -d' Eu estou usando a versão GNU coreutils de rm , em que -d diz rm para ir em frente e remover diretórios se eles estão vazios.

Por enquanto, tudo bem. Esse alias me permite usar rm como nos velhos tempos. No entanto, gostaria de dar um passo adiante. Eu gostaria que rm apagasse um diretório mesmo que o diretório contenha outros diretórios, desde que os diretórios sejam a única coisa lá. Não importa quão profunda seja a estrutura de diretórios, desde que não haja arquivos lá, apenas diretórios vazios (assim que chegar ao fundo), eu gostaria que rm removesse todos eles.

Isso poderia ser escrito como um alias que ainda funcionaria como o rm normal e excluiria todos os arquivos passados para ele?

    
por WhiteHotLoveTiger 09.12.2013 / 00:06

1 resposta

7

Você deseja percorrer uma árvore de diretórios e ver se ela contém algo diferente de um diretório. Isso está além dos recursos do rm . Você precisa de outras ferramentas, como find . Você pode excluir os diretórios vazios sob um determinado diretório dessa maneira ( -depth faz com que os diretórios-pai que ficam vazios sejam excluídos também):

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

Aqui está uma função que, para cada argumento, apaga o argumento se for um arquivo não-diretório ou uma árvore de diretórios que não contenha nada além de diretórios. Note que esta função não é atômica: se um dos argumentos mudar enquanto está sendo executado, você pode acabar com uma mensagem de erro, mas é seguro que não irá excluir nenhum diretório dentro de um diretório passado como argumento. / p>

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
}
    
por 09.12.2013 / 00:18