我正在 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 转义码。是否可以在cat
ted 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
printf
or $'...'
(在 bash 中)。
既然你使用的是 bash,你不妨使用这个:
normal=$'\e[0m' yellow=$'\e[33m'
请注意$
字符串之前的'\e[0m'
。
然而,获取转义字符的可移植方法是 printf,如下所示:
normal="$(printf '\033[0m')" yellow="$(printf '\033[33m')"
转义字符的八进制值 (033) 在所有 POSIX shell 中都有效。