Làm thế nào một chương trình đăng nhập có thể tiếp tục đăng nhập vào một tập tin bị xóa?


12

Từ Unix Power Tools, Phiên bản thứ 3 : Thay vì xóa một tệp, hãy làm trống phần:

Nếu một quy trình hoạt động có tệp mở (không phổ biến đối với tệp nhật ký), việc xóa tệp và tạo tệp mới sẽ không ảnh hưởng đến chương trình ghi nhật ký; những tin nhắn đó sẽ tiếp tục đi đến tập tin không còn được liên kết . Làm trống tệp không phá vỡ liên kết và vì vậy nó xóa tệp mà không ảnh hưởng đến chương trình ghi nhật ký.

( nhấn mạnh của tôi )

Tôi không hiểu tại sao một chương trình sẽ tiếp tục đăng nhập vào một tập tin bị xóa. Có phải vì mục mô tả tập tin không bị xóa khỏi bảng quy trình?

Câu trả lời:


11

Khi bạn xóa một tập tin, bạn thực sự xóa một liên kết đến tập tin (đến nút). Nếu ai đó đã mở tệp đó, họ có thể giữ mô tả tệp họ có. Các tập tin vẫn còn trên đĩa, chiếm không gian, và có thể được ghi và đọc từ nếu bạn có quyền truy cập vào nó.

Các unlinkchức năng được xác định với hành vi này bằng POSIX:

Khi số liên kết của tệp trở thành 0 và không có quá trình nào mở tệp, không gian bị chiếm bởi tệp sẽ được giải phóng và tệp sẽ không thể truy cập được nữa. Nếu một hoặc nhiều quá trình mở tệp khi liên kết cuối cùng bị xóa, liên kết sẽ bị xóa trước khi hủy liên kết (), nhưng việc xóa nội dung tệp sẽ bị hoãn cho đến khi tất cả các tham chiếu đến tệp được đóng lại .

Lời khuyên này vì hành vi đó. Trình nền sẽ mở tệp và sẽ không nhận thấy rằng nó đã bị xóa (trừ khi nó đang theo dõi cụ thể, điều này không phổ biến). Nó sẽ tiếp tục ghi hoàn toàn vào bộ mô tả tệp hiện có: bạn sẽ tiếp tục chiếm (thêm) dung lượng trên đĩa, nhưng bạn sẽ không thể thấy bất kỳ thư nào mà nó viết, vì vậy bạn thực sự đang ở tình trạng tồi tệ nhất của cả hai thế giới. Thay vào đó, nếu bạn cắt tệp thành độ dài bằng 0 thì không gian sẽ được giải phóng ngay lập tức và mọi thông báo mới sẽ được thêm vào ở phần cuối mới của tệp nơi bạn có thể nhìn thấy chúng.

Cuối cùng, khi trình nền kết thúc hoặc closes tệp , không gian sẽ được giải phóng. Không ai mới có thể mở tệp trong thời gian trung bình (ngoài giao diện phản chiếu dành riêng cho hệ thống như của Linux/proc/x/fd/... ). Nó cũng đảm bảo rằng:

Nếu số lượng liên kết của tệp là 0, khi tất cả các mô tả tệp được liên kết với tệp bị đóng, không gian bị chiếm bởi tệp sẽ được giải phóng và tệp sẽ không thể truy cập được nữa.

Vì vậy, bạn không mất dung lượng đĩa vĩnh viễn, nhưng bạn không thu được gì bằng cách xóa tệp và bạn mất quyền truy cập vào thư mới.


1
Điều gì sẽ xảy ra nếu người dùng (giả sử root ở đây) cố gắng hủy liên kết /proc/x/fd/y? Điều đó sẽ khiến quá trình không thể ghi vào bộ mô tả tập tin, hay đó là một hoạt động bất hợp pháp?
nanofarad

