cat / dev / null> file.log non tronca file di grandi dimensioni in Darwin


15

In passato, su sistemi Linux, sono stato in grado di troncare file di registro di grandi dimensioni e aperti (ovvero un file a cui viene attivamente scritto da un processo) utilizzando cat /dev/null > file.log.

Tuttavia, su 10.9 (Mavericks), questo non sembra essere il caso. Ho un file da 11 GB a cui è stata eseguita l'accesso da un'applicazione, ma quando eseguo lo stesso comando con detto file, sembra che non accada nulla.

Quando provo questo su un file di dimensioni insignificanti, funziona.

Ecco qui ls -l /dev/null:

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

Ho anche provato cp /dev/null file.loginutilmente.

Pensando che potrei sfruttare la funzione troncata ( man 2 truncatein Darwin), ho compilato questo ed eseguito su due file, uno di dimensioni insignificanti e l'altro il file di registro effettivo. Ancora una volta, ha funzionato contro il file banale e non ha funzionato sul registro molto più grande.

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

Il processo ritorna 0indipendentemente dal file che uso.


Come fai a sapere che non ha funzionato? Cosa dice duo du -hdice? È possibile che il file sia un file sparso?
Mikel,

2
Inoltre, qual è lo scopo di includere una licenza in questo post? Sembra solo aggiungere rumore.
Mikel,

du -h /tmp/file.logrisultati in11G /tmp/file.log
chb

@Mikel Ho incluso la licenza come cortesia ... noterai che l'ho redatta per la maggior parte.
chb

1
la licenza è una distrazione, la vera gemma qui è la risposta
iruvar il

Risposte:


12

cat /dev/nullè un po 'contorto un modo per scrivere un comando che non produce alcun output. :o truesono più ovvi.

In tutti cat /dev/null > file, : > filee anche > filenella maggior parte delle conchiglie, il guscio si apre file con O_TRUNC su stdout, poi esegue l'applicazione, che non emette nulla, allora il file viene chiuso e lasciato troncato.

Tuttavia, in quel caso o quando si utilizza la truncatechiamata di sistema, se il processo che sta riempiendo quel file non lo ha aperto con il flag O_APPEND, la prossima volta che scrive nel descrittore di file che ha aperto sul file, scriverà i dati all'offset erano all'interno del file.

Poiché HFS + non supporta file sparsi, ciò significa che lo spazio prima di tale offset dovrà essere riallocato e riempito di zeri dal sistema.

Quindi, è necessario uccidere l'applicazione che sta scrivendo su quel file prima di troncarlo. Oppure è necessario assicurarsi che l'applicazione apra il file con O_APPEND(come con >>se si utilizza il reindirizzamento della shell).

Se vuoi sperimentarlo:

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

Ora il fd 3 della mia shell è 100000 byte all'interno del file

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

Ora il file viene troncato (dimensione 0, nessuno spazio utilizzato sul disco).

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

Scrivendo 1 byte nel file con offset 100000, il file ora è grande 100001 byte, i primi tutti zeri, utilizzerebbero oltre 100k su HFS +, ma circa un solo blocco del disco nella maggior parte degli altri file system Unix

D'altra parte, con:

$ 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

Scrivere 1 byte nel file non a offset 100000, ma alla fine del file a causa di O_APPEND. Il file ha una dimensione di 1 byte e occupa lo spazio necessario per contenere quel byte.


1
Ho imparato così tanto da questa risposta. Grazie.
chb
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.