ANSI Color Specific RGB Sequence Bash

Both answers here fail to mention the Truecolor ANSI support for 8bpc color. This will get the RGB color the OP originally asked for.

Instead of ;5, use ;2, and specify the R, G, and B values (0-255) in the following three control segments.

\x1b[38;2;40;177;249m

To test if your terminal supports Truecolor:

printf "\x1b[38;2;40;177;249mTRUECOLOR\x1b[0m\n"

On my machine, XTerm happily outputted the correct color; although, terminals that are modeled after terminals that predate modern RGB color generally will not support truecolor – make sure you know your target before using this particular variant of the escape code.


I’d also like to point out the 38 and the ;5/;2 – Blue Ice mentioned that 38 routes and then 5 changes the color. That is slightly incorrect.

38 is the xterm-256 extended foreground color code; 3037 are simply 16-color foreground codes (with a brightness controlled by escape code 1 on some systems and the arguably-supported 9097 non-standard ‘bright’ codes) that are supported by all vt100/xterm-compliant colored terminals.

The ;2 and ;5 indicate the format of the color, ultimately telling the terminal how many more sequences to pull: ;5 specifying an 8-bit format (as Blue Ice mentioned) requiring only 1 more control segment, and ;2 specifying a full 24-bit RGB format requiring 3 control segments.

These extended modes are technically “undocumented” and are completely implementation defined. As far as I know and can research, they are not governed by the ANSI committee.


For the so inclined, the 5; (256 color) format starts with the 16 original colors (both dark/light, so 30-37 and 90-97) as colors 0-15.

The proceeding 216 colors (16-231) are formed by a 3bpc RGB value offset by 16, packed into a single value.

The final 24 colors (232-256) are greyscale starting from a shade slightly lighter than black ranging up to a shade slightly darker than white. Some emulators interpret these steps as linear increments from (256 / 24) on all three channels, though I’ve come across some emulators that seem to explicitly define these values.

Here is a Javascript function that performs such a conversion, taking into account all of the greys.

function rgbToAnsi256(r, g, b) {
    // we use the extended greyscale palette here, with the exception of
    // black and white. normal palette only has 4 greyscale shades.
    if (r === g && g === b) {
        if (r < 8) {
            return 16;
        }

        if (r > 248) {
            return 231;
        }

        return Math.round(((r - 8) / 247) * 24) + 232;
    }

    var ansi = 16
        + (36 * Math.round(r / 255 * 5))
        + (6 * Math.round(g / 255 * 5))
        + Math.round(b / 255 * 5);

    return ansi;
}

So in a way, you can calculate 256 ANSI colors from initial RGB values by reducing them from 8 to 3 bits in order to form a 256 encoded value in the event you want to programmatically do so on terminals that do not support Truecolor.

Leave a Comment