@hexafraction /proc/*/fd/*là các liên kết tượng trưng đến các tệp thực, vì vậy xóa chúng sẽ không xóa tệp. Tôi khuyên bạn nên thử nghiệm :) (dĩ nhiên không phải trên hệ thống sản xuất!)
Ruslan

1
@MichaelHomer Có lẽ bạn có thể làm rõ trong câu trả lời của mình rằng một khi tệp không được liên kết, quá trình có một bộ mô tả tệp trỏ đến nó có thể liên kết lại, cùng một đường dẫn hay không. Điều này đôi khi có thể hữu ích.
lgeorget

@hexafraction Vâng, đây chỉ là các biểu diễn (trong không gian hệ thống tập tin) của trạng thái quá trình và các đối tượng. Nếu bạn loại bỏ các biểu diễn đó trong không gian hệ thống tệp, sẽ không có gì xảy ra với quy trình thực tế - trừ khi nó (hoặc một số quy trình khác) phụ thuộc vào biểu diễn đó ở đó. Không chắc chắn bạn có thể sử dụng rmkhông liên tục bên trong /prochoặc /syskhông bị hệ thống thông báo.
David Tonhofer

@lgeorget Làm thế nào là hoàn thành?
Michael

8

Chính xác.

Các tập tin là ba bên.

  • Nội dung, nghĩa là một mảng byte phẳng, được ghi ở đâu đó trên đĩa hoặc được tạo khi đang di chuyển.
  • Nút chỉ mục hay viết tắt là inode , là cấu trúc dữ liệu được nhân và sử dụng bởi kernel. Nó chứa tất cả các siêu dữ liệu (kích thước, quyền, v.v.) về tệp và cũng trỏ đến vị trí của nội dung của tệp.
  • Một hoặc nhiều mục thư mục , đó là địa điểm, thao tác như những con đường như /home/user/personal_file, mà hành động như xử lý thông qua đó bạn có thể sử dụng các tập tin, sửa đổi nội dung của nó, thay đổi metadata của nó, vv

Khi bạn mở một tệp, bạn đưa đường dẫn đến hệ điều hành và nó sẽ trả về cho bạn một tay cầm trực tiếp đến nút. Với tay cầm này, được gọi là bộ mô tả tệp, bạn có thể thao tác tệp theo ý muốn (hoặc ít nhất, theo sự cho phép của HĐH).

Bạn không bao giờ có thể xóa trực tiếp một nút, bạn phải đưa ra một đường dẫn đến HĐH để yêu cầu xóa. Vì vậy, khi bạn muốn xóa một tập tin, bạn chỉ xóa mục nhập thư mục. Nếu tệp có các mục nhập thư mục khác, nó sẽ tiếp tục có thể truy cập được và ngay cả khi không có, inode của nó sẽ không bị xóa trong khi vẫn còn các mô tả tệp trỏ đến nó. Câu trả lời của @ MichaelHomer là kỹ thuật hơn và chi tiết hơn về chủ đề cụ thể này.


4

Hai câu trả lời khác giải thích rõ về vấn đề này - một tệp không bị "xóa" cho đến khi tất cả các thư mục liên kết đến nó tất cả các mô tả tệp đang mở cho nó đều biến mất.

Để tránh điều này, đó là một thói quen tốt để sử dụng

> /var/log/bigfile

thay vì

rm -f /var/log/bigfile

vì điều đó chỉ đặt lại nội dung về 0 byte thay vì xóa nó và bạn vẫn có thể thấy những gì được ghi vào nó.

Nếu bạn đã xóa tệp và trên linux nơi bạn có hệ thống tệp / Proc / fd, bạn vẫn có thể sử dụng

> /proc/12345/fd/3

bằng không nội dung của tệp (giả sử 12345 là id tiến trình của bạn và 3 là số fd của tệp lớn). Đây có thể là một trình bảo vệ cuộc sống nếu đĩa của bạn đang chạy đầy và bạn không thể giết quá trình ghi tệp nhật ký của mình vì một số lý do.


> /var/log/bigfilexóa dữ liệu hiện có trong tệp nhưng không ngăn các chương trình ghi vào đó. Có rất ít trường hợp đó là điều đúng đắn. Tôi muốn nói rằng đó là một thói quen xấu để có được vào. Nếu bạn muốn xóa một tập tin, sử dụng rm. Nếu bạn muốn dừng các chương trình đang viết ở đó, hãy giết chúng hoặc làm cho chúng dừng viết, trước hoặc sau khi xóa.
Gilles 'SO- ngừng trở nên xấu xa'

1
@Giles, chủ đề này là về việc xóa sẽ không giúp ích nếu chương trình vẫn mở tệp. Và nếu đĩa của bạn đầy vì một số chương trình hoạt động sai và syslogdlấp đầy /var/log/messages, > /var/log/messageslà một lựa chọn tốt hơn nhiều so với việc giết syslogd. Tất nhiên, điều đó không thể ngăn bạn phân tích vấn đề là gì ngay từ đầu.
Guntram Blohm hỗ trợ Monica
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.