Skip to content

Instantly share code, notes, and snippets.

@lifepillar
Created November 20, 2017 11:48
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save lifepillar/09a44b8cf0f9397465614e622979107f to your computer and use it in GitHub Desktop.
Save lifepillar/09a44b8cf0f9397465614e622979107f to your computer and use it in GitHub Desktop.
Test 24 bit colors in terminals
#!/bin/bash
#
# This file echoes a bunch of 24-bit color codes
# to the terminal to demonstrate its functionality.
# The foreground escape sequence is ^[38;2;<r>;<g>;<b>m
# The background escape sequence is ^[48;2;<r>;<g>;<b>m
# <r> <g> <b> range from 0 to 255 inclusive.
# The escape sequence ^[0m returns output to default
setBackgroundColor()
{
echo -en "\x1b[48;2;$1;$2;$3""m"
}
resetOutput()
{
echo -en "\x1b[0m\n"
}
# Gives a color $1/255 % along HSV
# Who knows what happens when $1 is outside 0-255
# Echoes "$red $green $blue" where
# $red $green and $blue are integers
# ranging between 0 and 255 inclusive
rainbowColor()
{
let h=$1/43
let f=$1-43*$h
let t=$f*255/43
let q=255-t
if [ $h -eq 0 ]
then
echo "255 $t 0"
elif [ $h -eq 1 ]
then
echo "$q 255 0"
elif [ $h -eq 2 ]
then
echo "0 255 $t"
elif [ $h -eq 3 ]
then
echo "0 $q 255"
elif [ $h -eq 4 ]
then
echo "$t 0 255"
elif [ $h -eq 5 ]
then
echo "255 0 $q"
else
# execution should never reach here
echo "0 0 0"
fi
}
for i in `seq 0 127`; do
setBackgroundColor $i 0 0
echo -en " "
done
resetOutput
for i in `seq 255 128`; do
setBackgroundColor $i 0 0
echo -en " "
done
resetOutput
for i in `seq 0 127`; do
setBackgroundColor 0 $i 0
echo -n " "
done
resetOutput
for i in `seq 255 128`; do
setBackgroundColor 0 $i 0
echo -n " "
done
resetOutput
for i in `seq 0 127`; do
setBackgroundColor 0 0 $i
echo -n " "
done
resetOutput
for i in `seq 255 128`; do
setBackgroundColor 0 0 $i
echo -n " "
done
resetOutput
for i in `seq 0 127`; do
setBackgroundColor `rainbowColor $i`
echo -n " "
done
resetOutput
for i in `seq 255 128`; do
setBackgroundColor `rainbowColor $i`
echo -n " "
done
resetOutput
@Masterxilo
Copy link

Run with

curl -s https://gist.githubusercontent.com/lifepillar/09a44b8cf0f9397465614e622979107f/raw/24-bit-color.sh | bash

@ashrasmun
Copy link

What's the expected output?

@lifepillar
Copy link
Author

Terminal with millions of colors:

true-colors

Terminal not supporting true colors (screenshot from Apple Terminal.app):

not-true-colors

@ashrasmun
Copy link

Thanks for the example :)
The script outputs empty lines for me on Windows Terminal with WSL2 running Ubuntu-20.04. Do you have an idea why this can be a case?
image

@lifepillar
Copy link
Author

Sorry, no. It might be a bug with the terminal.

@adizero
Copy link

adizero commented Sep 20, 2021

It is because GNU seq (compared to BSD/MACOS seq) does not support first argument > last argument. You need to change seq 255 128 calls to seq 255 -1 128 everywhere in the script. Or just use this fork of the script: https://gist.github.com/grhbit/db6c5654fa976be33808b8b33a6eb861

@mirabilos
Copy link

Eh, if the terminal is narrower than 129 columns (e.g. xterm with 9x18 font on 1024x768 laptop) the output is… weird.

@knghtbrd
Copy link

I see the same output as Windows Terminal on libvte terminals on Debian sid:

ii  libvte-2.91-0:amd64 0.68.0-1+b1  amd64        Terminal emulator widget for GTK+ 3.0 - runtime files

Tested with mate-terminal and kmscon. I could try others but generally if you've seen one VTE, you've seen them all. No idea when the regression happened.

@Goorzhel
Copy link

This is written for Bash, so why bother with seq at all? Do this instead:

for i in {255..128}; do
    setBackgroundColor $i 0 0
    echo -en " "
done

With that correction, the script works correctly on bash 5.1.16, alacritty 0.11.0, and NixOS 22.11.

@mirabilos
Copy link

mirabilos commented Feb 16, 2023 via email

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