Script shell Unix pour tronquer un gros fichier

87

J'essaye d'écrire un script Unix qui tronquera / videra un fichier qui est continuellement écrit / ouvert par une application quand il atteint, disons 3 Go d'espace. Je sais que la commande ci-dessous le ferait:

cp /dev/null [filename]

Mais je vais l'exécuter automatiquement dans un environnement de production en tant que travail cron - il suffit de poster ici pour voir si vous avez rencontré des problèmes en faisant quelque chose de similaire.

pipi
la source
Ce sont des prod. les journaux n'ont pas de valeur? J'ai eu la chance de conserver mes journaux de production pendant un an et plus (dans bzip2 -9 fmt) et disposais de quelques petits utilitaires qui facilitaient l'extraction des temps d'exécution des travaux, des enregistrements traités et une fois chargés dans une feuille de calcul, il était facile de calculer et de représenter graphiquement les taux de chargement. et un tas de trucs. Nous avons découvert un problème hdwr en raison de la baisse des rapports de charge. Oui, il existe de jolis outils de surveillance, donc tout dépend de votre situation. COMME OPTION SÉPARÉE, avez-vous regardé logrotate, cela pourrait vous fournir une certaine valeur (mais être ennuyeux avec sa configuration (juste deviner)!).
shellter
5
Notez que si le fichier journal est ouvert avec l'indicateur O_APPEND, la troncature est effective. S'il n'est pas ouvert avec l'indicateur O_APPEND, alors le programme continuera d'écrire au décalage de 3 Gio (la première fois); le système traitera les 3 premiers Gio comme tous octets-zéro (ce qui se compresse bien), mais le fichier continuera de croître. Tout dépend du programme qui écrit le journal.
Jonathan Leffler

Réponses:

116

Juste pour ajouter une autre réponse,

: > filename

: est un no-op dans bash (compatible POSIX), donc cela ouvre essentiellement le fichier pour l'écriture (qui bien sûr tronque le fichier) puis le ferme immédiatement.

EDIT: comme l'a commenté le shellter, vous n'avez pas réellement besoin d'une commande pour accompagner la redirection:

$ echo foo > foo.txt
$ cat foo.txt
foo
$ > foo.txt
$ cat foo.txt
$

Une simple redirection à elle seule effacera le fichier.

chepner
la source
25
ou juste > filename(comme je suis sûr que vous le savez). Bonne chance à tous.
shellter
5
@shelter "$> file" non POSIX et non portable. Vous devez utiliser la commande ":" no-op avant la redirection, comme suggéré initialement.
Aaron Toponce
2
+ plus pour smiley
Chris Suszyński
2
Comme @AaronToponce l'a souligné, "$> file" n'est en effet pas portable; sur ma configuration Zsh, cela fait pendre le shell (en attente d'une entrée). "$:> file" fonctionne très bien dans Zsh.
Linus Arver
1
@TechEnthusiast Cela dépend de vos attentes. La troncature elle-même est atomique, mais vous ne savez pas vraiment quand elle se produira par rapport à une écriture particulière. Vous pourriez, par exemple, vous retrouver avec une ligne partielle au début du fichier.
chepner le
65

J'ai utilisé la commande suivante sur debian

truncate -s 0 filename
Ricardo Marimon
la source
@SteveClay: sudo sh -c ': > filename'tronquera égalementfilename
Perleone
2
@SteveClay La suggestion de OPs fonctionne aussi parfaitement avec sudo: sudo cp /dev/null filename. Est également cpportable tandis que truncateLinux moderne est uniquement.
Tino
11

Cela me semble raisonnable. Unix, bien sûr, vous permettrait de le faire de 50 façons différentes. Par exemple,

echo -n "" >filename
cat /dev/null >filename
Don Branson
la source
2

trunc filename

fonctionne sur la version AIX d'UNIX

San
la source