alwayslast.bash

Este script permite poner en un archivo las últimas N líneas de una salida. Por ejemplo, ping [...] | alwayslast.bash FILE 10 permitiría que FILE tuviera las últimas 10 líneas de la salida de ping.

This script allows for a file to have the las N lines of an output. For example, ping [...] | alwayslast.bash FILE 10 would make FILE always have the last 10 lines from the output of ping.

#!/bin/bash

if [ "$#" -ne 2 ]; then
 echo "Usage: $0 output_file maxlines"
 exit 2
fi

FILE="$1"
MAXLINES="$2"

START=0
LINES=1

while IFS= read -r NEWLINE; do
 BUFFER[START]="$NEWLINE"

 TEMPFILE=$(mktemp)
 trap -- 'rm "$TEMPFILE"' EXIT INT TERM

 for INDEX in $(seq "$((START+1))" "$((LINES-1))") $(seq 0 "$START"); do
 printf '%s\n' "${BUFFER[$INDEX]}"
 done > "$TEMPFILE"

 chmod --reference="$FILE" "$TEMPFILE"
 mv "$TEMPFILE" "$FILE"
 trap -- EXIT INT TERM

 LINES="$((LINES+1))"
 if [ "$LINES" -gt "$MAXLINES" ]; then
 LINES="$MAXLINES"
 fi
 START="$(((START + 1) % MAXLINES))"
done

Gracias a Eduardo Bustamante por sus correcciones.


Comentarios

alwayslast.bash — 2 comentarios

  1. OUCH… Suena correcto, pero MUY gastalón 🙂

    ¿Por qué no usas una implementación ampliamente conocida y difundida? Digamos… El comando «last»?

    $ genera_salida –larga –demasiado | last -15

    • Tail (por la sintaxis veo que te referías a tail) sólo arroja las últimas líneas de un stream cerrado. (–follow tampoco es útil en este caso).

      Alwayslast.bash va consumiendo la entada estándar de un stream abierto y va exportando a un archivo las que hasta el momento son las últimas N líneas, remplazando el contenido en cada actualización para que queden sólo las últimas N líneas.

      Caso de uso: no querer esperar a que corran 30 pings para obtener sus estadísticas sino usar los últimos 30 de un ping que ya está en ejecución como fuente de datos.

Responder a Gunnar Wolf Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *