Intento mantener las últimas 50 líneas en mi archivo donde guardo la temperatura cada minuto. Usé este comando:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test
Pero el resultado es un archivo de prueba vacío. Pensé, enumerará las últimas 50 líneas del archivo de prueba y lo insertará en el archivo de prueba. Cuando uso este comando:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test2
Está funcionando bien. Hay 50 líneas en el archivo test2.
¿Alguien puede explicarme dónde está el problema?
command-line
logs
tail
dorinand
fuente
fuente
logging
móduloRespuestas:
El problema es que su shell está configurando la canalización de comandos antes de ejecutar los comandos. No es una cuestión de "entrada y salida", es que el contenido del archivo ya se ha ido antes de que se ejecute la cola. Va algo como:
>
archivo de salida para escribir, truncándolotail
.tail
corre, abre/home/pi/Documents/test
y no encuentra nada allíHay varias soluciones, pero la clave es comprender el problema, qué está realmente mal y por qué.
Esto producirá lo que estás buscando,
Explicacion:
$()
se llama sustitución de comando que ejecutatail -n 50 /home/pi/Documents/test
> /home/pi/Documents/test
redirige la salidaecho "$(tail -n 50 /home/pi/Documents/test)"
al mismo archivo.fuente
bash: xrealloc: cannot allocate 18446744071562067968 bytes
Otra solución para la redirección de archivos que borra el archivo primero es usarla
sponge
desde elmoreutils
paquete de esta manera:fuente
Esto se debe a que bash procesa la redirección con la
>
primera, eliminando el contenido del archivo. Luego ejecuta el comando. Si usara>>
, las últimas 50 líneas se agregarían al final de lo que está actualmente en el archivo. En este caso, tendría las mismas 50 líneas repetidas dos veces.El comando funciona como se espera al redirigir a un archivo diferente. Aquí hay una forma de escribir las últimas 50 líneas de un archivo en un archivo con el mismo nombre:
Esto primero escribe las últimas 50 líneas en un archivo temporal, que luego se mueve
mv
para reemplazar el archivo original.Como se señaló en los comentarios, esto no funcionará si el archivo aún está abierto. Mover el archivo también crea un nuevo inodo y puede cambiar la propiedad y los permisos. Una mejor manera de hacer esto usando un archivo temporal sería:
El archivo temporal también se puede eliminar, aunque cada vez que esto ocurra se sobrescribirá su contenido.
fuente
tail -50 /home/pi/Documents/test >/tmp/foo && cat /tmp/foo >/home/pi/Documents/test
tail ... > temp ; cat temp > orig ; rm -f temp
trabajos.Como ha visto el problema principal con la redirección de shell, aquí hay una forma alternativa de podar un archivo a sus últimas 50 líneas:
El trabajo duro lo realiza (GNU) sed con la
-i
función de "edición en el lugar", que funciona bajo las cubiertas al crear la salida en un archivo temporal. El resto de las líneas configuran las matemáticas para la operación de sed, a saber:wc
), luego reste 50; asignar eso an
.n
es positivo, ejecute el comando sed para eliminar las líneas 1 a n.fuente
printf
se utiliza para canalizar comandos (uno por línea) ened
. Losed
comandos son:1,$-50d
- Eliminar todas las últimas 50 líneasw
- escribir el archivo modificado de nuevo en el discoNo hay redirecciones involucradas, por lo que el shell no puede sobrescribir el archivo de salida antes de que se haya leído.
Además, a diferencia de la mayoría de las formas de edición "in situ" (que generalmente solo simulan la edición "in situ" creando un archivo temporal y luego renombrándolo sobre el original), en
ed
realidad edita el archivo original, por lo que mantiene el mismo inodo ( y propietario, grupo y permisos: tempfile + mv siempre cambiará el inodo y puede cambiar los demás según las circunstancias).fuente
En una pista ligeramente diferente, puede usar
logrotate(8)
para hacer copias de seguridad de los archivos de registro regularmente en archivos con nombres incrementales y luego eliminar los antiguos.Así es como se gestionan los archivos de registro del sistema principal para evitar que crezcan demasiado.
fuente