Может ли rm рекурсивно удалить пустые каталоги?

9

В старой версии Unix rmкоманда удаляла каталоги, если они были пустыми. Из справочной страницы Research Unix восьмого издания для rm : «Если запись является каталогом, она удаляется, только если она пуста». Мне нравится это поведение, поэтому у меня есть этот псевдоним /etc/profile: alias rm='rm -d'я использую версию GNU coreutils rm, в которой -dговорится, что rmнужно идти дальше и удалять каталоги, если они пусты.

Все идет нормально. Этот псевдоним позволяет мне использовать rmкак старые времена. Однако я бы хотел сделать еще один шаг вперед. я бы хотелrmудалить каталог, даже если каталог содержит другие каталоги, при условии, что каталоги - единственное, что там есть. Неважно, насколько глубока структура каталогов, пока там нет файлов, просто пустые (как только вы дойдете до дна) каталоги, я бы хотел rmудалить их все.

Может ли это быть записано как псевдоним, который по-прежнему функционирует как обычный rmи удаляет все переданные ему файлы?

WhiteHotLoveTiger
источник
Как насчет rmdir -p?
Кевин
Спасибо за предложение, Кевин, но это не совсем то поведение, которое я ищу. Если я бегу mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, у меня все еще остаются a, a / b2 и a / b2 / c2. То, что я хотел бы, чтобы передать только верхний уровень (в данном случае) rmи удалить все, что ниже его.
WhiteHotLoveTiger

Ответы:

8

Вы хотите пройти по дереву каталогов и посмотреть, содержит ли оно что-либо, кроме каталога. Это за пределами rmвозможностей. Вам нужны другие инструменты, такие как find. Вы можете удалить пустые каталоги в данном каталоге следующим образом ( -depthв результате также будут удалены родительские каталоги, которые становятся пустыми):

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

Вот функция, которая для каждого аргумента удаляет аргумент, если это не файл каталога или дерево каталогов, не содержащее ничего, кроме каталогов. Обратите внимание, что эта функция не является атомарной: если один из аргументов изменяется во время ее работы, вы можете получить сообщение об ошибке, но это безопасно, так как она не удаляет все не-каталоги внутри каталога, переданного в качестве аргумента.

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
}
Жиль "ТАК - перестань быть злым"
источник