Here is a digital clock I just made as an exercise in bash scripting:
#!/usr/bin/env bash
# A rather nice looking digital clock in the terminal.
function cleanup_() {
printf '\033[?25h' # unhide cursor
stty echo 2>/dev/null
}
trap cleanup_ EXIT
REFRESH_INTERVAL=0.2 # display the clock every 0.2 seconds, adjust if necessary
TIME_FORMAT="%H:%M:%S" # change to "%I:%M:%S" for 12-hour format
# Feel free to modify the FONT, the only restriction is that all characters are
# of equal height. There should be 11 characters, in this order: "0123456780:"
FONT=(
"█▀▀█ "
"█ █ "
"█ █ "
"▀▀▀▀ "
" █ "
" █ "
" █ "
" ▀ "
"▀▀▀█ "
"▄▄▄█ "
"█ "
"▀▀▀▀ "
"▀▀▀█ "
"▄▄▄█ "
" █ "
"▀▀▀▀ "
"█ █ "
"█▄▄█ "
" █ "
" ▀ "
"█▀▀▀ "
"█▄▄▄ "
" █ "
"▀▀▀▀ "
"█▀▀▀ "
"█▄▄▄ "
"█ █ "
"▀▀▀▀ "
"▀▀▀█ "
" █ "
" █ "
" ▀ "
"█▀▀█ "
"█▄▄█ "
"█ █ "
"▀▀▀▀ "
"█▀▀█ "
"█▄▄█ "
" █ "
"▀▀▀▀ "
" "
" ▀ "
" "
" ▀ "
)
FONT_HEIGHT=$(( ${#FONT[@]} / 11 )) # FONT height in characters
function figletise() {
read str;
for (( line = 0; line < FONT_HEIGHT; line++ )); do
printf " "
for (( c=0; c<${#str}; c++ )); do
local ch=$(LC_CTYPE=C printf '%d' "'${str:$c:1}") # get ascii value
ch=$((ch-48))
if (( ch >= 0 && ch <= 10 )); then
local i=$(( ch * FONT_HEIGHT + line )) # 2D -> 1D array conversion
printf '%s' "${FONT[$i]}"
fi
done
printf "\n"
done
}
stty -echo 2>/dev/null
printf '\033[?25l\n' # hide cursor
unset EXIT_
while true; do
date +"$TIME_FORMAT" | figletise
[[ -z $EXIT_ ]] || exit 0
read -t $REFRESH_INTERVAL -n 1 && EXIT_=1; # bloat for freebird
printf "\033[${FONT_HEIGHT}A\r" # move cursor to beginning,
# fixed for crappy terminals
done
Most of it is quite simple, but there are two interesting things about it (in my opinion):
- the escape sequence
\033[F
which works a bit like the carriage return\r
from the progress bar script above, but in addition, moves the cursor one line up - the way of obtaining ASCII code of a character, using
printf
function and a single quote character – a rather insane syntax which I haven’t seen before, but it works. Read about it here: http://mywiki.wooledge.org/BashFAQ/071