使用 $'...'、$"..."、'...' 和 "..." 的文本颜色

Str*_*ger 2 linux shell colors bash macos

从我记事起,我个人在使用 bash 时使用以下方法来更改输出文本的颜色:

red=$'\033[1;31m'                                                                        
nc=$'\033[0m'

echo "${red}This is red text$nc"
Run Code Online (Sandbox Code Playgroud)

无论是在 macOS 还是 Linux 上使用,它总是对我有用。出于好奇,为了更好地理解它为什么起作用,我做了一些研究并发现了一些不包括$red='\033[1;31m')的答案/示例。经过一些测试,如果我不使用$,输出颜色不会更改为红色,而只是打印字符串。但是,当使用sh而不是执行它时bash,文本确实会改变颜色。有人可以帮助我理解这是为什么吗?

我还用双引号而不是单引号对其进行了测试,并且它似乎仅在使用sh. 我将在下面发布示例。

这是我使用的脚本和代码:

#!/bin/bash                                                                              
                                                                                         
red=$'\033[1;31m'                                                                        
nc=$'\033[0m'                                                                            
                                                                                         
echo "${red}Test 1$nc"                                                                   
echo ""                                                                                  
                                                                                         
##########################                                                               
                                                                                         
red=$"\033[1;31m"                                                                        
nc=$"\033[0m"                                                                            
                                                                                         
echo "${red}Test 2$nc"                                                                   
echo ""                                                                                  
                                                                                         
##########################                                                               
                                                                                         
red='\033[1;31m'                                                                         
nc='\033[0m'                                                                             
                                                                                         
echo "${red}Test 3$nc"                                                                   
echo ""                                                                                  
                                                                                         
##########################                                                               
                                                                                         
red="\033[1;31m"                                                                         
nc="\033[0m"                                                                             
                                                                                         
echo "${red}Test 4$nc"                                                                   
echo ""  
Run Code Online (Sandbox Code Playgroud)

使用 bash 和 sh 在 macOS 上输出:

在此输入图像描述

Linux 上同时使用 bash 和 sh 的输出:

在此输入图像描述

ilk*_*chu 10

这里最主要的是,为了让终端识别控制序列,发送给终端的输出必须包含 ESC 字符,然后[1;31m. ESC 是一个控制字符,我们通常不会在 shell 脚本中按原样显示它,而是使用反斜杠转义符\033来使用其八进制字符代码(十进制 27、八进制 033 或十六进制 0x1b)来表示该字符。 )。其余的只是普通角色。

现在,反斜杠转义符需要在某个时候更改为原始 ESC 字符。有两个地方可能会发生这种情况:对变量的赋值和打印它的命令。


在支持它的 shell 中,$'...'引号的类型已经解释了转义,因此在 后red=$'\033[...',变量本身包含原始 ESC 字符。这不是标准的 POSIX 功能,在不支持它的 shell 中,它会分配原始美元符号,然后是反斜杠,033[等等。另一方面, red='\033[...'只会分配反斜杠033[等,从不解释转义。看

$"...",并且"..."永远不要解释转义,并且带有美元的转义符也是非标准的,因此可能会将文字美元符号留在不支持它的 shell 中。)


然后,第二步是印刷。在某些 shell 中echo会展开反斜杠转义。在其他情况下则不然。其中一些也有echo -e同样的情况。Bashecho默认情况下不会这样做,但是通过xpg_echo设置...它会这样做。Zshecho确实解释了它们。看


因此,在常用的 Linux 桌面发行版上的常用 Bash 中,如果xpg_echo未设置 where ,red=$'\033[1;31m'; echo "${red}text"则会在作业上生成 ESC 并打印红色文本,但red='\033[1;31m'; echo "${red}text"不会在作业或 中生成它,echo而只是\033[1;31mtext以正常颜色打印。

在 Debian/Ubuntu 上,sh是 Dash,其中$'...'不支持引号,但echo会解释反斜杠,因此 red=$'\033[1;31m'; echo "${red}text"打印正常颜色的$,然后打印红色文本。这就是您运行的shLinux 的样子。在其他一些 Linux 系统中您可能会得到不同的结果。

在 Mac 上,安装的 shellsh实际上是带xpg_echoset 的 Bash(安装时bash已禁用的 shell),或者在较新的 macOS 版本中安装的 zsh。尽管以 as 开始sh尝试使它们更加兼容 POSIX,但它们仍然支持引号$'...',因此red=$'\033[1;31m'; echo "${red}text"和都red='\033[1;31m'; echo "${red}text"打印红色文本。


还困惑吗?red='\033[1;31m'; printf "%b\n" "${red}text";应该可以在所有类似 POSIX 的 shell 中工作。告诉%b它处理参数中的反斜杠转义符,因此“文本”中的任何内容都会得到处理。


归档时间:

查看次数:

1378 次

最近记录:

3 年,9 月 前