Чи може rm рекурсивно видаляти порожні каталоги?


9

У старій версії Unix rmкоманда видалила б каталоги, якщо вони були порожніми. З основної сторінки Research Unix Eightth Edition для rm : "Якщо запис - це каталог, він видаляється, лише якщо порожній". Мені подобається така поведінка, тому я отримав цей псевдонім у своєму /etc/profile: alias rm='rm -d'я використовую версію coreutils GNU rm, в якій -dповідомляє rmйти вперед і видаляти каталоги, якщо вони порожні.

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

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


Як щодо 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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.