Là `rm -rf` không phải là nguyên tử?


11

Tôi vừa gặp một lỗi khó hiểu:

rm: cannot remove `xxx/app/cache/prod': Directory not empty

Điều này được gây ra bởi lệnh sau:

rm -rf $cache_dir/*

nơi $cache_dirđược định nghĩa làxxx/app/cache

Vì vậy, tôi thấy nó giống như: rmxóa tất cả mọi thứ trong cache/prodthư mục, sau đó ngay trước khi nó cố xóa cache/prodthư mục - một chương trình khác đã tạo một tệp / một thư mục bên trong nó do đó nó gây ra rmlỗi.

Là giả định của tôi đúng?


7
Giả định của bạn là chính xác - rm -rkhông phải là nguyên tử. Nếu bạn muốn chắc chắn rằng không có thêm tệp nào được tạo trong thư mục trong khi rm -rfđang chạy, bạn có thể đổi tên nó trước, sau đó xóa thư mục đã đổi tên.
Johnny

@ John: vâng, đó là những gì tôi thực sự đã thực hiện :-)
zerkms

Mặc dù điều đó không hoàn toàn an toàn. Nếu một ứng dụng hiện đang hoạt động ngoài thư mục đó, nó sẽ chỉ di chuyển và tiếp tục hoạt động bình thường.
Patrick

Điều này không liên quan gì đến việc rm -rfan toàn luồng: nếu bạn chạy đồng thời nhiều lần trên cùng một thư mục, thư mục sẽ bị xóa. Đây là về việc rm -rkhông phải là nguyên tử.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: nó phụ thuộc: "Một đoạn mã là an toàn luồng nếu nó chỉ thao tác các cấu trúc dữ liệu được chia sẻ theo cách đảm bảo thực thi an toàn bởi nhiều luồng cùng một lúc". Vì vậy, nếu chúng ta coi "luồng" là một rmlời gọi, chúng ta có thể nói về an toàn của luồng. Nhưng dù sao, nó cũng không thay đổi bất cứ điều gì
zerkms

Câu trả lời:


7

Thông báo lỗi được đưa ra là "Thư mục không trống" ( ENOTEMPTY), với giả định này của bạn nghe có vẻ đúng, đó là một điều kiện cuộc đua trong đó một chương trình đã tạo một tệp trong thư mục đó ngay trước khi rmcố gắng xóa thư mục, đưa ra ENOTEMPTYlỗi dự kiến từ bên dưới rmdir(2).

LƯU Ý: Để ở bên an toàn, bạn có thể di chuyển / đổi tên thư mục thành tên mới, sau đó thực hiện xóa thư mục này.


2
Câu trả lời này là sai, bạn có thể xóa các mục trong thư mục ngay cả khi một tệp đang được sử dụng, và sau đó xóa thư mục. Một thử nghiệm đơn giản mkdir x; cat > x/a &; tail -f x/a &; rm -r xcho thấy rằng một thư mục có thể bị xóa ngay cả khi các tệp đang được sử dụng, bất kể chúng được mở để đọc hay ghi.
wingbedubmariner

1
Có, các tệp vẫn tồn tại, nhưng điều này không liên quan gì đến việc tại sao xóa thư mục không thành công. Tuyên bố này trong câu trả lời của bạn cụ thể là sai: "Hệ thống sẽ không xóa một thư mục chứa các tệp nằm trong đó được mở ở chế độ đọc / ghi". Có một số nội dung hay trong câu trả lời của bạn, nó chỉ không liên quan đến câu hỏi :)
wingbedubmariner

1
Ngoài ra, hãy cẩn thận không nhầm lẫn giữa mô tả tập tin với các tập tin. Mô tả tập tin không bao giờ bị xóa, chỉ đóng.
wingbedubmariner

1
Đoạn đầu tiên của bạn có thể cần một số công việc quá. Bạn đã đúng về việc xóa tệp không xảy ra khi các tệp vẫn đang mở, chỉ là một khi tệp đã được hủy liên kết khỏi thư mục đó, chúng sẽ không ngăn thư mục bị xóa. Đúng, điều này có nghĩa là UNIX cho phép các tệp tồn tại không có trong bất kỳ thư mục nào, kỳ lạ như lúc đầu dường như.
wingbedubmariner

1
Tôi thực sự chỉ có thể nghĩ ra hai lý do tại sao việc xóa sẽ thất bại, hoặc trực giác của OP là chính xác và một tệp mới đã được tạo hoặc đó là lỗi cấp phép. rmphàn nàn về lỗi cấp phép, vì vậy tôi nghĩ chúng ta có thể loại bỏ điều đó. Tôi không đủ tự tin để gửi một câu trả lời mặc dù.
wingbedubmariner
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.