Linux的printf命令也可以输出ANSI转义码,不需要加-e选项,比如写成`printf"e[31m]。注意:这里需要把033[31m用双引号或者单引号括起来,防止bash自身转义\,这样会去掉\字符,导致echo命令接收不到\字符,无法处理转义字符。也可以写成echo-e"\e[31m",\e也是转义符的意思。后面测试的时候,统一使用\e的形式,输入更少的字符。具体测试如下:$echo-e"e[31m"$echo-e"e[0m"$执行后echo-e"\e[31m”命令,终端的提示符会变成红色,后面输入的字符也会变成红色。即终端默认的字符颜色变为红色。执行echo-e"\e[0m"命令重新设置终端属性,使终端的字符颜色变为原来的默认颜色。这里的0m转义码表示重置字符显示属性。一般来说,为了不影响终端本身的显示,使用ANSI转义码设置字符串显示颜色后,建议使用0m转义码重新设置为原来的颜色。示例如下:$echo-e"e[31mThisisaredstring.e[0m"Thisisaredstring.$在上面的命令中,\e[31m是ANSI转义码,意思是设置终端字符颜色为红色。\e[0m也是ANSI转义码,意思是重新设置终端的颜色属性,会恢复到原来的颜色。这两个转义码之间的字符串将显示在终端上。执行该命令后,终端的提示符会以原来的颜色显示。设置终端字符颜色的ANSI转义码详述如下。设置终端字符颜色的ANSI转义码的基本格式如下:Esc[Value;...;Valuem这里,Value可以提供多个值,使用分号';'分开。这些值可以分别指定字符的前景色、背景色和字符属性(粗体、下划线、反色)。它们之间的顺序没有限制。转义码以m字符结尾。设置字符前景色的值如下:colorvaluecolor30black31red32green33yellow34blue35purple36cyan37white设置字符背景色的值如下:colorvaluecolor40black41red42绿色43黄色44蓝色45紫色46青色47白色设置字符属性值如下:属性值属性含义0重置所有属性,包括字符颜色1设置粗体4添加下划线5开启闪烁7颜色反转8显示不可见text具体例子如下:$echo-e"e[31;44mFgcolor:Red.Bgcolor:Blue.e[0m"Fgcolor:红色的。Bg颜色:蓝色。$echo-e"e[44;31mFg颜色:红色。Bg颜色:Blue.e[0m"Fg红色。Bg颜色:蓝色。可以看出\e[31;44m和\e[44;31m这两个转义码设置的字符颜色是一样的。给定的前景色和背景色不需要顺序。目前大部分终端都支持256色,可以使用Esc[38;5;Valuem将终端字符设置为256色。这里的值是0-255。例如echo-e"\e[38;5;111mAAAAAA\e[0m"命令设置为111对应的颜色,具体颜色值请参考256色颜色表。网上有很多文章对它进行了解释。此处未列出。使用ANSI转义码移动终端光标ANSI转义码可用于移动终端光标位置,从而改变字符的输出位置。具体例子如下:$echo-e"123456789\e[4Dabc"12345abc9该命令中的\e[4D转义码表示将光标向左移动4列。可以看到,光标移动4列后,位于第6个字符的位置,重新输出abc,覆盖了原来的678个三个字符。具体移动游标的转义码解释如下:Esc码含义Esc[nA游标向上移动n行,列数不变。移动到终端顶部后,不再移动Esc[nB光标向下移动n行,列数不变。移动到终端底部后,Esc[nC光标不向右移动n列,行数不变。移动到终端最右边后,不再移动Esc[nD光标向左移动n列,行数不变。移动到终端最左边后,不再移动Esc[nE光标向下n行,列数变为行首Esc[nF光标向上n行,列数变为行首行Esc[Line;ColumnH将光标移动到指定的行数和列数。如果没有提供值,则默认值为0。Esc[ColumnG将光标移动到Column列,当前行号保持不变。Esc[s保存当前光标位置。稍后您可以使用Esc[u跳转到保存的位置。Esc[u跳转到Esc[s保存光标位置Esc[?25l隐藏光标(25后是小写l)Esc[?25h显示光标上面所说的终端位置是指终端可见的窗口位置,不包括缓冲位置。即窗口显示不会滚动,光标只会在当前可见的窗口区域跳动。注意:由于echo命令默认会输出一个换行符,所以移动光标后会造成换行,干扰光标移动的效果。在测试移动光标的转义码时,推荐使用printf命令进行测试。该命令默认不输出换行符。由于在bash中需要回车才能执行命令,所以会影响光标的左右移动。建议在printf本身输出的内容中左右移动光标。实际测试发现,如果光标向右移动n列,则光标会位于第n列的后面,然后输出字符串将从n+1列开始。Esc[C、Esc[0C、Esc[1C的作用相同,都是将光标向右移动一列。同理,Esc[D、Esc[0D、Esc[1D的作用相同,都是将光标向左移动一列。使用printf命令测试如下:$printf"123456789\e[1Da\n"12345678a$printf"123456789\e[0Da\n"12345678a$printf"123456789\e[Da\n"12345678a可以看出,使用\e[D,\e[0D,\e[1D向左移动光标,然后输出字符a,都覆盖同一个字符9。三个转义码对光标移动的作用是一样的。$printf"123456789\e[4Da\n"12345a789$printf"123456789\e[4D\e[Ca\n"123456a89$printf"123456789\e[4D\e[0Ca\n"123456a89$printf"123456789\e[4D\e[1Ca\n"123456a89\e[4D将光标向左移动4列到字符6。\e[C,\e[0C,\e[1C都将光标向右移动到下一个column,到字符7的位置,输出字符a,覆盖字符7。移动光标实现进度百分比的效果我们可以通过移动光标实现进度百分比的效果。假设有一个progress.sh脚本,内容如下:#!/bin/bashfor((i=0;i<=100;++i));doprintf"\e[5D%3d%%"$isleep0.1sdoneecho此处使用printf命令进行输出以格式化字符串。printf命令还使用\e来表示转义字符。\e[5D转义码表示将光标向左移动5列。由于输出字符不超过5个字符,所以光标每向左移动5列,就会移动到最左边,从第一列开始输出。那么后面输出的内容就会覆盖前面输出的内容,从而达到同一行重复输出的效果。sleep0.1s命令表示暂停0.1秒。添加此语句以清楚地看到进度百分比跳跃。否则执行速度太快,百分比会很快跳到100%。progress.sh脚本执行结果如下:$./progress.sh100%这不是动图,看不到进度百分比跳跃。你可以在实践中看到它。从结果来看,for循环中打印了多次信息,都打印在同一行,覆盖了之前的输出。而不是换行打印。通过移动光标实现进度条的效果接下来,通过移动光标实现进度条的效果。假设有一个progressbar.sh脚本,内容如下:#!/bin/bashfunctionprint_chars(){#传入的第一个参数指定要打印的字符串localchar="$1"#传入的第二个参数指定打印指定字符串多少次localnumber="$2"localcfor((c=0;c