Lý do gì mà rm-rf -rf a / bv nói rằng, a / b không phải là trống rỗng?


7

Kịch bản sau đây đôi khi mang lại cho tôi những thứ nhưcan't remove a/b as it's not empty

ssh -T user@host <<EOF
  cd somewhere
  rm -rf a/b    
EOF

Nhưng tôi đăng nhập vào máy chủ và thực thi rm -rf a/bthì tôi không bao giờ gặp sự cố.

Có các quy trình khác đang tạo tập tin a/b, điều đó có liên quan không?

Dù sao, làm thế nào để tạo một tập lệnh đảm bảo "a / b" sẽ bị xóa?


1
Điều đó thật buồn cười, rm -rfnên luôn luôn thành công, thiếu các vấn đề cho phép. Yêu cầu kịch bản in đầu ra gỡ lỗi nếu loại bỏ thất bại. ls -laR a/bnên đủ.
Faheem Mitha

Câu trả lời:


7

rmdir(2)sẽ thất bại nếu thư mục không trống. Nếu một quá trình khác đang tạo các tệp trong khi rm(1)xóa chúng, nó sẽ không biết xóa chúng và do đó đến lúc rm(1)phải cố gắng xóa những gì nó tin là một thư mục trống, nó sẽ thất bại với lỗi bạn đã đăng.

Một cách để xóa thư mục khi đối mặt với việc tạo tệp đồng thời trong thư mục là đổi tên nó:

mv a a~
rm -rf a~

Có thể điều này có thể không hoạt động nếu các quy trình tạo tệp a/bkhông được thực hiện theo đường dẫn ( open(2)so với openat(2)).

Tôi giả sử rằng quá trình tạo tệp trong đó a/bsẽ tạo lại thư mục đó nếu nó không tồn tại hoặc sẽ xử lý thất bại một cách duyên dáng nếu nó không tồn tại. Vì bạn đã cố xóa thư mục trong các quy trình khác, nên đó có vẻ là một giả định an toàn.


cảm ơn, glusterfs là thư mục chữa bệnh và không thể chữa lành nó bình thường bởi một số lỗi trong glusterfs, vì vậy mv một thư mục cho tên khác và rm đang sửa nó.
waza123

15

Có các quá trình khác đang tạo tập tin đến a / b, điều đó có liên quan không?

Rất có thể. rm -rfĐầu tiên có thể xóa tất cả các tệp, sau đó xóa tất cả các thư mục. Trong mui xe, rmdirhệ thống gọi để xóa một thư mục sẽ thất bại nếu thư mục không trống. Bạn có thể có một điều kiện cuộc đua đang diễn ra, trong đó rm -rfkiểm tra xem thư mục trống không, và nó là; một quá trình khác sau đó tạo ra một tệp mới; cuối cùng rm -rfgọi rmdir, nhưng một quá trình khác tạo ra một tập tin trước.

Lời khuyên của Faheem là tốt: đưa lsvào tình trạng lỗi của bạn

ssh -T user@host <<EOF
  cd somewhere
  rm -rf a/b || ( ls -a a/b && exit 1 )
EOF

Rất thú vị.
boehj

Sự thất bại &&nên ;hoặc nếu lskhông sẽ ngăn tập lệnh thoát.
R .. GitHub DỪNG GIÚP ICE

Vâng. lscho thấy có những tập tin mới trong thư mục đó. Tôi sẽ mvthử giải pháp.
Cheng

@R, điều đó không đúng. Nếu lsthất bại, subshell sẽ trả về lsmã lỗi của. ' && exit 1' là cần thiết để đảm bảo rằng nếu ls thành công , lớp vỏ phụ vẫn trả về mã lỗi. Nếu bạn thay thế nó cho '||', bạn sẽ che dấu mã lỗi thực sự cho ls.
jmtd

0

Trong trường hợp điều kiện cuộc đua rất cao: lệnh tiếp theo sẽ xóa các tệp lỗi thời và sau đó xóa các thư mục trống:

find /somedir -type f -atime +3 -print0 | xargs -0 --no-run-if-empty rm -f; find /somedir -mindepth 1 -type d -empty -not -name "*.empty" -print0 | xargs -0 --no-run-if-empty -I{} mv {} {}.empty; sleep 30; find /somedir -type d -name '*.empty' -print0 | xargs -0 --no-run-if-empty rm -rf

Hoặc từng bước:

find /somedir -type f -atime +3 -print0 | xargs -0 --no-run-if-empty rm -f;
find /somedir -mindepth 1 -type d -empty -not -name "*.empty" -print0 | xargs -0 --no-run-if-empty -I{} mv {} {}.empty;
sleep 30;
find /somedir -type d -name '*.empty' -print0 | xargs -0 --no-run-if-empty rm -rf;

ngủ 30 là cần thiết cho tất cả các quá trình để hoàn thành việc viết vào direcory loại bỏ.

CẢNH BÁO: bạn có thể mất dữ liệu mới của mình (trong trường hợp của tôi là bộ đệm nên tôi không quan tâm).

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.