Last active
November 26, 2022 07:11
-
-
Save lucaspar/d6d8e43229ef88f6ffd7ba8f8732cc7b to your computer and use it in GitHub Desktop.
Bash helper for displaying the last lines of an output continuously without cluttering the entire screen like `tail -f`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Display last N lines of input like tail, but cleaning the screen before every update. | |
# Example: date; for i in $(seq 1 2000); do echo $i; sleep 0.03; done | ntail 10 | |
function ntail { | |
# default to 10 lines of tail output | |
NUM_LINES=${1:-10} | |
# gets the current time in milliseconds | |
function mstime() { | |
date +%s%3N | |
} | |
LAST_UPDATE=$(mstime) # last time the screen was updated | |
NEEDS_REFRESH=false # whether to refresh the screen | |
SCREEN_BUFFER_SIZE=0 # number of lines on the screen | |
while IFS= read -r NEW_LINE; do | |
# concatenate new the new line to the buffer | |
TAIL_BUFFER="$TAIL_BUFFER$NEW_LINE"$'\n' | |
# if last update is greater than 100ms, refresh screen | |
if [ $(($(mstime) - LAST_UPDATE)) -gt 100 ]; then | |
NEEDS_REFRESH=true | |
fi | |
# refresh screen if needed | |
if [ "$NEEDS_REFRESH" = true ]; then | |
# reduce buffer size to last NUM_LINES lines | |
TAIL_BUFFER=$(echo "$TAIL_BUFFER" | tail -n "$NUM_LINES")$'\n' | |
# clear the last SCREEN_BUFFER_SIZE lines, preserving the stdout above that | |
for _ in $(seq 1 "$SCREEN_BUFFER_SIZE"); do | |
printf "\033[1A\033[2K" | |
done | |
# print the new buffer | |
printf "%s" "$TAIL_BUFFER" | |
SCREEN_BUFFER_SIZE=$(echo "$TAIL_BUFFER" | wc -l) | |
SCREEN_BUFFER_SIZE=$((SCREEN_BUFFER_SIZE - 1)) | |
LAST_UPDATE=$(mstime) | |
NEEDS_REFRESH=false | |
fi | |
done < /dev/stdin | |
} | |
ntail "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment