是否可以在 Bash 此处文档中使用 ANSI 颜色转义码?

是否可以在 Bash 此处文档中使用 ANSI 颜色转义码?

我正在 Bash 脚本中打印一条消息,并且我想对其中的一部分进行着色;例如,

#!/bin/bash

normal='\e[0m'
yellow='\e[33m'
cat <<- EOF
    ${yellow}Warning:${normal} This script repo is currently located in:
    [ more messages... ]
EOF

但是当我在终端(tmux内部gnome-terminal)运行时ANSI 转义字符只是以表格\形式打印出来的;例如,

\e[33mWarning\e[0m This scr....

如果我将想要着色的部分移动到printf此处文档之外的命令中,它就会起作用。例如,这有效:

printf "${yellow}Warning:${normal}"
cat <<- EOF
    This script repo is currently located in:
    [ more messages... ]
EOF

来自man bash– 这里文档:

不执行参数和变量扩展、命令替换、算术扩展或路径名扩展单词。如果其中有任何字符单词被引用,则分隔符是删除引号的结果单词,并且此处文档中的行未展开。如果单词如果不加引号,则此处文档的所有行都会进行参数扩展、命令替换和算术扩展。在后一种情况下,字符序列\<换行符>被忽略,并且\必须用于引用字符\$`

我不知道这会如何影响 ANSI 转义码。是否可以在catted out 的 Bash here 文档中使用 ANSI 转义码?

答案1

在您的脚本中,这些作业

normal='\e[0m'
yellow='\e[33m'

把那些字符字面上地进入变量,即\e[0m,而不是转义序列。您可以使用printf(或某些版本的)构造转义字符echo,例如,

normal=$(printf '\033[0m')
yellow=$(printf '\033[33m')

但你会更好地使用tput,因为这适用于任何正确设置的终端:

normal=$(tput sgr0)
yellow=$(tput setaf 3)

查看您的示例,似乎printf您正在使用 treats\e作为转义字符的版本(这可能适用于您的系统,但通常不能移植到其他系统)。要看到这个,请尝试

yellow='\e[33m'
printf 'Yellow:%s\n' $yellow

你会看到文字人物:

Yellow:\e[33m

而不是转义序列。将它们放入printf格式中告诉printf我们解释它们(如果可以的话)。

进一步阅读:

答案2

此赋值不会在变量中放置转义字符:

normal='\e[0m'                  yellow='\e[33m'

为此,您需要echo -e printfor $'...'(在 bash 中)。

既然你使用的是 bash,你不妨使用这个:

normal=$'\e[0m'                 yellow=$'\e[33m'

请注意$字符串之前的'\e[0m'

然而,获取转义字符的可移植方法是 printf,如下所示:

normal="$(printf '\033[0m')"    yellow="$(printf '\033[33m')"

转义字符的八进制值 (033) 在所有 POSIX shell 中都有效。

相关内容