¿Cómo truncar todos los archivos de registro?

18

¿Alguien puede darme una solución para truncar todos los archivos de registro en el /var/log/directorio?

y una pregunta solo por conocimiento, ¿es una buena idea o no?

#!/bin/bash
LOGDIR="/var/log"
for logfile in $(ls $LOGDIR/*log)
do
  truncate -s 0 $logfile
done
pylover
fuente
1
NO es una buena idea, /var/loges donde el sistema coloca los mensajes que pueda necesitar más adelante. Ubuntu ha encontrado el problema antes. Leer man 8 logrotate;man logrotate.conf.
Waltinator

Respuestas:

34

prueba esto:

truncate -s 0 /var/log/*log

EDITAR:

si desea hacer esto más de una vez, debe usarlo logrotatepara manejar sus registros. Por lo general, se instala en ubuntu. Echa un vistazo man logrotate(o si no lo tienes instalado, mira la página de manual en línea o instálalo con sudo apt-get install logrotate)

desde la página de manual:

logrotate está diseñado para facilitar la administración de sistemas que generan grandes cantidades de archivos de registro. Permite la rotación automática, la compresión, la eliminación y el envío por correo de archivos de registro. Cada archivo de registro puede manejarse diariamente, semanalmente, mensualmente o cuando crece demasiado.

GUARIDA
fuente
también puede vaciarlos usando echo ""> * log
Astm
10

Si desea borrar todos sus archivos de registro, no solo los de la carpeta de registro de primer nivel, puede usar:

shopt -s globstar                  # if needed
truncate -s 0 /var/log/*.log       # first-level logs
truncate -s 0 /var/log/**/*.log    # nested folders, like /var/log/nginx/access.log

Teniendo en cuenta que si ya ha logrotatecorrido, también deberá borrar los .gzregistros rotados :

find /var/log -type f -name '*.[0-99].gz' -exec rm {} +

Un uso válido para esto podría ser construir un contenedor de dispositivo VM para su distribución, por ejemplo.

Usted debe no necesita hacer esto como parte del mantenimiento rutinario: DEM como sugirió con razón, su uso logrotatepara eso.

msanford
fuente
1

Como seguimiento a @DEN respuesta

Esto encontrará todos los archivos de registro /var/logy los truncará a 0 bytes.

find /var/log -type f -iname '*.log' -print0 | xargs -0 truncate -s0
Luka
fuente
1
Lo usaría en su *.log*lugar, pero no estoy seguro de si es 100% seguro, por lo que no lo he incluido en la respuesta. Porque hay archivos como dovecot.log-20180930y dovecot.log-20180923.gz.
Luka
0

Existen dos métodos para truncar completamente un archivo, generalmente aplicable a la mayoría de los sistemas operativos compatibles con POSIX. Lo más común que verá con las secuencias de comandos de shell es algo como true > file.txto : > file.txt(y en el caso de bashshell, >solo la redirección es suficiente). Esto se debe a la forma en que los >archivos se abren mediante syscall open()o openat()mediante O_WRONLY|O_CREAT|O_TRUNCindicadores, que lee solo escritura O crea si el nombre de archivo no existe, O trunca el nombre de archivo existente.

Con eso en mente, podemos implementar algo así en C nosotros mismos:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv){
    if (argc == 2){
        int fd = open(argv[1],O_TRUNC);
        close(fd);
    }

    return 0;
}

Asigne un nombre al archivo que almacena este código trunc.cy compílelo gcc trunc.c -o trunc, y usted tiene una pequeña utilidad que truncará un argumento de nombre de archivo que se proporciona como en trunc ./foobar.txt. Por supuesto, este código no realiza otras verificaciones, solo trunca el primer parámetro posicional. Dejaré que los lectores descubran cómo lidiar con más de un parámetro posicional. En la nota al margen, hay truncate()syscall que también podríamos usar, y truncar un archivo a una longitud variable.

Ahora, si no eres fanático de C, Python podría ser más fácil para ti. open()El comando funciona según el mismo principio en Python: abrir el archivo para escribir y truncar si existe un nombre de archivo. Así podemos hacer

python -c 'import sys;open(sys.argv[1],"w").close()' passwd.copy 

En cuanto a encontrar todos los .logarchivos, eso ya se ha cubierto en otras respuestas: use *glob o glob extendido bash. También hay find -type f -name "*.log", que tiene un -execindicador para ejecutar comandos (en este caso particular sh -c ''para aprovechar >porque >es un operador de shell y no un ejecutable externo). Así puedes hacer

find /var/log -type f -name "*.log" -exec sh -c 'true > "$1"' sh {} \;

Es también digno de mención que los archivos de registro en el directorio, como /var/loga menudo se hacen girar a través del servicio logrotate, por lo que habrá nombres de archivo tales como /var/log/service.log, /var/log/service.log.1, etc., por lo que puede que quiera usar *.log.[1-9]el patrón vez


Entre otras cosas, podemos copiar /dev/nullen el archivo deseado. Por extraño que parezca, a pesar de que /dev/nulles un tipo de archivo de dispositivo de caracteres especiales, cuando copia eso en otro lugar, el resultado es un archivo normal vacío, al menos con GNU cp. Así podemos hacer

cp /dev/null foo.txt

o

dd if=/dev/null of=foo.txt

Otra lectura sugerida:

Sergiy Kolodyazhnyy
fuente
0

Es una buena práctica rotar los registros en / var / logs para rotar con la funcionalidad logrotate, pero no siempre que lo deseemos. Se imprimirán registros del sistema y serán útiles para depurar cualquier falla.

Si es un requisito no utilizar logrotate, se pueden explorar las opciones. Aunque truncar es una opción fácil en algunos sistemas del sistema Unix, este comando no está disponible fácilmente, es necesario instalarlo. Si no se permite instalar el nuevo comando, se puede usar el siguiente bucle.

for logfile $(ls /path/*.log)
do 
  cat /dev/null > $logfile
done
Devoloper250
fuente
Bash Pitfall # 1 : No escriba para bucles de esa manera. Usar en su for logfile in /path/*.loglugar.
PerlDuck