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.

Deja un comentario

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