View on GitHub

bash-funk

bash-funk is a collection of useful commands for Bash 3.2 or higher.

Bash-Funk “ansi” module

The following commands are available when this module is loaded:

  1. -ansi-alternate
  2. -ansi-bold
  3. -ansi-codes
  4. -ansi-colors-supported
  5. -ansi-colors16
  6. -ansi-colors256
  7. -ansi-reset
  8. -ansi-ul
  9. -cursor-pos
  10. -test-all-ansi

License

SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com)
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-ansi-alternate

Usage: -ansi-alternate [OPTION]... [ANSI_SEQUENCE]...

Alternately colorizes the line read from stdin. If stdout is no terminal highlighting is disabled automatically.

Parameters:
  ANSI_SEQUENCE
      ANSI escape sequence used for every n-th row, defaults to' '\033[35m'.

Options:
    --color [WHEN] (default: 'auto', one of: [always,auto,never])
        Indicates when to colorize the output.
    --skip LINES (integer: 0-?)
        Do not colorize the first N lines.
    -----------------------------
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Examples:
$  echo -e 'line1\nline2\nline3\nline4' | -ansi-alternate

$  echo -e 'line1\nline2\nline3\nline4' | -ansi-alternate '\033[31m'

$  echo -e 'line1\nline2\nline3\nline4' | -ansi-alternate '\033[31m' '\033[32m'

$  echo -e 'line1\nline2\nline3\nline4' | -ansi-alternate '\033[31m' '\033[32m' '\033[33m'

$  echo -e 'line1\nline2\nline3\nline4' | -ansi-alternate '\033[31m' --skip 3

Implementation:

# check if stdin is opend on terminal (and thus not on a pipe)
if [[ -t 0 ]]; then
   return 0
fi

local colorize
case "${_color:-auto}" in
   always) colorize=1 ;;
   never) colorize=0 ;;
   auto)
      if -ansi-colors-supported 8 && [[ -t 1 ]]; then
         colorize=1
      else
         colorize=0
      fi
esac

