【问题标题】:Colored shell script output library彩色 shell 脚本输出库
【发布时间】:2013-05-26 10:54:16
【问题描述】:

我正在寻找一种确定的方法来构建生成彩色输出的 shell 脚本。

不幸的是,我很难找到合适的库或很好的技术来做到这一点。我发现了很多有用但简单的例子,比如this。到目前为止,我发现的最全面的指南也是this one

在我开始编写自己的库之前,我想检查一下是否有人已经编写了它

如果您的解决方案不符合以下观察结果,那不是问题。我也想阅读它,以便在决定编写自己的解决方案时帮助我

我的主要担忧/观察:

  • 需要安全。想要避免垃圾输出,因为并非所有终端或寻呼机/编辑器(如 less、more、vim 等)都支持彩色输出或更多样式输出(粗体、闪烁、斜体等)
  • 需要简单易读。直接使用ANSI escape codes 太可怕了:echo -e '\033[32mthis is ugly and \033[1;32mvery green\033[0m'
  • 需要让我访问前景和背景文本的整个调色板和样式。我发现的大多数示例仅使用前景文本的基本颜色。
  • 最好只使用简单的命令,例如 bash 或更简单的内置命令和/或可以在大多数操作系统上找到的常用命令的 shell。例如,我可以使用colorize,但我需要 ruby​​(这还可以)并安装 colorize gem(不行)
  • Tput 似乎是一个不错的选择,因为它可以很好地操纵 shell 光标,但它有点简单/不太灵活

编辑

在对终端控制和输出格式进行了一些研究之后,我正在写 this gist 来尝试实现这一点。到目前为止,它做得很好

