cat / dev / null> file.log tidak memotong file besar di Darwin

15

Di masa lalu, pada sistem linux, saya bisa memotong file log yang besar dan terbuka (yaitu, file yang sedang aktif ditulis oleh suatu proses) menggunakan cat /dev/null > file.log.

Namun, pada 10.9 (Mavericks), sepertinya tidak demikian. Saya punya file 11GB yang sedang didata oleh aplikasi, tetapi ketika saya melakukan perintah yang sama dengan file tersebut, sepertinya tidak ada yang terjadi.

Ketika saya mencoba ini pada file ukuran sepele, itu berhasil.

Ini adalah ls -l /dev/null:

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

Saya juga sudah mencoba cp /dev/null file.logtidak berhasil.

Berpikir bahwa saya dapat mengambil keuntungan dari fungsi truncate ( man 2 truncatedi Darwin) saya mengkompilasi ini dan menjalankannya terhadap dua file, satu ukuran sepele dan yang lainnya file log yang sebenarnya. Sekali lagi, ini bekerja melawan file sepele dan tidak bekerja pada log yang jauh lebih besar.

/*
 * Copyright (c) 2013 Thomas de Grivel <[email protected]>
 *
 * 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;
}

Proses kembali 0terlepas dari file mana yang saya gunakan.

chb
sumber
Bagaimana Anda tahu itu tidak berhasil? Apa yang dikatakan duatau du -hdikatakan? Apakah mungkin file tersebut adalah file yang jarang?
Mikel
2
Juga, apa tujuan memasukkan lisensi dalam posting ini? Tampaknya hanya menambah kebisingan.
Mikel
du -h /tmp/file.loghasil dalam11G /tmp/file.log
chb
@Mikel Saya memasukkan lisensi sebagai rasa hormat ... Anda akan perhatikan bahwa saya mengurangi sebagian besar dari itu.
chb
1
lisensi adalah gangguan, permata sejati di sini adalah jawabannya
iruvar

Jawaban:

12

cat /dev/nullagak rumit cara untuk menulis perintah yang tidak menghasilkan output. :atau trueyang lebih jelas.

Dalam semua cat /dev/null > file, : > filedan bahkan > filedi sebagian besar kerang, shell membuka file dengan O_TRUNC pada stdout, kemudian menjalankan aplikasi yang tidak apa-apa output, maka file ditutup dan dibiarkan terpotong.

Namun, dalam kasus itu atau ketika menggunakan truncatesystem call, jika proses yang mengisi file itu tidak membukanya dengan flag O_APPEND, kali berikutnya ia menulis ke deskriptor file yang telah dibuka pada file, itu akan menulis data di offset itu ada di dalam file.

Karena HFS + tidak mendukung file jarang, itu berarti bahwa ruang sebelum offset itu harus dialokasikan kembali dan diisi dengan nol oleh sistem.

Jadi, Anda harus mematikan aplikasi yang sedang menulis ke file itu sebelum memotongnya. Atau Anda perlu memastikan aplikasi membuka file dengan O_APPEND(seperti dengan >>jika menggunakan redirection shell).

Jika Anda ingin bereksperimen dengannya:

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

Sekarang fd 3 dari shell saya adalah 100000 byte di dalam file

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

Sekarang file terpotong (ukuran 0, tidak ada ruang yang digunakan pada disk).

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

Menulis 1 byte ke file pada offset 100000, file tersebut sekarang berukuran 100001 bytes, yang pertama semuanya nol, akan menggunakan lebih dari 100k pada HFS +, tetapi sekitar hanya satu blok disk di sebagian besar sistem file Unix lainnya

Di sisi lain, dengan:

$ 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

Menulis 1 byte ke file tidak diimbangi 100000, tetapi pada akhir file karena O_APPEND. File berukuran 1 byte, dan membutuhkan ruang yang dibutuhkan untuk menampung satu byte itu.

Stéphane Chazelas
sumber
1
Saya belajar banyak dari jawaban ini. Terima kasih.
chb