356 lines
11 KiB
Bash
356 lines
11 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
########################################################
|
|
# Simple and fancy input & output
|
|
########################################################
|
|
|
|
which tput > /dev/null 2>&1 && [[ $(tput -T$TERM colors) -gt 8 ]] && CAN_USE_COLORS=1 || CAN_USE_COLORS=0
|
|
USE_COLORS=${USE_COLORS:-$CAN_USE_COLORS}
|
|
|
|
# Icons (message prefixes)
|
|
[[ "$USE_COLORS" == 1 ]] && IINFO="( i )" || IINFO=''
|
|
[[ "$USE_COLORS" == 1 ]] && INOTE="( * )" || INOTE=''
|
|
[[ "$USE_COLORS" == 1 ]] && IWARN="( # )" || IWARN=''
|
|
[[ "$USE_COLORS" == 1 ]] && IERROR="( ! )" || IERROR=''
|
|
[[ "$USE_COLORS" == 1 ]] && IFATAL="( @ )" || IFATAL=''
|
|
[[ "$USE_COLORS" == 1 ]] && ISUCCESS="( ! )" || ISUCCESS=''
|
|
[[ "$USE_COLORS" == 1 ]] && IASK="( ? )" || IASK=''
|
|
[[ "$USE_COLORS" == 1 ]] && IDEBUG="(DBG)" || IDEBUG=''
|
|
[[ "$USE_COLORS" == 1 ]] && IVRB="( + )" || IVRB=''
|
|
|
|
# Text attributes
|
|
[[ "$USE_COLORS" == 1 ]] && FRESET="$(tput sgr0)" || FRESET='' # Normal
|
|
[[ "$USE_COLORS" == 1 ]] && FBOLD="$(tput bold)" || FBOLD='' # Bold
|
|
[[ "$USE_COLORS" == 1 ]] && FDIM="$(tput dim)" || FDIM='' # Dimmed
|
|
[[ "$USE_COLORS" == 1 ]] && FLINE="$(tput smul)" || FLINE='' # Underlined
|
|
[[ "$USE_COLORS" == 1 ]] && FENDLINE="$(tput rmul)" || FENDLINE='' # End of underlined
|
|
[[ "$USE_COLORS" == 1 ]] && FBLINK="$(tput blink)" || FBLINK='' # Blink
|
|
[[ "$USE_COLORS" == 1 ]] && FREV="$(tput rev)" || FREV='' # Reversed
|
|
|
|
# Text colors - normal
|
|
[[ "$USE_COLORS" == 1 ]] && FBLACK="$(tput setaf 0)" || FBLACK='' # Black
|
|
[[ "$USE_COLORS" == 1 ]] && FRED="$(tput setaf 1)" || FRED='' # Red
|
|
[[ "$USE_COLORS" == 1 ]] && FGREEN="$(tput setaf 2)" || FGREEN='' # Green
|
|
[[ "$USE_COLORS" == 1 ]] && FYELLOW="$(tput setaf 3)" || FYELLOW='' # Yellow
|
|
[[ "$USE_COLORS" == 1 ]] && FBLUE="$(tput setaf 4)" || FBLUE='' # Blue
|
|
[[ "$USE_COLORS" == 1 ]] && FPURPLE="$(tput setaf 5)" || FPURPLE='' # Purple
|
|
[[ "$USE_COLORS" == 1 ]] && FCYAN="$(tput setaf 6)" || FCYAN='' # Cyan
|
|
[[ "$USE_COLORS" == 1 ]] && FWHITE="$(tput setaf 7)" || FWHITE='' # White
|
|
|
|
# Text colors - bright
|
|
[[ "$USE_COLORS" == 1 ]] && FLBLACK="$(tput setaf 8)" || FLBLACK='' # Black
|
|
[[ "$USE_COLORS" == 1 ]] && FLRED="$(tput setaf 9)" || FLRED='' # Red
|
|
[[ "$USE_COLORS" == 1 ]] && FLGREEN="$(tput setaf 10)" || FLGREEN='' # Green
|
|
[[ "$USE_COLORS" == 1 ]] && FLYELLOW="$(tput setaf 11)" || FLYELLOW='' # Yellow
|
|
[[ "$USE_COLORS" == 1 ]] && FLBLUE="$(tput setaf 12)" || FLBLUE='' # Blue
|
|
[[ "$USE_COLORS" == 1 ]] && FLPURPLE="$(tput setaf 13)" || FLPURPLE='' # Purple
|
|
[[ "$USE_COLORS" == 1 ]] && FLCYAN="$(tput setaf 14)" || FLCYAN='' # Cyan
|
|
[[ "$USE_COLORS" == 1 ]] && FLWHITE="$(tput setaf 15)" || FLWHITE='' # White
|
|
|
|
# Background colors - normal
|
|
[[ "$USE_COLORS" == 1 ]] && FBBLACK="$(tput setab 0)" || FBBLACK='' # Black
|
|
[[ "$USE_COLORS" == 1 ]] && FBRED="$(tput setab 1)" || FBRED='' # Red
|
|
[[ "$USE_COLORS" == 1 ]] && FBGREEN="$(tput setab 2)" || FBGREEN='' # Green
|
|
[[ "$USE_COLORS" == 1 ]] && FBYELLOW="$(tput setab 3)" || FBYELLOW='' # Yellow
|
|
[[ "$USE_COLORS" == 1 ]] && FBBLUE="$(tput setab 4)" || FBBLUE='' # Blue
|
|
[[ "$USE_COLORS" == 1 ]] && FBPURPLE="$(tput setab 5)" || FBPURPLE='' # Purple
|
|
[[ "$USE_COLORS" == 1 ]] && FBCYAN="$(tput setab 6)" || FBCYAN='' # Cyan
|
|
[[ "$USE_COLORS" == 1 ]] && FBWHITE="$(tput setab 7)" || FBWHITE='' # White
|
|
|
|
# Background colors - bright
|
|
[[ "$USE_COLORS" == 1 ]] && FBLBLACK="$(tput setab 8)" || FBLBLACK='' # Black
|
|
[[ "$USE_COLORS" == 1 ]] && FBLRED="$(tput setab 9)" || FBLRED='' # Red
|
|
[[ "$USE_COLORS" == 1 ]] && FBLGREEN="$(tput setab 10)" || FBLGREEN='' # Green
|
|
[[ "$USE_COLORS" == 1 ]] && FBLYELLOW="$(tput setab 11)" || FBLYELLOW='' # Yellow
|
|
[[ "$USE_COLORS" == 1 ]] && FBLBLUE="$(tput setab 12)" || FBLBLUE='' # Blue
|
|
[[ "$USE_COLORS" == 1 ]] && FBLPURPLE="$(tput setab 13)" || FBLPURPLE='' # Purple
|
|
[[ "$USE_COLORS" == 1 ]] && FBLCYAN="$(tput setab 14)" || FBLCYAN='' # Cyan
|
|
[[ "$USE_COLORS" == 1 ]] && FBLWHITE="$(tput setab 15)" || FBLWHITE='' # White
|
|
|
|
now() {
|
|
echo "[$(date +'%H:%M:%S')] "
|
|
}
|
|
|
|
ask() {
|
|
IFS= read -rp "$(print ${FBOLD}${FBBLUE}${FWHITE}${IASK}${FRESET}\ ${FBOLD}$1 ): " $2
|
|
}
|
|
|
|
print() {
|
|
echo -e "$*${FRESET}"
|
|
}
|
|
|
|
debug() {
|
|
if [ "$2" ]; then
|
|
print "${FDIM}${FBOLD}${FRESET}${FDIM}$(now)${IDEBUG} ${FUNCNAME[1]:-?}():${BASH_LINENO:-?}\t$1 " >&2
|
|
else
|
|
print "${FDIM}${FBOLD}${FRESET}${FDIM}$(now)${IDEBUG} $1 " >&2
|
|
fi
|
|
}
|
|
|
|
var_dump() {
|
|
debug "$1 = ${!1}"
|
|
}
|
|
|
|
print_stacktrace() {
|
|
STACK=""
|
|
local i
|
|
local stack_size=${#FUNCNAME[@]}
|
|
debug "Callstack:"
|
|
# for (( i=$stack_size-1; i>=1; i-- )); do
|
|
for (( i=1; i<$stack_size; i++ )); do
|
|
local func="${FUNCNAME[$i]}"
|
|
[ x$func = x ] && func=MAIN
|
|
local linen="${BASH_LINENO[$(( i - 1 ))]}"
|
|
local src="${BASH_SOURCE[$i]}"
|
|
[ x"$src" = x ] && src=non_file_source
|
|
debug " at $func $src:$linen"
|
|
done
|
|
}
|
|
|
|
verbose() {
|
|
print "${FBOLD}$(now)${IVRB}${FRESET}${FYELLOW} $1 "
|
|
}
|
|
|
|
info() {
|
|
print "${FBOLD}$(now)${FWHITE}${FBLBLUE}${IINFO}${FRESET}${FWHITE} $1 "
|
|
}
|
|
|
|
note() {
|
|
print "${FBOLD}$(now)${FDIM}${FWHITE}${INOTE}${FRESET} $1 "
|
|
}
|
|
|
|
success() {
|
|
print "${FBOLD}$(now)${FBGREEN}${FWHITE}${ISUCCESS}${FRESET}$FGREEN $1 "
|
|
}
|
|
|
|
warn() {
|
|
print "${FBOLD}$(now)${FBYELLOW}${FBLACK}${IWARN}${FRESET}${FYELLOW} Warning:${FRESET} $1 "
|
|
}
|
|
|
|
error() {
|
|
print "${FBOLD}$(now)${FBLRED}${FWHITE}${IERROR} Error: ${FRESET}${FLRED} $1 " >&2
|
|
}
|
|
|
|
fatal() {
|
|
print "${FBOLD}$(now)${FBRED}${FWHITE}${IFATAL} FATAL: $1 " >&2
|
|
print_stacktrace
|
|
}
|
|
|
|
die() {
|
|
error "${1:-halted}"
|
|
exit ${2:-255}
|
|
}
|
|
|
|
var='test var_dump'
|
|
var_dump var
|
|
debug 'test debug'
|
|
verbose 'test verbose'
|
|
info 'test info'
|
|
note 'test note'
|
|
success 'test success'
|
|
warn 'test warn'
|
|
error 'test error'
|
|
fatal 'test fatal'
|
|
die 'test die'
|
|
|
|
# experiments ==============================================================================
|
|
|
|
# https://unix.stackexchange.com/a/269085
|
|
# https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
|
|
# https://linuxcommand.org/lc3_adv_tput.php
|
|
# https://gist.github.com/nowmilano/4055d6df5b6e4ea87c5a72dc2d604193
|
|
# https://gist.github.com/nick3499/402a6d7dccd474f2bdb679f4311b1238
|
|
# https://gist.github.com/connorjan/2b02126868157c2b69f9aa0a052cdc86
|
|
|
|
# tput setaf 0
|
|
# echo "BLACK FOREGROUND"
|
|
# tput setaf 1
|
|
# echo "RED FOREGROUND"
|
|
# tput setaf 2
|
|
# echo "GREEN FOREGROUND"
|
|
# tput setaf 3
|
|
# echo "YELLOW FOREGROUND"
|
|
# tput setaf 4
|
|
# echo "BLUE FOREGROUND"
|
|
# tput setaf 5
|
|
# echo "MAGENTA FOREGROUND"
|
|
# tput setaf 6
|
|
# echo "CYAN FOREGROUND"
|
|
# tput setaf 7
|
|
# echo "WHITE FOREGROUND"
|
|
# tput reset
|
|
|
|
# ===========
|
|
|
|
|
|
# ===========
|
|
|
|
# tohex(){
|
|
# dec=$(($1%256)) ### input must be a number in range 0-255.
|
|
# if [ "$dec" -lt "16" ]; then
|
|
# bas=$(( dec%16 ))
|
|
# mul=128
|
|
# [ "$bas" -eq "7" ] && mul=192
|
|
# [ "$bas" -eq "8" ] && bas=7
|
|
# [ "$bas" -gt "8" ] && mul=255
|
|
# a="$(( (bas&1) *mul ))"
|
|
# b="$(( ((bas&2)>>1)*mul ))"
|
|
# c="$(( ((bas&4)>>2)*mul ))"
|
|
# printf 'dec= %3s basic= #%02x%02x%02x\n' "$dec" "$a" "$b" "$c"
|
|
# elif [ "$dec" -gt 15 ] && [ "$dec" -lt 232 ]; then
|
|
# b=$(( (dec-16)%6 )); b=$(( b==0?0: b*40 + 55 ))
|
|
# g=$(( (dec-16)/6%6)); g=$(( g==0?0: g*40 + 55 ))
|
|
# r=$(( (dec-16)/36 )); r=$(( r==0?0: r*40 + 55 ))
|
|
# printf 'dec= %3s color= #%02x%02x%02x\n' "$dec" "$r" "$g" "$b"
|
|
# else
|
|
# gray=$(( (dec-232)*10+8 ))
|
|
# printf 'dec= %3s gray= #%02x%02x%02x\n' "$dec" "$gray" "$gray" "$gray"
|
|
# fi
|
|
# }
|
|
|
|
# for i in $(seq 0 255); do
|
|
# tohex ${i}
|
|
# done
|
|
|
|
# ===========
|
|
|
|
# fromhex(){
|
|
# hex=${1#"#"}
|
|
# r=$(printf '0x%0.2s' "$hex")
|
|
# g=$(printf '0x%0.2s' ${hex#??})
|
|
# b=$(printf '0x%0.2s' ${hex#????})
|
|
# printf '%03d' "$(( (r<75?0:(r-35)/40)*6*6 +
|
|
# (g<75?0:(g-35)/40)*6 +
|
|
# (b<75?0:(b-35)/40) + 16 ))"
|
|
# }
|
|
|
|
# fromhex 00fc7b
|
|
|
|
# ===========
|
|
|
|
# mode2header(){
|
|
# #### For 16 Million colors use \e[0;38;2;R;G;Bm each RGB is {0..255}
|
|
# printf '\e[mR\n' # reset the colors.
|
|
# printf '\n\e[m%59s\n' "Some samples of colors for r;g;b. Each one may be 000..255"
|
|
# printf '\e[m%59s\n' "for the ansi option: \e[0;38;2;r;g;bm or \e[0;48;2;r;g;bm :"
|
|
# }
|
|
|
|
# mode2colors(){
|
|
# # foreground or background (only 3 or 4 are accepted)
|
|
# local fb="$1"
|
|
# [[ $fb != 3 ]] && fb=4
|
|
# local samples=(0 63 127 191 255)
|
|
# for r in "${samples[@]}"; do
|
|
# for g in "${samples[@]}"; do
|
|
# for b in "${samples[@]}"; do
|
|
# printf '\e[0;%s8;2;%s;%s;%sm%03d;%03d;%03d ' "$fb" "$r" "$g" "$b" "$r" "$g" "$b"
|
|
# done; printf '\e[m\n'
|
|
# done; printf '\e[m'
|
|
# done; printf '\e[mReset\n'
|
|
# }
|
|
# mode2header
|
|
# mode2colors 3
|
|
# mode2colors 4
|
|
|
|
# ===========
|
|
|
|
# printf '\e[48;5;%dm ' {0..255}; printf '\e[0m \n'
|
|
# for r in {200..255..5}; do
|
|
# fb=4
|
|
# g=1
|
|
# b=1
|
|
# printf '\e[0;%s8;2;%s;%s;%sm ' "$fb" "$r" "$g" "$b"
|
|
# done
|
|
# echo
|
|
|
|
# ===========
|
|
|
|
# color(){
|
|
# for c; do
|
|
# printf '\e[48;5;%dm%03d' $c $c
|
|
# done
|
|
# printf '\e[0m \n'
|
|
# }
|
|
|
|
# IFS=$' \t\n'
|
|
# color {0..15}
|
|
# for ((i=0;i<6;i++)); do
|
|
# color $(seq $((i*36+16)) $((i*36+51)))
|
|
# done
|
|
# color {232..255}
|
|
|
|
# ===========
|
|
|
|
# for ((i=0; i<256; i++)) ;do
|
|
# echo -n ' '
|
|
# tput setab $i
|
|
# tput setaf $(( ( (i>231&&i<244 ) || ( (i<17)&& (i%8<2)) ||
|
|
# (i>16&&i<232)&& ((i-16)%6 <(i<100?3:2) ) && ((i-16)%36<15) )?7:16))
|
|
# printf " C %03d " $i
|
|
# tput op
|
|
# (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
|
|
# printf "\n" ''
|
|
# done
|
|
|
|
# ===========
|
|
|
|
# echo "tput character test"
|
|
# echo "==================="
|
|
# echo
|
|
|
|
# tput bold; echo "This text has the bold attribute."; tput sgr0
|
|
|
|
# tput smul; echo "This text is underlined (smul)."; tput rmul
|
|
|
|
# # Most terminal emulators do not support blinking text (though xterm
|
|
# # does) because blinking text is considered to be in bad taste ;-)
|
|
# tput blink; echo "This text is blinking (blink)."; tput sgr0
|
|
|
|
# tput rev; echo "This text has the reverse attribute"; tput sgr0
|
|
|
|
# # Standout mode is reverse on many terminals, bold on others.
|
|
# tput smso; echo "This text is in standout mode (smso)."; tput rmso
|
|
|
|
# tput sgr0
|
|
# echo
|
|
|
|
|
|
# experiments ==============================================================================
|
|
|
|
# function delay_spinner(){
|
|
# ##
|
|
# ## Usage:
|
|
# ##
|
|
# ## $ long-running-command &
|
|
# ## $ delay_spinner " Please wait msg..."
|
|
# ##
|
|
# ## Spinner exists when long-running-command completes
|
|
# ##
|
|
# local PROGRESSTXT
|
|
# if [ ! "$1" ]; then
|
|
# PROGRESSTXT=" Please wait..."
|
|
# else
|
|
# PROGRESSTXT="$1"
|
|
# fi
|
|
# # visual progress marker function
|
|
# # http://stackoverflow.com/users/2869509/wizurd
|
|
# # vars
|
|
# local pid=$!
|
|
# local delay=0.1
|
|
# local spinstr='|/-\'
|
|
# echo -e "\n\n"
|
|
# while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
|
|
# local temp=${spinstr#?}
|
|
# printf "\r$PROGRESSTXT[%c] " "$spinstr"
|
|
# local spinstr=$temp${spinstr%"$temp"}
|
|
# sleep $delay
|
|
# printf "\b\b\b\b\b\b"
|
|
# done
|
|
# printf -- '\n\n'
|
|
# #
|
|
# # <-- end function ec2cli_spinner -->
|
|
# #
|
|
# }
|
|
# sleep 10 && echo 'test' &
|
|
# delay_spinner "Please wait msg..."
|