Skip to main content
added 890 characters in body
Source Link

From 8-bit color chapter of Wikipedia's ANSI escape code, and to be quicker, without any loop:

#!/bin/bash shape='XXXXXXXX' arry=(0for 0((i=0; 2{,,}{,,}{,,,}i<256; 0{,,}i++)) ;do eval arry= fg=$(${arry[@]/?/\${shape:&\}}(((i>231&&i<244)||((i<17)&&(i%8<2))||(i>16&&i<232)&&((i-16)%6*11+ printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" declare -ai arry= ({0..255}i-16)/6%6*14+(i-16)/36*10)<58)?7:16)) printf -v shape "$shape" ${arry[@]} printf -v' shape "$shape"\e[48;5;%d;38;5;%dm ${arry[@]}C %3d \e[49;39m' $i $fg $i eval "arry= (${arry[@]/*/\"(&>231\&\&&<244)|| ((&<17i<16||i>231)\&\& && (&%8<2(i+1)%8==0)||(&>16\&\& ) || &<232)\&\&((&-16i>16&&i<232)%6*11+&& (&-16)/6%6*14+(&i-1615)/36*10%6==0)<58?7:16\"})" )) && printf "$shape" ${arry[@]} printf "\n" done 

Note: On my raspberry, this could by cut'n pasted into a fresh terminal windowscript take approx 1.5 seconds to complete.

Same but without loop:

Same script with some commentsCould be quicker again:

#!/bin/bash # Building a shape of 41 lines with two first lines of 8 fields, followed # by 36 lines of 6 fields, then 3 lines of 8 fields. shape='XXXXXXXX' # an 8 X string arry=(0 0 2{,,}{,,}{,,,} 0{,,}) # 2(x8) + 36(x6) + 3(x8): 41 lines eval arry=(${arry[@]/?/\${shape:&\}}) # 'arry=(XXXXXXXX XXXXXXXX XXXXXX ...' printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" # %d will be ANSI color, then %%3d right aligned label, and %%%%d foreground declare -ai arry=({0..255}) # arry is now an array of 256 integers printf -v shape "$shape" ${arry[@]} # populate colors printf -v shape "$shape" ${arry[@]} # populate labels # Building array of 256 foreground colors eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} # print out finalised shape with foregrounds 

Note: this could by cut'n pasted into a fresh terminal window.

Then this version will print same output, but in ~0.6 second on my raspberry pi.

Explained:

  • Building a shape of 41 lines with two first lines of 8 fields, followed by 36 lines of 6 fields, then 3 lines of 8 fields.
     shape='XXXXXXXX' # some 8 X string arry=(0 0 2{,,}{,,}{,,,} 0{,,}) # 2(x8) + 36(x6) + 3(x8): 41 lines eval arry=(${arry[@]/?/\${shape:&\}}) # 'arry=(XXXXXXXX XXXXXXXX XXXXXX ..' printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" 
    • replace each X by a format string for 3 values:
    • add a newline \n after each group of transformed X
    • %d will be ANSI color resolved first, then
    • %%3d for right aligned label, and
    • %%%%d for the foreground color.
  • Converting $arry into an integer array containing values from 0 to 255
    declare -ai arry=({0..255}) 
  • Populate background colors (%d)
     printf -v shape "$shape" ${arry[@]} 
  • Populate labels (%%d)
     printf -v shape "$shape" ${arry[@]} 
  • Compute 256 foreground colors into (integer) array $arry
     eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" 
  • Populate finalised shape with foregrounds and print out.
     printf "$shape" ${arry[@]} 

From 8-bit color chapter of Wikipedia's ANSI escape code, and to be quicker, without any loop:

#!/bin/bash shape='XXXXXXXX' arry=(0 0 2{,,}{,,}{,,,} 0{,,}) eval arry=(${arry[@]/?/\${shape:&\}}) printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" declare -ai arry=({0..255}) printf -v shape "$shape" ${arry[@]} printf -v shape "$shape" ${arry[@]} eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\&  &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} 

