Lors de la gestion des fichiers journaux, certains finissent sous forme de fichiers compressés grâce à logrotate
et d'autres non. Donc, quand vous essayez quelque chose comme ça:
$ zcat *
vous vous retrouvez avec une ligne de commande comme zcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gz
puis avec:
gzip: xyz.log: not in gzip format
Existe-t-il un outil qui prendra les octets magiques, semblable au fonctionnement de file
, et utilisera zcat
ou cat
selon le résultat pour que je puisse diriger la sortie vers grep
par exemple?
NB: Je sais que je peux l'écrire, mais je demande s'il existe déjà un outil.
zless
Il semble dommage de zcat
, car libz possède une API qui prend en charge la lecture de fichiers compressés et non compressés de manière transparente. Mais la page de manuel dit que zcat
est équivalent à gunzip -c
.
Essayez-le avec -f
ou --force
:
zcat -f -- *
Puisque zcat
n'est qu'un simple script qui s'exécute
exec gzip -cd "$@"
avec de longues options qui se traduiraient par
exec gzip --stdout --decompress "$@"
et, selon le man gzip
(souligner le mien):
-f --force Forcer la compression ou la décompression même si le fichier a plusieurs liens Ou le fichier correspondant existe déjà, ou si les données compressées sont Lues ou écrites sur un terminal. Si les données d'entrée ne sont pas dans un format Reconnu par gzip, et si l'option --stdout est également donnée, copiez les données d'entrée Sans les modifier dans la sortie standard: laissez zcat se comporter comme un chat.
Aussi:
afin que je puisse diriger la sortie vers
grep
par exemple
Vous pouvez utiliser zgrep
pour cela:
zgrep -- PATTERN *
voir cependant le commentaire de Stéphane ci-dessous.
J'utilise exactement dans le même but:
{ cat /var/log/messages ; zcat /var/log/messages*.gz ; }| grep something | grep "something else" ....
Il existe un remplacement direct pour ztools (zcat, zgrep, ..) appelé zutils qui unit tous les outils de décompression indépendamment du backend. Ainsi, avec la même commande, vous pouvez lire les fichiers plain, lzma, gzipped, xz de manière transparente.
Il est disponible dans debian wheezy ou plus récent, probablement aussi dans redhat/centos.
La page du projet est ici nongnu.org
Un article de blog expliquant l'utilisation de l'utilitaire ici ( noone.org )
Cela fonctionne très bien dans RHEL 5.x où zcat est un binaire. Il échoue dans RHEL 6.x (et Ubuntu 12.x) où zcat est un script. Ceci tilisé pour fonctionner correctement.
Je n'utiliserais pas du tout zcat mais zgrep ne traitera pas non plus correctement les fichiers non compressés.
Ouvre à la fois compressé et non compressé, dans l'ordre chronologique.
ls -v syslog* | tac | xargs zcat -f | less
Et l'emballage?
$ cat xcat.sh
#!/bin/bash
for i in $@;do
[ ! -z "$(file -i $i | grep "gzip")" ] && zcat $i || cat $i
done
$ bash xcat.sh plain.txt gzipped_text.gz
Copiez et collez (ou mettez-le à la fin de votre ~/.bashrc
fichier) cette fonction bash :
logs() { zcat -f $(ls -rv "$1"*) | less; }
Vous pouvez maintenant taper par exemple logs /var/log/syslog
ou logs /var/log/nginx/access.log
pour voir tous le syslog ou nginx consigner les messages du plus ancien au plus récent avec moins .
Vous pouvez ensuite rechercher quelque chose en tapant /something
et frapper n
pour suivant .
Il y a un beau script Perl qui fait exactement cela. C'est logresolvemerge.pl du projet awstats: http://www.awstats.org/docs/awstats_tools.html
Logresolvemerge vous permet d'obtenir un fichier journal de sortie unique, trié par date, construit à partir de sources particulières:
La sortie est sur STDOUT, de sorte que vous pouvez l'utiliser très bien dans des processus supplémentaires.
En s'appuyant sur la réponse de @ Ryan, les éléments suivants obtiendront tous les fichiers "laminés" triés alphabétiquement, puis récupèrent le fichier actuel, les décompressent si nécessaire et less
:
cat <(ls mylog.log-* | sort) <(ls mylog.log) | xargs zcat -f | less
ou si vous voulez les obtenir tous sous forme de flux continu, vous pouvez les tail
et éventuellement les rediriger vers un autre processus
cat <(ls mylog.log-* | sort | xargs zcat -f) <(tail -f -n +0 mylog.log)
Je dois noter que cela est conçu pour les journaux qui tournent quotidiennement avec la date ajoutée à la fin du fichier. Si votre journal nous enregistre dans un format différent, vous devrez modifier la première partie de l'instruction cat
pour l'adapter.