Colored shell script output library

2019-03-07 15:05发布

I am looking for a definitive way to build shell scripts that generates colored output.

Unfortunately I am having a hard time finding an appropriate lib or good technique for doing this. I found a lot of helpful but simple examples like this. Also the most comprehensive guide that I found until now is this one.

Before I start writing my own library, I want to check if anyone already wrote it

If your solution does not fit into the observations below thats not a problem. I would like also to read it so it can help me out if decide to write my own solution

My main concerns/observations:

  • Needs to be safe. Want to avoid garbage output as not all terminals or pagers/editors (like less, more, vim, and so on) support colored output or more styled output (bold, blinked, italic, etc)
  • Needs to be easy and readable. Using ANSI escape codes directly is horrible: echo -e '\033[32mthis is ugly and \033[1;32mvery green\033[0m'
  • Needs to give me access to the whole color palette and styles for foreground and background text. Most of the examples I found uses only the basic colors for foreground text only.
  • Its preferable to use only simple commands like bash or simpler shells built in commands and/or common commands that can be found on most operating systems. For instance I can use colorize but I would need ruby (that's somewhat ok) and the colorize gem installed (not ok)
  • Tput seems to be a good option as it can manipulate the shell cursor quite well, but it is somewhat simpler/less flexible

Edit

After some research on terminal control and output formatting, I am writing this gist that tries to accomplish this. So far it is doing quite well

6条回答
Deceive 欺骗
2楼-- · 2019-03-07 15:49

Shameless plug... check Rainbow.sh

Usage

Just import rainbow.sh and start using the available functions in your scripts.

source rainbow.sh 

vargreen=$(echogreen "Grass is green")
varred=$(echored "Roses are red")

echo "$vargreen ..Crickets are noisy.. $varred"

enter image description here

查看更多
爷的心禁止访问
3楼-- · 2019-03-07 15:52

echo -e "\033[33;31m Color Text" - red

echo -e "\033[33;32m Color Text" - green

echo -e "\033[33;33m Color Text" - yellow

echo -e "\033[33;34m Color Text" - blue

echo -e "\033[33;35m Color Text" - Magenta

echo -e "\033[33;30m Color Text" - Gray

echo -e "\033[33;36m Color Text" - Cyan

http://techietent.blogspot.in/2013/03/how-to-echo-colored-text-in-linux-shell.html

查看更多
Bombasti
4楼-- · 2019-03-07 15:55

Here is an modified snippet from my dotfiles that should do what you want

RCol='\e[0m'    # Text Reset

# Regular           Bold                Underline           High Intensity      BoldHigh Intens     Background          High Intensity Backgrounds
Bla='\e[0;30m';     BBla='\e[1;30m';    UBla='\e[4;30m';    IBla='\e[0;90m';    BIBla='\e[1;90m';   On_Bla='\e[40m';    On_IBla='\e[0;100m';
Red='\e[0;31m';     BRed='\e[1;31m';    URed='\e[4;31m';    IRed='\e[0;91m';    BIRed='\e[1;91m';   On_Red='\e[41m';    On_IRed='\e[0;101m';
Gre='\e[0;32m';     BGre='\e[1;32m';    UGre='\e[4;32m';    IGre='\e[0;92m';    BIGre='\e[1;92m';   On_Gre='\e[42m';    On_IGre='\e[0;102m';
Yel='\e[0;33m';     BYel='\e[1;33m';    UYel='\e[4;33m';    IYel='\e[0;93m';    BIYel='\e[1;93m';   On_Yel='\e[43m';    On_IYel='\e[0;103m';
Blu='\e[0;34m';     BBlu='\e[1;34m';    UBlu='\e[4;34m';    IBlu='\e[0;94m';    BIBlu='\e[1;94m';   On_Blu='\e[44m';    On_IBlu='\e[0;104m';
Pur='\e[0;35m';     BPur='\e[1;35m';    UPur='\e[4;35m';    IPur='\e[0;95m';    BIPur='\e[1;95m';   On_Pur='\e[45m';    On_IPur='\e[0;105m';
Cya='\e[0;36m';     BCya='\e[1;36m';    UCya='\e[4;36m';    ICya='\e[0;96m';    BICya='\e[1;96m';   On_Cya='\e[46m';    On_ICya='\e[0;106m';
Whi='\e[0;37m';     BWhi='\e[1;37m';    UWhi='\e[4;37m';    IWhi='\e[0;97m';    BIWhi='\e[1;97m';   On_Whi='\e[47m';    On_IWhi='\e[0;107m';

Then you can just echo -e "${Blu}blue ${Red}red ${RCol}etc...."

查看更多
Explosion°爆炸
5楼-- · 2019-03-07 16:00

I took demure's list as inspiration and did a little DRYing out of it. (And changed \e to the hexadecimal \x1B, since the former isn't supported in OS X's Terminal.app since Snow Leopard.) Here's what I came up with:

## Colours and font styles
## Syntax: echo -e "${FOREGROUND_COLOUR}${BACKGROUND_COLOUR}${STYLE}Hello world!${RESET_ALL}"

# Escape sequence and resets
ESC_SEQ="\x1b["
RESET_ALL="${ESC_SEQ}0m"
RESET_BOLD="${ESC_SEQ}21m"
RESET_UL="${ESC_SEQ}24m"

# Foreground colours
FG_BLACK="${ESC_SEQ}30;"
FG_RED="${ESC_SEQ}31;"
FG_GREEN="${ESC_SEQ}32;"
FG_YELLOW="${ESC_SEQ}33;"
FG_BLUE="${ESC_SEQ}34;"
FG_MAGENTA="${ESC_SEQ}35;"
FG_CYAN="${ESC_SEQ}36;"
FG_WHITE="${ESC_SEQ}37;"
FG_BR_BLACK="${ESC_SEQ}90;"
FG_BR_RED="${ESC_SEQ}91;"
FG_BR_GREEN="${ESC_SEQ}92;"
FG_BR_YELLOW="${ESC_SEQ}93;"
FG_BR_BLUE="${ESC_SEQ}94;"
FG_BR_MAGENTA="${ESC_SEQ}95;"
FG_BR_CYAN="${ESC_SEQ}96;"
FG_BR_WHITE="${ESC_SEQ}97;"

# Background colours (optional)
BG_BLACK="40;"
BG_RED="41;"
BG_GREEN="42;"
BG_YELLOW="43;"
BG_BLUE="44;"
BG_MAGENTA="45;"
BG_CYAN="46;"
BG_WHITE="47;"

# Font styles
FS_REG="0m"
FS_BOLD="1m"
FS_UL="4m"

The BR_ colours are the "bright" or "high-intensity" colours. Done this way, you can even mix them with other font styles. (e.g. underlined bright white)

If you want to bookmark this, I made a gist for it: https://gist.github.com/ian128K/39a490e5aa8d3bb77a8b

查看更多
甜甜的少女心
6楼-- · 2019-03-07 16:01

I personally use these in my xcol tool that I developed using Andreas Schamanek code as a reference.

#normal=$(tput sgr0)                      # normal text
normal=$'\e[0m'                           # (works better sometimes)
bold=$(tput bold)                         # make colors bold/bright
red="$bold$(tput setaf 1)"                # bright red text
green=$(tput setaf 2)                     # dim green text
fawn=$(tput setaf 3); beige="$fawn"       # dark yellow text
yellow="$bold$fawn"                       # bright yellow text
darkblue=$(tput setaf 4)                  # dim blue text
blue="$bold$darkblue"                     # bright blue text
purple=$(tput setaf 5); magenta="$purple" # magenta text
pink="$bold$purple"                       # bright magenta text
darkcyan=$(tput setaf 6)                  # dim cyan text
cyan="$bold$darkcyan"                     # bright cyan text
gray=$(tput setaf 7)                      # dim white text
darkgray="$bold"$(tput setaf 0)           # bold black = dark gray text
white="$bold$gray"                        # bright white text

I use these variables in my scripts like so

echo "${red}hello ${yellow}this is ${green}coloured${normal}"

Checkout my xcol tool for ideas and examples

https://ownyourbits.com/2017/01/23/colorize-your-stdout-with-xcol/

xcol example

查看更多
该账号已被封号
7楼-- · 2019-03-07 16:07

tput can handle more than is indicated on the page you link to. All tput does is output the characters you would include in your echo statement, based on what appears in the current terminal's termcap/terminfo database. Some examples:

$ tput setaf 5 | hexdump -C
00000000  1b 5b 33 35 6d                                    |.[35m|
$ tput setaf 17 | hexdump -C
00000000  1b 5b 33 38 3b 35 3b 31  37 6d                    |.[38;5;17m|
$ tput reset | hexdump -C
00000000  1b 63 1b 5b 3f 31 30 30  30 6c 1b 5b 3f 32 35 68  |.c.[?1000l.[?25h|

You would use it the same way you use the variable defined in your gist; in fact, you could use it to create your gist, in a portable fashion:

black=$(tput setaf 0)
查看更多
登录 后发表回答