Rm có thể loại bỏ đệ quy các thư mục trống?


9

Trong phiên bản cũ của Unix, rmlệnh sẽ xóa các thư mục nếu chúng trống. Từ trang man Research Research Eighth Edition cho rm : "Nếu một mục nhập là một thư mục thì nó chỉ bị xóa nếu trống." Tôi thích hành vi này, vì vậy tôi đã có bí danh này /etc/profile: alias rm='rm -d'Tôi đang sử dụng phiên bản GNU coreutils rm, trong đó sẽ -dnói rmtrước và xóa các thư mục nếu chúng trống.

Càng xa càng tốt. Bí danh này cho phép tôi sử dụng rmnhư ngày xưa. Tuy nhiên, tôi muốn tiến thêm một bước nữa. tôi muốnrmđể xóa một thư mục ngay cả khi thư mục chứa các thư mục khác, miễn là thư mục là thứ duy nhất ở đó. Không quan trọng cấu trúc thư mục đi sâu đến đâu, miễn là không có bất kỳ tệp nào trong đó, chỉ là các thư mục trống (một khi bạn xuống đến cuối), tôi muốn rmxóa tất cả chúng.

Điều này có thể được viết dưới dạng bí danh vẫn hoạt động như thường lệ rmvà xóa bất kỳ tệp nào được truyền cho nó không?


Thế còn rmdir -p?
Kevin

Cảm ơn vì lời đề nghị Kevin, nhưng đây không hoàn toàn là hành vi tôi đang tìm kiếm. Nếu tôi chạy mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, tôi vẫn còn lại với a, a / b2 và a / b2 / c2. Điều tôi muốn là chỉ vượt qua cấp cao nhất (trong trường hợp này) rmvà xóa mọi thứ bên dưới nó.
WhiteHotLoveTiger

Câu trả lời:


8

Bạn muốn duyệt qua một cây thư mục và xem nếu nó chứa bất cứ thứ gì ngoài một thư mục. Điều này là vượt quá rmkhả năng của. Bạn cần các công cụ khác như find. Bạn có thể xóa các thư mục trống trong một thư mục đã cho theo cách này ( -depthkhiến các thư mục mẹ cũng bị trống cũng bị xóa):

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

Đây là một hàm, đối với mỗi đối số, sẽ xóa đối số nếu đó là tệp không phải thư mục hoặc cây thư mục không chứa bất cứ thứ gì ngoài thư mục. Lưu ý rằng hàm này không phải là nguyên tử: nếu một trong các đối số thay đổi trong khi nó đang chạy, bạn có thể sẽ gặp một thông báo lỗi, nhưng nó an toàn ở chỗ nó sẽ không xóa bất kỳ thư mục nào trong thư mục được truyền dưới dạng đối số.

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.