Cách dọn dẹp thư mục tmp an toàn trên Linux


14

Tôi sử dụng RAM cho tmpfs / tmp của tôi, chính xác là 2GB. Thông thường, điều này là đủ nhưng đôi khi, các quy trình tạo các tệp trong đó và không thể tự dọn dẹp. Điều này có thể xảy ra nếu họ gặp sự cố. Tôi cần xóa các tệp tmp mồ côi này nếu không quá trình trong tương lai sẽ hết dung lượng trên / tmp.

Làm thế nào tôi có thể thu gom rác / tmp một cách an toàn? Một số người làm điều đó bằng cách kiểm tra dấu thời gian sửa đổi lần cuối, nhưng cách tiếp cận này không an toàn vì có thể có các quy trình chạy dài mà vẫn cần các tệp đó. Một cách tiếp cận an toàn hơn là kết hợp điều kiện dấu thời gian sửa đổi cuối cùng với điều kiện không có quá trình nào có tệp xử lý tệp cho tệp. Có một chương trình / kịch bản / vv thể hiện phương pháp này hoặc một số phương pháp khác cũng an toàn không?

Ngẫu nhiên, Linux / Unix có cho phép chế độ mở tệp khi tạo trong đó tệp đã tạo bị xóa khi quá trình tạo kết thúc, ngay cả khi nó bị sập không?


Kiểm tra xem bạn có thể sử dụng tmpfs thay vì / tmp: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--

Câu trả lời:


15

Bạn có thể muốn thử một cái gì đó như thế:

find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'

find được sử dụng để tìm các tập tin phù hợp với tiêu chí nhất định.

  • -mtime +7 chỉ chọn các tệp cũ hơn 7 ngày (bạn có thể sử dụng bất kỳ giá trị nào khác)
  • -exec fuser -s {} ';'gọi fuser ở chế độ im lặng cho mọi tệp phù hợp với tiêu chí cũ. fuser trả về 0 (= true) cho mọi tệp được truy cập ngay bây giờ và 1 (= false) cho những tệp chưa được xử lý. Vì chúng tôi chỉ quan tâm đến những người chưa được xử lý, chúng tôi đã đặt -nottrước-exec
  • -exec echo {} ';'chỉ in tất cả các tên tập tin phù hợp với tiêu chí. bạn có thể muốn sử dụng -exec rm {} ';'thay vì ở đây, nhưng vì điều này có thể xóa một số tệp vẫn đang sử dụng, tôi nghĩ rằng an toàn hơn khi thực hiện một tiếng vang đơn giản trước tiên.
  • chỉnh sửa: Bạn có thể muốn thêm một cái gì đó như -name 'foo*.bar'hoặc -uid 123để hạn chế ảnh hưởng của việc dọn dẹp vào các mẫu tệp hoặc ID người dùng cụ thể để tránh các hiệu ứng ngẫu nhiên.

Đến điểm cuối cùng: Hãy xem xét rằng có thể có các tệp chỉ được ghi một lần (ví dụ: khi khởi động hệ thống) nhưng đọc thường xuyên (ví dụ: bất kỳ X-session-cookie nào). Do đó, tôi khuyên bạn nên thêm một số kiểm tra tên để chỉ ảnh hưởng đến các tệp được tạo bởi các chương trình bị lỗi của bạn.

chỉnh sửa2: Cho câu hỏi cuối cùng của bạn: Một tệp sẽ không bị xóa khỏi đĩa cho đến khi không có quá trình nào xử lý mở đối với nó (ít nhất là đối với các hệ thống tệp linux gốc). Vấn đề là mục nhập thư mục bị xóa ngay lập tức, điều đó có nghĩa là từ khi bạn xóa tệp, không có quy trình mới nào có thể mở tệp được nữa (vì không có tên tệp nào được đính kèm).

Để biết chi tiết, hãy xem: /programming/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: Nhưng nếu tôi muốn tự động hóa toàn bộ quá trình thì sao?

Như tôi đã nói, có thể có các tệp được viết một lần và sau đó đọc từng lần một (ví dụ: cookie phiên X, tệp PID, v.v.). Những người sẽ không bị loại trừ bởi tập lệnh xóa nhỏ này (đó là lý do tại sao bạn có thể muốn chạy thử echotrước tiên trước khi thực sự xóa các tệp).

Một cách để thực hiện một giải pháp an toàn là sử dụng atime.
atimelưu trữ thời gian mỗi tệp được truy cập lần cuối. Nhưng tùy chọn hệ thống tệp đó thường bị vô hiệu hóa vì nó có tác động khá lớn đến hiệu suất (theo blog này ở đâu đó trong khu vực 20-30%). Có relatime, nhưng người ta chỉ ghi thời gian truy cập nếu mtimeđã thay đổi, vì vậy điều này sẽ không giúp chúng ta.

Nếu bạn muốn sử dụng atime, tôi khuyên bạn nên có /tmpmột phân vùng riêng (lý tưởng nhất là ramdisk) để tác động hiệu suất trên toàn hệ thống không quá lớn.

Khi atimeđược bật, tất cả những gì bạn phải làm là thay thế -mtimetham số trong dòng lệnh trên bằng -atime.
Bạn có thể loại bỏ -not -exec fuser -s {} ';', nhưng tôi sẽ giữ nó ở đó chỉ để đảm bảo (trong trường hợp các ứng dụng giữ các tệp mở trong một thời gian dài).

Nhưng hãy nhớ kiểm tra lệnh bằng cách sử dụng echotrước khi bạn kết thúc việc xóa những thứ mà hệ thống của bạn vẫn cần!


đẹp. Điều gì về các tệp được đóng bởi một quá trình chạy dài trong khi nó không cập nhật chúng? Nếu chúng là các tệp ngữ cảnh, bạn có thể mất quy trình xử lý (phải thừa nhận, đây không phải là một quy trình rất thông minh; nhưng người ta cần biết tác dụng phụ dự kiến ​​của việc /tmp/dọn dẹp 'bên' ).
nik

Đó là vấn đề của phương pháp này (như tôi đã chỉ ra trong đoạn cuối). Cách tiếp cận tốt nhất ở đây sẽ là thêm các kiểm tra mẫu uid / gid hoặc tệp (chỉnh sửa câu trả lời cho phù hợp)
mreithub

Điều này có nên được đặt vào một kịch bản cron ...?
CMCDragonkai

@CMCDragonkai Tất nhiên bạn có thể đặt cái này vào crontab. Nhưng như tôi đã đề cập, có thể có các tệp được truy cập nhưng không được ghi và do đó có thể không được lọc bởi tập lệnh nhỏ này. Đó là lý do tại sao an toàn hơn để in danh sách các tệp bị ảnh hưởng trước và sau đó tự quyết định có nên xóa chúng hay không. Nếu bạn /tmpđang ở trên một phân vùng riêng (ví dụ: ramdisk), bạn có thể kích hoạt atimenó và sử dụng -atimetham số của find.
mreithub

Tôi đang lên kế hoạch để làm điều này trên một máy chủ. Vì vậy, tôi không thể ở đó để đếm tất cả các tệp trong tmp mọi lúc. Sẽ có bất kỳ vấn đề? Ngoài ra tôi nghĩ rằng chúng tôi có nghĩa là sử dụng tương đối không atime?
CMCDragonkai

3

Đừng cuộn của riêng bạn.

Debian / Ubuntu có tmpreaper, có lẽ nó cũng có sẵn ở các dist khác.

# tmpreaper - cleans up files in directories based on their age

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 

Trong /etc/tmpreaper.conftệp, nếu tôi đặt cả hai /tmp/var/tmplàm thư mục dọn dẹp, bạn có thể đề xuất bao lâu cho TMPREAPER_TIMEtham số hoặc tối đa trước đó của các tệp tmp sẽ bị xóa không? Tôi đã nghe nói tốt hơn là giữ một tuổi dài hơn cho /var/tmpcác tệp hơn /tmpcác tệp. Nhưng nếu chúng chỉ có thể được thiết lập với cùng độ tuổi tối đa, tôi không có manh mối.
Xiaodong Qi

2

Về phần cuối cùng của câu hỏi của bạn:

Mặc dù tôi không nghĩ rằng tồn tại chế độ mở / tạo 'xóa-này-nếu-tôi-chết', một quá trình có thể xóa tệp một cách an toàn sau khi tạo, miễn là nó xử lý để mở tệp. Sau đó, hạt nhân sẽ giữ tệp trên đĩa và ngay khi quá trình cuối cùng đã mở tệp thoát ra (có thể là do sự cố hoặc thông thường), không gian bị chiếm giữ bởi tệp sẽ được giải phóng.

Đối với một cách chung chung về vấn đề mà một số quy trình đôi khi không dọn sạch / tmp, tôi khuyên bạn nên xem xét các không gian tên mount, được mô tả, ví dụ ở đây hoặc ở đây . Nếu quy trình trong câu hỏi là một daemon hệ thống, systemd và tính năng gốc của nó để cho phép các hệ thống tập tin private / tmp có thể được quan tâm.



0

Có được danh sách các tệp cũ hơn, vì vậy, loại trừ các tệp được mở bởi bất kỳ thứ gì trong danh sách đó:

find /tmp -mtime +7 |\
    egrep -v "`lsof -n +D /tmp | awk 'NR>1 {print $9}'| tr \\n \|`" 

lsof -n +D /tmp: tìm tệp đang mở trong / tmp
awk 'NR>1 {print $9}': chỉ in cột thứ chín của đầu ra lsof, ngoại trừ các tiêu đề
tr \\n \|: thay thế dòng mới bằng thanh (OR in egrep)
egrep -v "foo|moo|bar": dòng in KHÔNG chứa foo hoặc moo hoặc bar


0

Tôi đồng ý với điều trên, để thêm vào nó - Tôi luôn luôn chạy lsof +L1 | grep tmpvà giết hoặc khởi động lại các quá trình đang giữ các tệp tmp "đã xóa": VÍ DỤ-

# lsof +L1 | grep tmp
xfce4-ter  1699  user   32u   REG    8,6      192     0 818552 /tmp/vte966VLX (deleted)
chrome     3301  user  138u   REG    8,6    16400     0 818547 /tmp/etilqs_Z0guKD7p6ork9iG (deleted)

2
SU sắp xếp ngẫu nhiên các bài đăng - vì vậy không có bên trên hoặc bên dưới. Bài viết nào bạn đang đề cập đến?
Journeyman Geek

0

Bạn chỉ có thể làm rm -rf /tmp/*và hy vọng không có gì phá vỡ ...


Đề xuất làm điều gì đó "và hy vọng không có gì phá vỡ" không thực sự trả lời OP "có cách nào an toàn để làm việc này không. Có lẽ bạn có thể giải thích lý do tại sao đề xuất của bạn an toàn?
bertieb

@bertieb Điểm tốt. Tôi đoán có lẽ an toàn nếu nó không chạy bằng root, nhưng ...
Solomon Ucko
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.