【问题讨论】:

  • echo -e '\033[32mthis is ugly and \033[1;32mvery green\033[0m' 并没有那么可怕,当您使用 RED=\033[32m 之类的变量甚至是颜色数组时。
  • 确实如此。我想写一个更高级的库,但可能会坚持格式化字符串中的变量

标签: linux macos shell colors


【解决方案1】:

这是来自我的dotfiles 的修改后的 sn-p,它应该可以满足您的需求

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';

那你可以echo -e "${Blu}blue ${Red}red ${RCol}etc...."

【讨论】:

  • 谢谢端庄。我正在根据您的回答写一个要点(将链接添加到我的帖子)
  • 我可能最终会借用你的 style vars 和 $TC sub var
  • 在 Mac 上,使用 \x1B 而不是 \e
  • @MaRco85 echoing '\e[0m' 将重置颜色。你也可以启动一个新的终端。
  • 如果您使用\033 而不是\e,您不必担心系统支持问题。
【解决方案2】:

echo -e "\033[33;31m 颜色文本" - 红色

echo -e "\033[33;32m 彩色文本" - 绿色

echo -e "\033[33;33m 彩色文本" - 黄色

echo -e "\033[33;34m 彩色文字" - 蓝色

echo -e "\033[33;35m 彩色文本" - 洋红色

echo -e "\033[33;30m 彩色文本" - 灰色

echo -e "\033[33;36m 彩色文本" - 青色

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

【讨论】:

    【解决方案3】:

    无耻插件...检查Rainbow.sh

    用法

    只需导入 rainbow.sh 并开始使用脚本中的可用函数。

    source rainbow.sh 
    
    vargreen=$(echogreen "Grass is green")
    varred=$(echored "Roses are red")
    
    echo "$vargreen ..Crickets are noisy.. $varred"
    

    【讨论】:

    • @Hugh Perkins 许可证将是 MIT,我将在今天晚些时候更新 repo。
    【解决方案4】:

    tput 可以处理的超出您链接到的页面上的指示。所有tput 所做的只是根据当前终端的termcap/terminfo 数据库中显示的内容输出您将包含在echo 语句中的字符。一些例子:

    $ 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|
    

    您可以像使用 gist 中定义的变量一样使用它;事实上,你可以用它来创建你的要点,以一种便携的方式:

    black=$(tput setaf 0)
    

    【讨论】:

      【解决方案5】:

      我以端庄的清单为灵感,并对其进行了一些干燥处理。 (并将 \e 更改为十六进制的 \x1B,因为自 Snow Leopard 以来 OS X 的 Terminal.app 不支持前者。)这是我想出的:

      ## 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"
      

      BR_ 颜色是“明亮”或“高强度”颜色。通过这种方式,您甚至可以将它们与其他字体样式混合使用。 (例如带下划线的亮白色)

      如果你想收藏这个,我为它做了一个要点:https://gist.github.com/ian128K/39a490e5aa8d3bb77a8b

      【讨论】:

        【解决方案6】:

        我个人在我使用 Andreas Schamanek 代码开发的 xcol 工具中使用这些作为参考。

        #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
        

        我在我的脚本中像这样使用这些变量

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

        查看我的 xcol 工具以获取想法和示例

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

        【讨论】:

          【解决方案7】:

          以防万一有人来这里寻找着色输出的 shell 过滤器,Alexey Gladkov 有一个 POSIX shell 实现,在libshell 中潜伏为utils/cgrep(它的设计非常具有防御性)以及他更多的参与cfilter 用 golang 写的。

          【讨论】:

            【解决方案8】:

            使用此线程上所有很棒的答案快速添加此内容,同时添加对--no-color 标志和NO_COLOR 环境变量的支持。

            ## Enable our easy to read Colour Flags as long as --no-colors hasn't been passed or the NO_COLOR Env Variable is set. 
            ## NOTE: the NO_COLOR env variable is from: https://no-color.org/
            if [[ ! $* == *--no-color* && -z "${NO_COLOR}" ]]
            then 
            
                ESeq="\x1b["
            
                # Set up our Colour Holders. 
                ResetColor="$ESeq"'0m'    # Text Reset
            
                Bold="$ESeq"'1m';    Underline="$ESeq"'4m'
            
                # Regular              Bold                        Underline                       High Intensity           
                Black="$ESeq"'0;30m';  BoldBlack="$ESeq"'1;30m';   UnderlineBlack="$ESeq"'4;30m';  IntenseBlack="$ESeq"'0;90m'; 
                Red="$ESeq"'0;31m';    BoldRed="$ESeq"'1;31m';     UnderlineRed="$ESeq"'4;31m';    IntenseRed="$ESeq"'0;91m';   
                Green="$ESeq"'0;32m';  BoldGreen="$ESeq"'1;32m';   UnderlineGreen="$ESeq"'4;32m';  IntenseGreen="$ESeq"'0;92m'; 
                Yellow="$ESeq"'0;33m'; BoldYelllow="$ESeq"'1;33m'; UnderlineYellow="$ESeq"'4;33m'; IntenseYellow="$ESeq"'0;93m';
                Blue="$ESeq"'0;34m';   BoldBlue="$ESeq"'1;34m';    UnderlineBlue="$ESeq"'4;34m';   IntenseBlue="$ESeq"'0;94m';  
                Purple="$ESeq"'0;35m'; BoldPurple="$ESeq"'1;35m';  UnderlinePurple="$ESeq"'4;35m'; IntensePurple="$ESeq"'0;95m';
                Cyan="$ESeq"'0;36m';   BoldCyan="$ESeq"'1;36m';    UnderlineCyan="$ESeq"'4;36m';   IntenseCyan="$ESeq"'0;96m';  
                White="$ESeq"'0;37m';  BoldWhite="$ESeq"'1;37m';   UnderlineWhite="$ESeq"'4;37m';  IntenseWhite="$ESeq"'0;97m'; 
            
                #Bold High Intensity                Background              High Intensity Backgrounds
                BoldIntenseBlack="$ESeq"'1;90m';    OnBlack="$ESeq"'40m';   OnIntenseBlack="$ESeq"'0;100m';
                BoldIntenseRed="$ESeq"'1;91m';      OnRed="$ESeq"'41m';     OnIntenseRed="$ESeq"'0;101m';
                BoldIntenseGreen="$ESeq"'1;92m';    OnGreen="$ESeq"'42m';  OnIntenseGreen="$ESeq"'0;102m';
                BoldIntenseYellow="$ESeq"'1;93m';   OnYellow="$ESeq"'43m';  OnIntenseYellow="$ESeq"'0;103m';
                BoldIntenseBlue="$ESeq"'1;94m';     OnBlue="$ESeq"'44m';    OnIntenseBlue="$ESeq"'0;104m';
                BoldIntensePurple="$ESeq"'1;95m';   OnPurple="$ESeq"'45m';  OnIntensePurple="$ESeq"'0;105m';
                BoldIntenseCyan="$ESeq"'1;96m';     OnCyan="$ESeq"'46m';    OnIntenseCyan="$ESeq"'0;106m';
                BoldIntenseWhite="$ESeq"'1;97m';    OnWhite="$ESeq"'47m';   OnIntenseWhite="$ESeq"'0;107m';
            fi
            

            然后您可以在如下回显中使用这些:

            echo -e "${BoldGreen}Grabbing our variables${ResetColor}"
            echo -e "${BoldGreen}Done${ResetColor} ${Red}Moving on ...${ResetColor}"
            

            要禁用输出,您可以export NO_COLOR=true 禁用整个会话的颜色或将标志添加到单个脚本调用./myscript.sh --no-color

            此添加是由https://no-color.org/ 提示的,并且看到颜色代码出现在日志和文件输出等内容中的一些经验使它们难以阅读。当您预计将涉及非控制台媒体时,通过将这些标志包裹在颜色定义中,您可以轻松关闭脚本的颜色输出。

            为了便于阅读,我还扩展了颜色名称,希望您在编写脚本时有bit of an IDE 提供帮助;所以长度不如可读性重要。我什至保留了美国人color的?

            我不是 Bash/shell 专家,所以请告诉我您发现的任何问题;但我希望这对某些人有所帮助!

            【讨论】:

              猜你喜欢
              • 2014-12-07
              • 1970-01-01
              • 1970-01-01
              • 2019-05-06
              • 2020-08-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多