【问题标题】:Implementing --color=auto in your own bash scripts在您自己的 bash 脚本中实现 --color=auto
【发布时间】:2021-05-22 03:37:00
【问题描述】:

我在网上寻找过这个问题的答案,但找不到任何答案(查找bash 和color 会得到很多其他与颜色相关的结果)。

我想做的是在我自己的 bash 脚本中实现一个--color=(never|always|auto) 参数,类似于ls、grep 或其他命令中的选项。我一直不明白 auto 选项是如何在幕后工作的,以判断命令的输出是通过管道传输还是重定向。

我在想一个这样的例子:

example.sh
#!/bin/bash

text="This is some text"

if [[ "$1" == "--color=always" ]]; then
  echo -e "\e[1;36m${text}\e[0m" # light blue
elif [[  "$1" == "--color=never" ]]; then
  echo "$text"
elif [[  "$1" == "--color=auto" ]]; then
  if [ Being Redirect or Piped ]; then
    echo "$text"
  else
    echo -e "\e[1;36m${text}\e[0m" # light blue
  fi
fi

我已经做了一些测试,如果我在回显的字符串中指定颜色代码,那么当它被管道/重定向时,颜色代码也将被管道/重定向(我们期望--color=always 的行为)。此外,如果我没有在我的回显文本中放置颜色代码,这就是我期望 --color=never 的行为(显然)。我想不通的是如何让--color=auto之类的东西工作,它知道管道和重定向;功能如下:

./example.sh --color=auto
=> This is some text # Entire string is colored light blue
./example.sh --color=auto | grep "text"
=> This is some text  # Piped text isn't colored so only "text" ends up colored  from the grep command (if grep is set to color it)

我不确定如何实现这一点(或者是否可能),到目前为止,谷歌搜索一直没有帮助。我不确定这是否有帮助或相关,但我是 linux 用户(Ubuntu)并使用带有xterm-256color 的终端,我现在不关心可移植性,但如果有限制,我会好奇任何解决方案它将工作的终端类型。对此的任何指导将不胜感激。

【问题讨论】:

    标签: bash terminal


    【解决方案1】:

    颜色只有在数据输出到终端时才有意义,所以像--color=auto 这样的选项只需要检查它是否打印到tty/pty。对于 Bash,你可以这样写:

    color=... # auto | always | never
    ...
    if [[ $color == auto ]]; then
      # 0 for stdin, 1 for stdout, 2 for stderr
      if [[ -t 1 ]]; then
        # we're writing to a tty so use colors
        ...
      else
        # not a tty, no colors
        ...
      fi
    fi
    

    其他语言通常会有类似 C 的isatty(3) 的函数来检查打开的文件是否为 tty。

    【讨论】:

      【解决方案2】:

      使用功能。使用变量。正确构造代码。您的代码可能如下所示:

      # parse arguments
      color=... # auto | always | never
      
      color_green() {
           if ((!use_color)); then return; fi
           echo "Output green color code"
      }
      color_reset() {
           if ((!use_color)); then return; fi
           echo "Output reset color code"
      }
      printf_green() {
          color_green
          printf "$@"
          color_reset
          printf "\n"
      }
      
      use_color=0
      # enable coloring when always, or when output is a tty and auto
      if [[ "$color" == always || ( "$color" == auto && -t 1 ) ]]; then
        use_color=1
      fi
      
      printf_green "Hello world"
      

      如果对可以使用的终端类型有限制。

      -t 开关是standard,应该在任何地方都可用。它在内部调用isatty()。测试是 fd 1 是一个终端,您基本上是在测试输出是否对用户可见,或者它是否转到另一个程序(即管道)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多