if [[ $colorize == 1 ]]; then
   local ansi_sequences_count=${#_ANSI_SEQUENCE[@]}
   if (( ansi_sequences_count == 0 )); then
      _ANSI_SEQUENCE=( '\033[35m' '' )
      ansi_sequences_count=2
   elif (( ansi_sequences_count == 1 )); then
      _ANSI_SEQUENCE=( "${_ANSI_SEQUENCE[0]}" '' )
      ansi_sequences_count=2
   fi

   local line line_no=0 skip=${_skip:0}
   while IFS='$\n' read -r line; do
      (( line_no++ ))
      if (( line_no > skip )); then
         echo -ne "${_ANSI_SEQUENCE[$(( ( (line_no - skip) - 1) % ansi_sequences_count ))]}"
         echo -n "$line"
         echo -e "\033[0m"
      else
         echo "$line"
      fi
   done
else
   local line
   while IFS='$\n' read -r line; do
      echo "$line"
   done
fi

-ansi-bold

Usage: -ansi-bold [OPTION]... [TEXT]

Sets bold mode or prints the given text in bold.

Parameters:
  TEXT
      The text to print in bold.

Options:
    --off
        Print the ANSI escape sequence that disables sets bold attribute.
    --on
        Print the ANSI escape sequence that enables sets bold attribute.
    -----------------------------
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

if [[ $_TEXT ]]; then
   echo -ne "\033[1m$_TEXT\033[22m"
fi

if [[ $_on ]]; then
   echo -ne "\033[1m"
elif [[ $_off ]]; then
   echo -ne "\033[22m"
fi

-ansi-codes

Usage: -ansi-codes [OPTION]... [PREFIX]

Prints commands to set variables with common ANSI codes. When used with the 'echo' command, the -e option is not required.

Parameters:
  PREFIX (default: 'ANSI_')
      Prefix to be used for the declared variables.

Options:
-e, --escape
        If specified the escape code will be printed as octal value .
    -----------------------------
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

if [[ $_escape ]]; then
   local ESC="\033";
else
   local ESC=$(echo -e "\033");
fi

echo "
${_PREFIX}RESET=\"$ESC[0m\"
${_PREFIX}BOLD=\"$ESC[1m\"
${_PREFIX}BOLD_OFF=\"$ESC[22m\"
${_PREFIX}ITALIC=\"$ESC[3m\"
${_PREFIX}UNDERLINE=\"$ESC[4m\"
${_PREFIX}UNDERLINE_DOUBLE=\"$ESC[21m\"
${_PREFIX}UNDERLINE_OFF=\"$ESC[24m\"
${_PREFIX}BLINK_SLOW=\"$ESC[5m\"
${_PREFIX}BLINK_FAST=\"$ESC[6m\"
${_PREFIX}BLINK_OFF=\"$ESC[25m\"
${_PREFIX}INVERT=\"$ESC[7m\"
${_PREFIX}INVERT_OFF=\"$ESC[27m\"

${_PREFIX}FG_BLACK=\"$ESC[30m\"
${_PREFIX}FG_RED=\"$ESC[31m\"
${_PREFIX}FG_GREEN=\"$ESC[32m\"
${_PREFIX}FG_YELLOW=\"$ESC[33m\"
${_PREFIX}FG_BLUE=\"$ESC[34m\"
${_PREFIX}FG_MAGENTA=\"$ESC[35m\"
${_PREFIX}FG_CYAN=\"$ESC[36m\"
${_PREFIX}FG_GRAY=\"$ESC[37m\"

${_PREFIX}FG_LIGHT_RED=\"$ESC[91m\"
${_PREFIX}FG_LIGHT_GREEN=\"$ESC[92m\"
${_PREFIX}FG_LIGHT_YELLOW=\"$ESC[93m\"
${_PREFIX}FG_LIGHT_BLUE=\"$ESC[94m\"
${_PREFIX}FG_LIGHT_MAGENTA=\"$ESC[95m\"
${_PREFIX}FG_LIGHT_CYAN=\"$ESC[96m\"
${_PREFIX}FG_WHITE=\"$ESC[97m\"

${_PREFIX}BG_BLACK=\"$ESC[40m\"
${_PREFIX}BG_RED=\"$ESC[41m\"
${_PREFIX}BG_GREEN=\"$ESC[42m\"
${_PREFIX}BG_YELLOW=\"$ESC[43m\"
${_PREFIX}BG_BLUE=\"$ESC[44m\"
${_PREFIX}BG_MAGENTA=\"$ESC[45m\"
${_PREFIX}BG_CYAN=\"$ESC[46m\"
${_PREFIX}BG_GRAY=\"$ESC[47m\"

${_PREFIX}BG_LIGHT_BLACK=\"$ESC[100m\"
${_PREFIX}BG_LIGHT_RED=\"$ESC[101m\"
${_PREFIX}BG_LIGHT_GREEN=\"$ESC[102m\"
${_PREFIX}BG_LIGHT_YELLOW=\"$ESC[103m\"
${_PREFIX}BG_LIGHT_BLUE=\"$ESC[104m\"
${_PREFIX}BG_LIGHT_MAGENTA=\"$ESC[105m\"
${_PREFIX}BG_LIGHT_CYAN=\"$ESC[106m\"
${_PREFIX}BG_WHITE=\"$ESC[107m\"
"

-ansi-colors-supported

Usage: -ansi-colors-supported [OPTION]... [NUM_COLORS]

Determines if the given number of ANSI colors is supported by the current terminal. If NUM_COLORS is specified, the exit value indicates if the color range is supported. If NUM_COLORS is not specified, the number of supported colors is printed with exit code 0.

Parameters:
  NUM_COLORS
      Number of colors that need to be supported.

Options:
-v, --verbose
        Prints additional information during command execution.
    -----------------------------
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Examples:
$ -ansi-colors-supported 
256
$ -ansi-colors-supported -v 8
Terminal 'xterm' supports 8 colors.

Implementation:

local numColors
if hash tput &>/dev/null; then
   numColors=$(tput colors)
elif hash infocmp &>/dev/null; then
   local termInfo=$(infocmp $TERM || true);
   if [[ $termInfo =~ colors#([0-9]+), ]]; then
      local numColors=${BASH_REMATCH[1]}
   else
      numColors=-1
   fi
elif [[ $TERM == "cygwin" ]]; then
   numColors=8
else
   numColors=-1
fi

if [[ $_NUM_COLORS ]]; then
   if [[ $numColors -ge $_NUM_COLORS ]]; then
      [[ $_verbose ]] && echo "Terminal '$TERM' supports $numColors colors."
      return 0
   else
      [[ $_verbose ]] && echo "Terminal '$TERM' supports only $numColors colors."
      return 1
   fi
else
   echo $numColors
   return 0
fi

-ansi-colors16

Usage: -ansi-colors16 [OPTION]...

Prints a table with 8/16 ANSI colors.

Options:
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

if ! -ansi-colors-supported 8; then
   echo "WARNING: Your current terminal '$TERM' is reported to not support displaying 8 colors."
   echo
elif ! -ansi-colors-supported 16; then
   echo "WARNING: Your current terminal '$TERM' is reported to not support displaying 16 colors."
   echo
fi

echo "To set one of the following color combinations use '\033[<BG>;<FG>m'"
echo
echo -n "      "
for fg in {30..37} 39 {90..97}; do
   printf "  FG %2d" "$fg"
done
echo
for bg in {40..47} 49 {100..107}; do
   printf "BG %3d " "$bg"
   for fg in {30..37} 39 {90..97}; do
      printf "\033[${bg};${fg}m%3d;%2d\033[0m " "$bg" "$fg"
   done
   echo
done

-ansi-colors256

Usage: -ansi-colors256 [OPTION]...

Prints a table with 256 ANSI colors.

Options:
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

if ! -ansi-colors-supported 256; then
   echo "WARNING: Your current terminal '$TERM' is reported to not support displaying 256 colors."
   echo
fi

# this function is inspired by https://github.com/Evanlec/config/blob/master/bin/256colors2.pl

local i green red blue spacer

printf "To set one of the following \033[1mforeground\033[0m colors use '\\\033[38;5;\033[1m<NUM>\033[0mm'\n"
echo
echo "System Colors:"
for (( i=0; i<16; i++));do
   if (( i == 0 )); then
      printf "\033[48;5;231m"
   else
      printf "\033[48;5;0m"
   fi
   printf "\033[38;5;${i}m%2d \033[0m" "$i"
done
echo
echo
echo "Color Cubes 6x6x6:"
for (( green=0; green<6; green++ )) {
   for (( red=0; red<6; red++ )) {
      for (( blue=0; blue<6; blue++ )) {
         i=$(( 16 + 36*red + 6*green + blue ))
         if (( (i - 16) % 6 == 0)); then
            spacer=""
         else
            spacer=" "
         fi
         if (( i > 87 )); then
            printf "\033[38;5;${i}m$spacer%3d\033[0m" "$i"
         else
            printf "\033[38;5;${i}m$spacer%2d\033[0m" "$i"
         fi
      }
      printf "\033[38;5;8m|\033[0m"
   }
   echo
}
echo
echo "Grayscale Ramp:"
for i in 16 {232..255} 231;do
   if (( i == 16 || i > 231 && i < 234 )); then
      printf "\033[48;5;236m"
   else
      printf "\033[48;5;0m"
   fi
   printf "\033[38;5;${i}m%3d \033[0m" "$i"
done
echo

echo
echo
printf "To set one of the following \033[1mbackground\033[0m colors use '\\\033[48;5;\033[1m<NUM>\033[0mm'\n"
echo
echo "System Colors:"
for (( i=0; i<16; i++));do
   if (( i == 0 )); then
      printf "\033[48;5;231m"
   else
      printf "\033[48;5;0m"
   fi
   printf "\033[48;5;${i}m%2d \033[0m" "$i"
done
echo
echo
echo "Color Cubes 6x6x6:"
for (( green=0; green<6; green++ )) {
   for (( red=0; red<6; red++ )) {
      for (( blue=0; blue<6; blue++ )) {
         i=$(( 16 + 36*red + 6*green + blue ))
         if (( (i - 16) % 6 == 0)); then
            spacer=""
         else
            spacer=" "
         fi
         if (( i > 87 )); then
            printf "\033[38;5;235;48;5;${i}m$spacer%3d\033[0m" "$i"
         else
            printf "\033[38;5;235;48;5;${i}m$spacer%2d\033[0m" "$i"
         fi
      }
      printf " "
   }
   echo
}
echo
echo "Grayscale Ramp:"
for i in 16 {232..255} 231;do
   if (( i == 231 )); then
      printf "\033[38;5;254m"
   else
      printf "\033[38;5;15m"
   fi
   printf "\033[48;5;${i}m%3d \033[0m" "$i"
done
echo

-ansi-reset

Usage: -ansi-reset [OPTION]...

Prints an ANSI escape sequence that reset all ANSI attributes.

Options:
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

echo -ne "\033[0m"

-ansi-ul

Usage: -ansi-ul [OPTION]... [TEXT]

Sets underlined mode or prints the given text underlined.

Parameters:
  TEXT
      The text to print underlined.

Options:
    --off
        Print the ANSI escape sequence that disables sets underlined attribute.
    --on
        Print the ANSI escape sequence that enables sets underlined attribute.
    -----------------------------
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

if [[ $_TEXT ]]; then
   echo -ne "\033[4m$_TEXT\033[24m"
fi

if [[ $_on ]]; then
   echo -ne "\033[4m"
elif [[ $_off ]]; then
   echo -ne "\033[24m"
fi

-cursor-pos

Usage: -cursor-pos [OPTION]...

Performs ANSI cursor operations.

Options:
    --assign VARNAME
        Assigns the current cursor position to the variable with the given name.
-d, --down [LINES] (default: '1', integer: ?-?)
        Moves the cursor n lines down.
    --fd [NUM] (default: '1', integer: ?-?)
        Send the ANSI sequences to the given file descriptor.
-l, --left [COLUMNS] (default: '1', integer: ?-?)
        Move the cursor n columns forward.
    --print
        Prints the current cursor position.
    --restore
        Restores the last saved cursor position.
-r, --right [COLUMNS] (default: '1', integer: ?-?)
        Move the cursor n columns backward.
    --save
        Saves the current cursor position.
    --set ROW_AND_COL
        Sets the cursor position (ROW:COL).
-u, --up [LINES] (default: '1', integer: ?-?)
        Moves the cursor n lines up.
    -----------------------------
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

if [[ $_save ]]; then
   echo -en "\033[s" >&$_fd
fi

if [[ $_restore ]]; then
   echo -en "\033[u" >&$_fd
fi

if [[ $_up ]]; then
   echo -en "\033[${_up}A" >&$_fd
fi

if [[ $_down ]]; then
   echo -en "\033[${_down}B" >&$_fd
fi

if [[ $_right ]]; then
   echo -en "\033[${_right}C" >&$_fd
fi

if [[ $_left ]]; then
   echo -en "\033[${_left}D" >&$_fd
fi

if [[ $_set ]]; then
   echo -en "\033[${_set//:/;}H" >&$_fd
fi

if [[ $_print || $_assign ]]; then
   local pos
   echo -en "\E[6n" && read -sdR pos >&$_fd
   pos=${pos#*[}
   pos=${pos//;/:}
   if [[ $_print ]]; then
      echo $pos >&$_fd
   fi
   if [[ $_assign ]]; then
      eval "$_assign=\"$pos\""
    fi
fi

-test-all-ansi

Usage: -test-all-ansi [OPTION]...

Performs a selftest of all functions of this module by executing each function with option '--selftest'.

Options:
    --help
        Prints this help.
    --tracecmd
        Enables bash debug mode (set -x).
    --selftest
        Performs a self-test.
    --
        Terminates the option list.

Implementation:

-ansi-alternate --selftest && echo || return 1
-ansi-bold --selftest && echo || return 1
-ansi-codes --selftest && echo || return 1
-ansi-colors-supported --selftest && echo || return 1
-ansi-colors16 --selftest && echo || return 1
-ansi-colors256 --selftest && echo || return 1
-ansi-reset --selftest && echo || return 1
-ansi-ul --selftest && echo || return 1
-cursor-pos --selftest && echo || return 1