Bisakah rm menghapus direktori kosong secara rekursif?

9

Dalam versi Unix yang lama, rmperintah akan menghapus direktori jika kosong. Dari halaman manual Research Unix Eighth Edition untuk rm : "Jika sebuah entri adalah direktori, itu dihapus hanya jika kosong." Saya suka perilaku ini, jadi saya punya alias ini di /etc/profile: alias rm='rm -d'Saya menggunakan versi GNU coreutils rm, yang -dmemerintahkan rmuntuk melanjutkan dan menghapus direktori jika kosong.

Sejauh ini bagus. Alias ​​ini memungkinkan saya untuk menggunakan rmseperti dulu. Namun, saya ingin melangkah lebih jauh. saya inginrmuntuk menghapus direktori bahkan jika direktori tersebut berisi direktori lain, selama direktori adalah satu-satunya hal di sana. Tidak masalah seberapa dalam struktur direktori berjalan, selama tidak ada file di sana, cukup kosongkan (begitu Anda sampai ke bawah) direktori, saya ingin rmmenghapus semuanya.

Mungkinkah ini ditulis sebagai alias yang masih berfungsi seperti biasa rmdan menghapus semua file yang diteruskan ke sana?

WhiteHotLoveTiger
sumber
Bagaimana dengan rmdir -p?
Kevin
Terima kasih atas sarannya Kevin, tetapi ini bukan perilaku yang saya cari. Jika saya menjalankan mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, saya masih tersisa dengan a, a / b2, dan a / b2 / c2. Yang saya inginkan adalah lulus level atas saja (dalam hal ini) rm, dan menghapus semua yang ada di bawahnya.
WhiteHotLoveTiger

Jawaban:

8

Anda ingin melintasi pohon direktori dan melihat apakah itu berisi apa pun selain direktori. Ini di luar rmkemampuan. Anda memerlukan alat lain seperti find. Anda dapat menghapus direktori kosong di bawah direktori yang diberikan dengan cara ini ( -depthmenyebabkan direktori induk yang menjadi kosong juga dihapus):

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

Berikut adalah fungsi yang, untuk setiap argumen, menghapus argumen jika itu adalah file non-direktori atau pohon direktori yang tidak mengandung apa pun selain direktori. Perhatikan bahwa fungsi ini bukan atom: jika salah satu argumen berubah saat sedang berjalan, Anda mungkin berakhir dengan pesan kesalahan, tetapi aman karena tidak akan menghapus non-direktori di dalam direktori yang dilewati sebagai argumen.

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 'SANGAT berhenti menjadi jahat'
sumber