cat / dev / null> file.log, Darwin'deki büyük dosyayı kısaltmaz


15

Geçmişte, linux sistemlerde, büyük, açık günlük dosyalarını (yani, bir işlem tarafından aktif olarak yazılan bir dosyayı) kullanarak kesebildim cat /dev/null > file.log.

Ancak, 10.9'da (Mavericks) durum böyle görünmüyor. Bir uygulama tarafından oturum açmış 11GB'lık bir dosyam var, ancak adı geçen dosyayla aynı komutu gerçekleştirdiğimde hiçbir şey olmuyor gibi görünüyor.

Bunu önemsiz boyuttaki bir dosyada denediğimde işe yarıyor.

İşte ls -l /dev/null:

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

Ben de cp /dev/null file.logboşuna çalıştım .

Kesik işlevden ( man 2 truncateDarwin'de) yararlanabileceğimi düşünerek bunu derledim ve biri önemsiz boyutta diğeri gerçek günlük dosyası olan iki dosyaya karşı çalıştırdım. Yine, önemsiz dosyaya karşı çalıştı ve çok daha büyük kütük üzerinde çalışmadı.

/*
 * 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;
}

0Hangi dosyayı kullandığımdan bağımsız olarak işlem geri döner .


İşe yaramadığını nereden biliyorsun? Ne diyor duya da du -hdiyor? Dosyanın seyrek bir dosya olması mümkün mü?
Mikel

2
Ayrıca, bu yayına lisans eklemenin amacı nedir? Sadece gürültü katıyor gibi görünüyor.
Mikel

du -h /tmp/file.logsonuçları11G /tmp/file.log
chb

@Mikel Lisansı nezaket olarak ekledim ... çoğunu redaksiyona aldığımı fark edeceksiniz.
chb

1
lisans bir oyalama, buradaki gerçek cevabı cevap
iruvar

Yanıtlar:


12

cat /dev/nullçıktı üretmeyen bir komut yazmanın bir yolu biraz kıvrıktır. :ya trueda daha açık olanlardır.

Tümünde cat /dev/null > file, : > fileve hatta > fileen kabuklarda, kabuk ardından çıkış şey yapmaz uygulamayı çalıştırır, stdout'ta O_TRUNC dosyayı açar, ardından dosya kapatılır ve kesilmiş bıraktı.

Ancak, bu durumda veya truncatesistem çağrısını kullanırken, bu dosyayı dolduran işlem dosyayı O_APPEND bayrağıyla açmadıysa, dosyada açtığı dosya tanımlayıcısına bir dahaki sefere yazarsa, dosyanın içindeki ofsetteki veriler.

HFS + seyrek dosyaları desteklemediğinden, bu ofsetten önceki boşluğun sistem tarafından yeniden tahsis edilmesi ve sıfırlarla doldurulması gerektiği anlamına gelir.

Bu nedenle, bu dosyaya yazılan uygulamayı kesmeden önce öldürmeniz gerekir. Veya uygulamanın dosyayı ile açtığından emin olmanız gerekir O_APPEND( >>kabuk yeniden yönlendirme kullanılıyorsa olduğu gibi ).

Denemek istiyorsanız:

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

Kabuğumun fd 3'ü dosya içinde 100000 bayt

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

Şimdi dosya kesilmiş (boyut 0, diskte alan yok).

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

Ofset 100000'de dosyaya 1 bayt yazıldığında, dosya şimdi 100001 bayt büyüktür, ilki sıfırlar, HFS + üzerinde 100 binden fazla kullanır, ancak diğer Unix dosya sistemlerinin çoğunda sadece bir disk bloğu

Öte yandan, ile:

$ 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

Ofset 100000'de değil, dosyanın sonunda dosyaya 1 bayt yazma O_APPEND. Dosya 1 bayt büyüklüğünde ve bu bayt için gereken alanı alır.


1
Bu cevaptan çok şey öğrendim. Teşekkürler.
chb
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.