ANSI Color Specific RGB Sequence Bash

前端 未结 5 1646
孤街浪徒
孤街浪徒 2020-12-04 08:56

I know that in bash terminals a reliable way to change color is using ANSI escape sequences. For example:

echo -e \"\\033[0;31mbrown text\\033[0;00m\"


        
相关标签:
5条回答
  • 2020-12-04 09:13

    No there's not.

    And to nitpick, those are technically not "ANSI escape sequences" but VT100 control codes (which were defined long before there were graphical terminals and terms like "RGB").

    0 讨论(0)
  • 2020-12-04 09:16

    Currently true color escape sequences (\e[38;2;R;G;Bm) are supported by certain terminal emulators including gnome-terminal (with vte >= 0.36), konsole, and st [suckless].

    The feature is not supported by certain others, e.g. pterm [putty], terminology [enlightenment], urxvt.

    xterm is halfway in between: it recognizes the escape sequences, but rounds every color to the nearest one in the 256-color palette.

    0 讨论(0)
  • 2020-12-04 09:21

    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; 30-37 are simply 16-color foreground codes (with a brightness controlled by escape code 1 on some systems and the arguably-supported 90-97 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.

    0 讨论(0)
  • 2020-12-04 09:27

    This does exist, but instead of the 16777216 (256^3) colors that the OP was looking for, there are 216 (6^3) equally distributed colors, in a larger set of 256 colors. Example:

    echo -e "\033[38;5;208mpeach\033[0;00m"
    

    This will output a pleasing sort of peach colored text.


    Taking apart this command: \033[38;5;208m

    The \033 is the escape code. The [38; directs command to the foreground. If you want to change the background color instead, use [48; instead. The 5; is just a piece of the sequence that changes color. And the most important part, 208m, selects the actual color.


    There are 3 sets of colors that can be found in the 256 color sequence for this escape. The first set is the basic "candy" color set, or values 0-15. Then there is a cube of distributed colors, from 16-231. Lastly there is a detailed grayscale set from 232-255.

    You can find a table with all of these values here: http://bitmote.com/index.php?post/2012/11/19/Using-ANSI-Color-Codes-to-Colorize-Your-Bash-Prompt-on-Linux#256%20(8-bit)%20Colors

    0 讨论(0)
  • 2020-12-04 09:28

    This will work

    echo -e "**\033[38;2;255;0;0m**red text\033[0;00m"
    

    format: "\033[38;2;R;G;Bm"

    • R is your RED component of your RGB
    • G is your GRREN component of your RGB
    • B is your BLUE component of your RGB
    0 讨论(0)
提交回复
热议问题