Note: this could by cut'n pasted into a fresh terminal window.

Same script with some comments:

#!/bin/bash # Building a shape of 41 lines with two first lines of 8 fields, followed # by 36 lines of 6 fields, then 3 lines of 8 fields. shape='XXXXXXXX' # an 8 X string arry=(0 0 2{,,}{,,}{,,,} 0{,,}) # 2(x8) + 36(x6) + 3(x8): 41 lines eval arry=(${arry[@]/?/\${shape:&\}}) # 'arry=(XXXXXXXX XXXXXXXX XXXXXX ...' printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" # %d will be ANSI color, then %%3d right aligned label, and %%%%d foreground declare -ai arry=({0..255}) # arry is now an array of 256 integers printf -v shape "$shape" ${arry[@]} # populate colors printf -v shape "$shape" ${arry[@]} # populate labels # Building array of 256 foreground colors eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} # print out finalised shape with foregrounds 

From 8-bit color chapter of Wikipedia's ANSI escape code:

#!/bin/bash for ((i=0; i<256; i++)) ;do  fg=$((((i>231&&i<244)||((i<17)&&(i%8<2))||(i>16&&i<232)&&((i-16)%6*11+  (i-16)/6%6*14+(i-16)/36*10)<58)?7:16)) printf ' \e[48;5;%d;38;5;%dm C %3d \e[49;39m' $i $fg $i  (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&  printf "\n" done 

Note: On my raspberry, this script take approx 1.5 seconds to complete.

Same but without loop:

Could be quicker again:

#!/bin/bash shape='XXXXXXXX' arry=(0 0 2{,,}{,,}{,,,} 0{,,}) eval arry=(${arry[@]/?/\${shape:&\}}) printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" declare -ai arry=({0..255}) printf -v shape "$shape" ${arry[@]} printf -v shape "$shape" ${arry[@]} eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} 

Note: this could by cut'n pasted into a fresh terminal window.

Then this version will print same output, but in ~0.6 second on my raspberry pi.

Explained:

  • Building a shape of 41 lines with two first lines of 8 fields, followed by 36 lines of 6 fields, then 3 lines of 8 fields.
     shape='XXXXXXXX' # some 8 X string arry=(0 0 2{,,}{,,}{,,,} 0{,,}) # 2(x8) + 36(x6) + 3(x8): 41 lines eval arry=(${arry[@]/?/\${shape:&\}}) # 'arry=(XXXXXXXX XXXXXXXX XXXXXX ..' printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" 
    • replace each X by a format string for 3 values:
    • add a newline \n after each group of transformed X
    • %d will be ANSI color resolved first, then
    • %%3d for right aligned label, and
    • %%%%d for the foreground color.
  • Converting $arry into an integer array containing values from 0 to 255
    declare -ai arry=({0..255}) 
  • Populate background colors (%d)
     printf -v shape "$shape" ${arry[@]} 
  • Populate labels (%%d)
     printf -v shape "$shape" ${arry[@]} 
  • Compute 256 foreground colors into (integer) array $arry
     eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" 
  • Populate finalised shape with foregrounds and print out.
     printf "$shape" ${arry[@]} 
added 2327 characters in body
Source Link

Preamble: about $TERM variable

Preamble: about $TERM variable

echo $TERM xterm tput colors 8 
echo $TERM xterm tput colors 8 

enter image description herebad no colored output

export TERM=xterm-256color ; reset tput colors 256 
export TERM=xterm-256color ; reset tput colors 256 

Doing simply the job by using tput

Doing simply the job by using tput

#!/bin/bash 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 
#!/bin/bash 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 * 11 + ( i - 16 ) / 6 % 6 * 14 + ( i - 16 ) / 36 * 10 ) < 58 ) ? 7 : 16 )) printf " C %3d " $i tput op (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) && printf "\n" done 

CouldShould render something like:

enter image description here256 colors ansi term

Optimizing : reducing forks by running tput as background process

Optimizing : reducing forks by running tput as background process

#!/bin/bash # Connector fifos directory read TMPDIR < <(mktemp -d /dev/shm/conn_shell_XXXXXXX) fd=3 # find next free fd nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;} tputConnector() { mkfifo $TMPDIR/tput nextFd TPUTIN eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)" nextFd TPUTOUT eval "exec $TPUTOUT<$TMPDIR/tput" rm $TMPDIR/tput rmdir $TMPDIR } myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2 } tputConnector myTput op op myTput "setaf 7" grey myTput "setaf 16" black fore=("$black" "$grey") for ((i=0; i<256; i++)) ;do myTput "setab $i" bgr printf " %s%s %3d %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)|| (i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58 ? 1 : 0 ]}" $i "$op" (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) && printf "\n" '' done 
#!/bin/bash # Connector fifos directory read TMPDIR < <(mktemp -d /dev/shm/conn_shell_XXXXXXX) fd=3 # find next free fd nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;} tputConnector() { mkfifo $TMPDIR/tput nextFd TPUTIN eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)" nextFd TPUTOUT eval "exec $TPUTOUT<$TMPDIR/tput" rm $TMPDIR/tput rmdir $TMPDIR } myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2 } tputConnector myTput op op myTput "setaf 7" grey myTput "setaf 16" black fore=("$black" "$grey") for ((i=0; i<256; i++)) ;do myTput "setab $i" bgr printf " %s%s %3d %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)|| (i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58 ? 1 : 0 ]}" $i "$op" (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) && printf "\n" '' done 

While second script run in ~0.11 second on my desk and ~4.97 seconds on my raspberry.

Without forks, using ansi sequences

From 8-bit color chapter of Wikipedia's ANSI escape code, and to be quicker, without any loop:

#!/bin/bash shape='XXXXXXXX' arry=(0 0 2{,,}{,,}{,,,} 0{,,}) eval arry=(${arry[@]/?/\${shape:&\}}) printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" declare -ai arry=({0..255}) printf -v shape "$shape" ${arry[@]} printf -v shape "$shape" ${arry[@]} eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} 

Note: this could by cut'n pasted into a fresh terminal window.

Same script with some comments:

#!/bin/bash # Building a shape of 41 lines with two first lines of 8 fields, followed # by 36 lines of 6 fields, then 3 lines of 8 fields. shape='XXXXXXXX' # an 8 X string arry=(0 0 2{,,}{,,}{,,,} 0{,,}) # 2(x8) + 36(x6) + 3(x8): 41 lines eval arry=(${arry[@]/?/\${shape:&\}}) # 'arry=(XXXXXXXX XXXXXXXX XXXXXX ...' printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" # %d will be ANSI color, then %%3d right aligned label, and %%%%d foreground declare -ai arry=({0..255}) # arry is now an array of 256 integers printf -v shape "$shape" ${arry[@]} # populate colors printf -v shape "$shape" ${arry[@]} # populate labels # Building array of 256 foreground colors eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} # print out finalised shape with foregrounds 

Note: as this don't refer to tput, environment variable TERM doesn't matter.

Preamble: about $TERM variable

echo $TERM xterm tput colors 8 

enter image description here

export TERM=xterm-256color ; reset tput colors 256 

Doing simply the job by using tput

#!/bin/bash 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 

Could render something like:

enter image description here

Optimizing : reducing forks by running tput as background process

#!/bin/bash # Connector fifos directory read TMPDIR < <(mktemp -d /dev/shm/conn_shell_XXXXXXX) fd=3 # find next free fd nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;} tputConnector() { mkfifo $TMPDIR/tput nextFd TPUTIN eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)" nextFd TPUTOUT eval "exec $TPUTOUT<$TMPDIR/tput" rm $TMPDIR/tput rmdir $TMPDIR } myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2 } tputConnector myTput op op myTput "setaf 7" grey myTput "setaf 16" black fore=("$black" "$grey") for ((i=0; i<256; i++)) ;do myTput "setab $i" bgr printf " %s%s %3d %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)|| (i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58 ? 1 : 0 ]}" $i "$op" (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) && printf "\n" '' done 

