从我记事起,我个人在使用 bash 时使用以下方法更改输出文本的颜色:
red=$'\033[1;31m'
nc=$'\033[0m'
echo "${red}This is red text$nc"
无论是在 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 ""
使用 bash 和 sh 在 macOS 上输出:
使用 bash 和 sh 在 Linux 上输出:
这里主要是终端要识别控制序列,发送到终端的输出必须包含 ESC 字符,然后
[1;31m
. 该 ESC 是一个控制字符,我们通常不会在 shell 脚本中按原样显示它,而是使用反斜杠转义\033
来使用其八进制字符代码(它是十进制 27、八进制 033 或十六进制 0x1b )。其余的只是普通字符。现在,该反斜杠转义需要在某个时候更改为原始 ESC 字符。有两个地方可能会发生这种情况:对变量的赋值和打印它的命令。
在支持它的 shell 中,
$'...'
引号的类型已经解释了转义,因此在 之后red=$'\033[...'
,变量本身包含原始 ESC 字符。这不是标准的 POSIX 功能,在不支持它的 shell 中,它会分配原始美元符号,然后是反斜杠,033[
等等。另一方面,red='\033[...'
只会分配反斜杠033[
等,从不解释转义。看(
$"..."
,并且"..."
永远不要解释转义,并且带有美元的那个也是非标准的,因此可能会将文字美元符号留在不支持它的外壳中。)然后,第二步是印刷。在某些 shell
echo
中扩展了反斜杠转义。在其他情况下则不然。其中一些人echo -e
再次这样做。Bashecho
默认情况下不会这样做,但是在xpg_echo
设置设置后......它会这样做。Zshecho
确实解释了它们。看因此,在您通常的 Linux 桌面发行版上的通常 Bash 中,
xpg_echo
未设置的地方red=$'\033[1;31m'; echo "${red}text"
会在作业上生成 ESC 并打印红色文本,但red='\033[1;31m'; echo "${red}text"
不会在作业或 the 中生成它,echo
并且只会以正常颜色打印\033[1;31mtext
。在 Debian/Ubuntu 上,
sh
是 Dash,其中$'...'
不支持引号但echo
会解释反斜杠,因此red=$'\033[1;31m'; echo "${red}text"
打印一个 normal-colored$
,然后是红色文本。这就是你的运行sh
和 Linux 的样子。在其他一些 Linux 系统中,您可能会得到不同的结果。在 Mac 上,安装的 shell
sh
实际上是带有xpg_echo
set 的 Bash(安装bash
时禁用了它),或者是较新的 macOS 版本中的 zsh。尽管开始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
反斜杠转义,因此“文本”中的任何内容都会被处理。我可以回答 Linux。我认为关键不是如何使用 ANSI 转义序列,而是如何声明一个变量。
在
sh
中,当您使用您打印变量的值,
red
然后打印一些文本。在前两种情况下,ANSI 转义序列之前有一个美元符号,因此不受颜色变化的影响。在
bash
中,当您使用ANSI 转义序列被解释,但与
ANSI 转义序列不会被解释,而是按字面意思打印字符,但可能会在
echo
语句“之前”进行转换。在你
sh
有另一个内置函数echo
,它显然解释了没有选项的 ANSI 转义序列-e
。bash
如果您查看 的十六进制值,则可以解释第一个示例和其他示例之间的差异red
。查看我编辑的脚本,echo -e
我还通过将该选项添加到脚本中来方便查看,因此请尝试两者和
我建议你声明你的“着色”变量没有任何美元符号,例如
并且仅当您在语句中使用变量时才使用美元符号。
echo