find -delete không xóa các thư mục không trống


32

Lệnh

$ find ~ -name .DS_Store -ls -delete

hoạt động trên Mac OS X, nhưng

$ find ~ -name __pycache__ -type d -ls -delete

không - các thư mục được tìm thấy nhưng không bị xóa.

Tại sao?

Tái bút Tôi biết tôi có thể làm

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +

câu hỏi là tại sao find -delete không không làm việc.

Câu trả lời:


36

find's -deletecờ làm việc tương tự nhưrmdir khi xóa thư mục. Nếu thư mục không trống khi đến, nó không thể bị xóa.

Bạn cần làm trống thư mục trước. Vì bạn đang chỉ định -type d,find sẽ không làm điều đó cho bạn.

Bạn có thể giải quyết điều này bằng cách thực hiện hai lần: đầu tiên xóa mọi thứ trong các thư mục có tên __pycache__, sau đó xóa tất cả các thư mục có tên __pycache__:

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete

Một số ít được kiểm soát chặt chẽ, nhưng trong một dòng duy nhất:

find ~ -path '*/__pycache__*' -delete

Điều này sẽ xóa bất cứ thứ gì trong nhà bạn __pycache__là một phần của đường dẫn của nó.


Trong tìm 4.4.2, lệnh cuối cùng cần phải find ~ -path '*/__pycache__*' -deletehoặc có thể find ~ -path '*/__pycache__/*' -o -name __pycache__ -deletelà an toàn.
ness101

3
@ naught101, mà nên find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deletenhư có ưu tiên hơn hoặc .
Stéphane Chazelas

6

Có một vài lý do tiềm năng cho việc này.

1) Bạn bảo nó chỉ xóa các thư mục ( -type d) và các thư mục đó vẫn có các tệp bên trong chúng.

2) Thư mục của bạn chỉ chứa các thư mục khác, vì vậy -type dsẽ giải quyết vấn đề nội dung. Tuy nhiên, bạn đang sử dụng OS-X, phần lớn dựa trên FreeBSD và FreeBSD findtheo mặc định sẽ xử lý thư mục trước nội dung của nó.
Tuy nhiên, -depthtùy chọn tồn tại để giải quyết vấn đề này bằng cách yêu findcầu xử lý thư mục sau nội dung của nó.

find ~ -name __pycache__ -type d -ls -delete -depth

Vấn đề này không tồn tại trên linux vì -deletetùy chọn này hoàn toàn cho phép -depth.

 

FreeBSD man 1 find:

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.

GNU man 1 find:

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.

2
Yeah, nhưng FreeBSD của find (1) nói cho -delete, “xử lý traversal ... Depth-đầu tiên được ngụ ý bởi tùy chọn này.”, Và GNU find (1) nói: “... -delete ngụ ý chiều sâu , ...”, vì vậy nó không nên cần thiết để thêm -depthvào lệnh.
G-Man nói 'Phục hồi Monica'

1
Từ trang quản lý GNU find: "Để tránh nhầm lẫn, các tùy chọn toàn cầu nên được chỉ định trên dòng lệnh sau danh sách các điểm bắt đầu, ngay trước thử nghiệm đầu tiên, tùy chọn vị trí hoặc hành động. Nếu bạn chỉ định tùy chọn chung ở một nơi khác, hãy tìm sẽ đưa ra một thông điệp cảnh báo giải thích rằng điều này có thể gây nhầm lẫn. " Bây giờ, -deletelà một "tùy chọn toàn cầu" sau ~lệnh được đưa ra. Tôi cũng đã nhận thấy rằng nó không có sự khác biệt cho dù bạn thêm -depthhay không. Các thư mục không trống vẫn không bị xóa (nhưng có lẽ vì tôi cũng sử dụng -maxdepth)
David Tonhofer
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.