While second script run in ~0.11 second on my desk and ~4.97 seconds on my raspberry.

Preamble: about $TERM variable

echo $TERM xterm tput colors 8 

bad no colored output

export TERM=xterm-256color ; reset tput colors 256 

Doing simply the job by using tput

#!/bin/bash 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 * 11 + ( i - 16 ) / 6 % 6 * 14 + ( i - 16 ) / 36 * 10 ) < 58 ) ? 7 : 16 )) printf " C %3d " $i tput op (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) && printf "\n" done 

Should render something like:

256 colors ansi term

Optimizing : reducing forks by running tput as background process

#!/bin/bash # Connector fifos directory read TMPDIR < <(mktemp -d /dev/shm/conn_shell_XXXXXXX) fd=3 # find next free fd nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;} tputConnector() { mkfifo $TMPDIR/tput nextFd TPUTIN eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)" nextFd TPUTOUT eval "exec $TPUTOUT<$TMPDIR/tput" rm $TMPDIR/tput rmdir $TMPDIR } myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2 } tputConnector myTput op op myTput "setaf 7" grey myTput "setaf 16" black fore=("$black" "$grey") for ((i=0; i<256; i++)) ;do myTput "setab $i" bgr printf " %s%s %3d %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)|| (i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58 ? 1 : 0 ]}" $i "$op" (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) && printf "\n" '' done 

While second script run in ~0.11 second on my desk and ~4.97 seconds on my raspberry.

Without forks, using ansi sequences

From 8-bit color chapter of Wikipedia's ANSI escape code, and to be quicker, without any loop:

#!/bin/bash shape='XXXXXXXX' arry=(0 0 2{,,}{,,}{,,,} 0{,,}) eval arry=(${arry[@]/?/\${shape:&\}}) printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" declare -ai arry=({0..255}) printf -v shape "$shape" ${arry[@]} printf -v shape "$shape" ${arry[@]} eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} 

Note: this could by cut'n pasted into a fresh terminal window.

Same script with some comments:

#!/bin/bash # Building a shape of 41 lines with two first lines of 8 fields, followed # by 36 lines of 6 fields, then 3 lines of 8 fields. shape='XXXXXXXX' # an 8 X string arry=(0 0 2{,,}{,,}{,,,} 0{,,}) # 2(x8) + 36(x6) + 3(x8): 41 lines eval arry=(${arry[@]/?/\${shape:&\}}) # 'arry=(XXXXXXXX XXXXXXXX XXXXXX ...' printf -v shape '%s\n' "${arry[@]//X/ \\e[48;5;%d;38;5;%%%%dm C %%3d \\e[0m}" # %d will be ANSI color, then %%3d right aligned label, and %%%%d foreground declare -ai arry=({0..255}) # arry is now an array of 256 integers printf -v shape "$shape" ${arry[@]} # populate colors printf -v shape "$shape" ${arry[@]} # populate labels # Building array of 256 foreground colors eval "arry=(${arry[@]/*/\"(&>231\&\&&<244)||((&<17)\&\&(&%8<2))||(&>16\&\& &<232)\&\&((&-16)%6*11+(&-16)/6%6*14+(&-16)/36*10)<58?7:16\"})" printf "$shape" ${arry[@]} # print out finalised shape with foregrounds 

Note: as this don't refer to tput, environment variable TERM doesn't matter.

added 13 characters in body
Source Link

Optimizing : reducing forks by running backgroung tasktput as background process

Optimizing : reducing forks by running backgroung task

Optimizing : reducing forks by running tput as background process

added 50 characters in body
Source Link
Loading
added 890 characters in body
Source Link
Loading
deleted 66 characters in body
Source Link
Loading
Source Link
Loading