Skip to content

Instantly share code, notes, and snippets.

@literallylara
Last active April 14, 2026 18:28
Show Gist options
  • Select an option

  • Save literallylara/fb2d47789ac3cd0ff9b771f5e7dc86f3 to your computer and use it in GitHub Desktop.

Select an option

Save literallylara/fb2d47789ac3cd0ff9b771f5e7dc86f3 to your computer and use it in GitHub Desktop.
watch + tail = peek: show command output in a limited scrolling region.
#!/bin/bash
DESCRIPTION='watch + tail = peek: show command output in a limited scrolling region.'
VERSION=1.0.4
AUTHOR='@literallylara'
LICENSE='MIT'
WEBSITE='https://codeberg.org/literallylara/scripts/src/branch/main/utility/peek'
# Documentation:
# man console_codes
# man ascii
# man terminfo
# man bash
# ECMA-48 Select Graphic Rendition
SGR_RESET=$'\033[0m'
SGR_REVERSE_VIDEO_ON=$'\033[7m'
SGR_REVERSE_VIDEO_OFF=$'\033[27m'
SGR_COLOR_DEFAULT_FG=$'\033[39m'
SGR_COLOR_RED_FG=$'\033[31m'
SGR_COLOR_GREEN_FG=$'\033[32m'
SGR_COLOR_YELLOW_FG=$'\033[33m'
# Script settings
CHAR_RUNNING=''
CHAR_SUCCESS=''
CHAR_ERROR='×'
OUTPUT_PREFIX="${SGR_COLOR_YELLOW_FG}${SGR_REVERSE_VIDEO_ON} ${SGR_REVERSE_VIDEO_OFF}${SGR_COLOR_DEFAULT_FG} "
#########################
### UTILITY FUNCTIONS ###
#########################
trunc() {
n="$1"
t="$2"
if [ "${#t}" -le "$n" ]; then echo "$t"; else echo "${t:0:n-1}"; fi
}
# Cursor position report (CPR)
# - Command : ESC[6n
# - Response : ESC[y;xR
# man console_codes
term_get_cursor_pos() {
# The `read -p` trick comes from Stack Overflow (see blow).
# It ensures that `read` does not block when executed from within a script.
# https://unix.stackexchange.com/questions/88296/get-vertical-cursor-position/183121#183121
# -s = silent
# -dR = delimiter set to R
# -p = prompt
# IFS = internal field separator(s)
# _ = discarded variable (will be 'ESC')
IFS='[;' read -r -s -dR -p $'\e[6n' _ row col
echo "$row $col"
}
# Equivalent to: tput cup
# See: man console_codes
term_set_cursor_pos() {
row=$1
col=$2
# ESC[y;xH, where y = row, x = column
printf '\033[%d;%dH' "$((row + 1))" "$col" >"$(tty)"
# tput cup $1 $2
}
# Equivalent to: tput csr
# See: man console_codes
term_set_scroll_region() {
top=$1
bottom=$2
# ESC[t;br, where t = top, b = bottom
printf '\033[%d;%dr' "$((top + 1))" "$((bottom + 1))" >"$(tty)"
# tput csr $1 $2
}
term_del_from_cursor_to_end() {
printf "\033[J" >"$(tty)"
# tput ed
}
# Equivalent to: stty size
term_get_size() {
if stty size 2>/dev/null; then
: # already printed to stdout
elif command -v tput >/dev/null; then
echo "$(tput lines) $(tput cols)"
else
echo 'Missing `stty size` or `tput` command'
fi
}
# Equivalent to tput cuu
# See: man console_codes
term_move_cursor_up() {
# ESC[NA, where N = number of rows to move up
printf '\033[%dA' "$((MAX_LINES + 1))" >"$(tty)"
}
# Dynamic globals
cols=$(term_get_size | cut -d' ' -f2)
MAX_TITLE_LENGTH=$((cols - 4))
MAX_LINE_LENGTH=$((cols - 2))
SCRIPT_NAME="$(basename "$0")"
print_help_and_exit() {
echo "Usage: $SCRIPT_NAME [OPTIONS] -- COMMAND"
echo ''
echo 'Options:'
echo ' -h, --help print help and exit'
echo ' -t, --title header title to display. Defaults to COMMAND'
echo ' -n, --max-lines maxmimum number of COMMAND output lines to show at once'
echo ' -o, --out output file to write full COMMAND output to'
echo " -v, --version print version and exit"
echo ''
echo 'Example:'
echo " $SCRIPT_NAME -t 'Counting to 100' -- sh -c 'for i in {1..100}; do echo \$i; sleep .01; done'"
exit
}
# argument parsing
for arg in "$@"; do
shift
case "$arg" in
'-h' | '--help') print_help_and_exit ;;
'-t' | '--title') TITLE="$1" ;;
'-n' | '--max-lines') MAX_LINES="$1" ;;
'-o' | '--out') OUTFILE="$1" ;;
'-v' | '--version')
echo "$SCRIPT_NAME $VERSION - $DESCRIPTION"
echo "License : $LICENSE"
echo "Author : $AUTHOR"
echo "Website : $WEBSITE"
exit
;;
'--') break ;;
esac
done
# argument defaults
if [ -z "$MAX_LINES" ] || [ "$MAX_LINES" = 0 ]; then MAX_LINES=5; fi
if [ -z "$TITLE" ]; then TITLE="$(trunc $MAX_TITLE_LENGTH "$*")"; fi
if [ -z "$OUTFILE" ]; then OUTFILE='/dev/null'; fi
print_header() {
if [ -z "$1" ]; then
color=$SGR_COLOR_YELLOW_FG
status=$CHAR_RUNNING
elif [ "$1" = 0 ]; then
color=$SGR_COLOR_GREEN_FG
status=$CHAR_SUCCESS
else
color=$SGR_COLOR_RED_FG
status=$CHAR_ERROR
fi
printf '%s%s %s %s %s%s\n' "$color" "$SGR_REVERSE_VIDEO_ON" "$status" "$TITLE" "$SGR_REVERSE_VIDEO_OFF" "$SGR_COLOR_DEFAULT_FG"
}
print_header
# make sure we have $ARG_MAX_LINES below us
for _ in $(seq "$MAX_LINES"); do printf '\n'; done
# move cursor back up
term_move_cursor_up $((MAX_LINES + 1))
# get current row
row=$(term_get_cursor_pos | cut -d' ' -f1)
# set terminal scroll region from $row to $row + $ARG_MAX_LINES
term_set_scroll_region "$row" $((row + MAX_LINES))
# move cursor into scroll region
term_set_cursor_pos "$row" 0
# start command, truncate and prefix lines
(if [ "${#@}" -eq 1 ]; then
# evaluate pipes, redirections, etc.
eval "$@"
else
# normal execution
"$@"
fi) 2>&1 | tee "$OUTFILE" | sed -r "s/^(.{$MAX_LINE_LENGTH}).*/\1/; s/^/$OUTPUT_PREFIX/"
# get command output
EXIT_CODE="${PIPESTATUS[0]}"
# reset scroll region
term_set_scroll_region 0 "$(term_get_size | cut -d' ' -f1)"
# move cursor to header
term_set_cursor_pos $((row - 1)) 0
# update header
print_header "$EXIT_CODE"
# remove output
term_del_from_cursor_to_end
# forward exit code
exit "$EXIT_CODE"
@literallylara
Copy link
Copy Markdown
Author

$ peek --help
Usage: peek [OPTIONS] -- COMMAND

Options:
  -h, --help       print help and exit
  -t, --title      header title to display. Defaults to COMMAND
  -n, --max-lines  maxmimum number of COMMAND output lines to show at once
  -o, --out        output file to write full COMMAND output to
  -v, --version    print version and exit

Example:
  peek -t 'Counting to 100' -- sh -c 'for i in {1..100}; do echo $i; sleep .01; done'

peek

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment