cat / dev / null> file.log không cắt bớt tệp lớn ở Darwin


15

Trước đây, trên các hệ thống linux, tôi đã có thể cắt bớt các tệp nhật ký lớn, mở (nghĩa là một tệp đang được một quá trình tích cực ghi vào một quy trình) bằng cách sử dụng cat /dev/null > file.log.

Tuy nhiên, vào ngày 10.9 (Mavericks), điều đó dường như không xảy ra. Tôi đã có một tệp 11GB đang được đăng nhập bởi một ứng dụng, nhưng khi tôi thực hiện cùng một lệnh với tệp đã nói, dường như không có gì xảy ra.

Khi tôi thử điều này trên một tập tin có kích thước tầm thường, nó hoạt động.

Đây là ls -l /dev/null:

crw-rw-rw- 1 root wheel 3, 2 Dec 16 12:49 /dev/null

Tôi cũng đã cố gắng cp /dev/null file.logvô ích.

Nghĩ rằng tôi có thể tận dụng chức năng cắt ngắn ( man 2 truncateở Darwin), tôi đã biên dịch nó và chạy nó với hai tệp, một kích cỡ tầm thường và tệp kia là tệp nhật ký thực tế. Một lần nữa, nó hoạt động chống lại tệp tầm thường và không hoạt động trên nhật ký lớn hơn nhiều.

/*
 * Copyright (c) 2013 Thomas de Grivel <thomas@lowh.net>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 ...
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <unistd.h>

int main (int argc, const char **argv)
{
        int e = 0;
        while (--argc) {
                argv++;
                if (truncate(*argv, 0)) {
                        e = 4;
                        warn("%s", *argv);
                }
        }
        return e;
}

Quá trình trả về 0bất kể tập tin nào tôi sử dụng.


Làm thế nào để bạn biết nó không hoạt động? Không duhay du -hnói gì? Có thể các tập tin là một tập tin thưa thớt?
Mikel

2
Ngoài ra, mục đích của việc bao gồm một giấy phép trong bài viết này là gì? Nó dường như chỉ thêm tiếng ồn.
Mikel

du -h /tmp/file.logkết quả trong11G /tmp/file.log
chb 16/12/13

@Mikel Tôi đã bao gồm giấy phép như một phép lịch sự ... bạn sẽ lưu ý rằng tôi đã xử lý lại hầu hết giấy phép.
chb

1
Giấy phép là một sự xao lãng, viên ngọc thực sự ở đây là câu trả lời
iruvar 17/12/13

Câu trả lời:


12

cat /dev/nulllà một chút phức tạp một cách để viết một lệnh không tạo ra đầu ra. :hoặc truelà những người rõ ràng hơn.

Trong tất cả cat /dev/null > file, : > filevà thậm chí > filetrong hầu hết vỏ, vỏ mở tập tin với O_TRUNC trên stdout, sau đó chạy các ứng dụng mà không làm bất cứ điều gì đầu ra, sau đó các tập tin được đóng lại và trái cắt ngắn.

Tuy nhiên, trong trường hợp đó hoặc khi sử dụng lệnh truncategọi hệ thống, nếu quá trình điền vào tệp đó không mở nó bằng cờ O_APPEND, lần tiếp theo nó ghi vào bộ mô tả tệp mà nó đã mở trên tệp, nó sẽ ghi dữ liệu ở phần bù nó nằm trong tệp.

Vì HFS + không hỗ trợ các tệp thưa thớt, điều đó có nghĩa là không gian trước phần bù đó sẽ phải được phân bổ lại và chứa đầy các số không bởi hệ thống.

Vì vậy, bạn cần phải giết ứng dụng đang ghi vào tệp đó trước khi cắt nó. Hoặc bạn cần đảm bảo ứng dụng mở tệp bằng O_APPEND(giống như >>nếu sử dụng chuyển hướng shell).

Nếu bạn muốn thử nghiệm với nó:

$ exec 3> x
$ yes | head -n 50000 >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100000 Dec 16 21:32 x

Bây giờ fd 3 của shell của tôi là 100000 byte trong tệp

$ : > x
$ ls -ls x
0 -rw-r--r--  1 me me  0 Dec 16 21:34 x

Bây giờ tệp bị cắt ngắn (kích thước 0, không có không gian sử dụng trên đĩa).

$ echo >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100001 Dec 16 21:34 x

Ghi 1 byte vào tệp ở độ lệch 100000, tệp hiện có dung lượng lớn 100001 byte, các số đầu tiên đều là số không, sẽ sử dụng hơn 100k trên HFS +, nhưng chỉ khoảng một khối đĩa trong hầu hết các hệ thống tệp Unix khác

Mặt khác, với:

$ exec 3>> x
$ yes | head -n 50000 >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100000 Dec 16 21:35 x
$ : > x
$ echo >&3
$ ls -ls x
8 -rw-r--r--  1 me me  1 Dec 16 21:36 x

Viết 1 byte vào tệp không phải ở offset 100000, nhưng ở cuối tệp vì O_APPEND. Tệp có dung lượng lớn 1 byte và chiếm không gian cần thiết để giữ một byte đó.


1
Tôi đã học được rất nhiều từ câu trả lời này. Cảm ơn.
chb
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.