cat / dev / null> file.log ne tronque pas les gros fichiers dans Darwin


15

Dans le passé, sur les systèmes Linux, j'ai pu tronquer de gros fichiers journaux ouverts (c'est-à-dire un fichier qui est activement écrit par un processus) en utilisant cat /dev/null > file.log.

Cependant, sur 10.9 (Mavericks), cela ne semble pas être le cas. J'ai un fichier de 11 Go connecté à une application, mais lorsque j'exécute la même commande avec ledit fichier, rien ne semble se produire.

Quand j'essaye ceci sur un fichier de taille insignifiante, cela fonctionne.

Voici ls -l /dev/null:

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

J'ai également essayé cp /dev/null file.logen vain.

Pensant que je pourrais profiter de la fonction tronquer ( man 2 truncatedans Darwin), j'ai compilé cela et l'ai exécuté contre deux fichiers, l'un de taille triviale et l'autre le fichier journal réel. Encore une fois, cela a fonctionné contre le fichier trivial et n'a pas fonctionné sur le journal beaucoup plus volumineux.

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

Le processus retourne 0quel que soit le fichier que j'utilise.


Comment savez-vous que cela n'a pas fonctionné? Que signifie duou du -hdire? Est-il possible que le fichier soit un fichier clairsemé?
Mikel

2
Aussi, quel est le but d'inclure une licence dans ce post? Cela ne fait qu'ajouter du bruit.
Mikel

du -h /tmp/file.logrésultats dans11G /tmp/file.log
chb

@Mikel J'ai inclus la licence par courtoisie ... vous remarquerez que j'en ai expurgé la majeure partie.
chb

1
la licence est une distraction, le vrai joyau est la réponse
iruvar

Réponses:


12

cat /dev/nullest un peu compliqué pour écrire une commande qui ne produit aucune sortie. :ou truesont plus évidents.

Dans tous cat /dev/null > file, : > fileet même > filedans la plupart des coquilles, la coquille ouvre le fichier avec O_TRUNC sur la sortie standard, puis exécute l'application qui ne émet, le fichier est fermé et gauche tronquée.

Cependant, dans ce cas ou lors de l'utilisation de l' truncateappel système, si le processus qui remplit ce fichier ne l'a pas ouvert avec l'indicateur O_APPEND, la prochaine fois qu'il écrit dans le descripteur de fichier qu'il a ouvert sur le fichier, il écrira les données à l'offset qu'elles étaient dans le fichier.

Parce que HFS + ne prend pas en charge les fichiers épars, cela signifie que l'espace avant ce décalage devra être réalloué et rempli de zéros par le système.

Vous devez donc supprimer l'application qui écrit dans ce fichier avant de le tronquer. Ou vous devez vous assurer que l'application ouvre le fichier avec O_APPEND(comme avec >>si vous utilisez la redirection shell).

Si vous voulez l'expérimenter:

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

Maintenant, le fd 3 de mon shell est de 100 000 octets dans le fichier

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

Maintenant, le fichier est tronqué (taille 0, aucun espace utilisé sur le disque).

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

En écrivant 1 octet dans le fichier à l'offset 100000, le fichier fait maintenant 100001 octets, les premiers étant tous des zéros, utiliseraient plus de 100k sur HFS +, mais environ un seul bloc de disque dans la plupart des autres systèmes de fichiers Unix

D'autre part, avec:

$ 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

Écriture de 1 octet dans le fichier non pas à l'offset 100000, mais à la fin du fichier à cause de O_APPEND. Le fichier fait 1 octet et prend l'espace nécessaire pour contenir cet octet.


1
J'ai tellement appris de cette réponse. Merci.
chb
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.