如何修改PS1命令行提示符的颜色

  • 原创
  • Madman
  • /
  • 2018-05-09 09:23
  • /
  • 0
  • 327 次阅读

Linux修改字符颜色-min.png

Synopsis: 在Linux中要改变输出字符的颜色,可以使用ANSI转义码或者tput命令。ANSI转义码可以控制字符的显示效果如加粗、加下划线、闪烁等,也可以改变字体的显示颜色(前景色),或者改变背景显示颜色,这些显示控制代码是可以组合使用的,用分号隔开即可,与顺序无关。tput命令也有对应的子命令来达到这些效果。另外,如果要修改Linux命令提示符PS1的颜色,需要特别注意的是bash环境下还需要在ANSI转义码前后添加\[和\]这两个额外的转义字符,否则当在命令行中输入的字符长度过长要换行时会错乱

1. ANSI转义码

ANSI转义码可以将光标定位在显示器上的指定位置,擦除部分显示,以及控制显示的格式(本文将要讨论的内容)等

1.1 ANSI escape sequences - CSI

Control Sequence Introducer, CSI是ANSI转义序列中最有用处的序列,用两字符序列ESC [表示,这个序列是由控制字符ESC(通常用^[<ESC>表示),加上后面的左方括号字符[组成,即^[[。因为大多数文本编辑器将键盘上的ESC键解释为其它功能,所以不能仅敲击ESC键,比如在xterm终端中要输出^[这个字符,你需要先按Ctrl + v,然后按ESC

在bash中,控制字符ESC也支持\e\033\x1b三种转义字符的写法,大写字母也行(console_codes

1.2 设置显示属性 - SGR

建议阅读ANSI转义码中关于SGR部分,和console_codes中关于ECMA-48 Set Graphics Rendition部分。

要控制显示格式,必须使用Set Graphic Rendition, SGR转义序列ESC [ parameters m,其中m表示这是SGR序列,parameters是控制代码,可以有多个代码组合,中间用分号;隔开,如果不指定代码ESC [ m相当于ESC [ 0 m(重置所有显示控制属性为默认设置)。

显示控制代码有3类:

  • 效果控制代码
  • 前景色控制代码(即字体颜色)
  • 背景色控制代码

(1) 效果控制代码

代码 效果 备注
0 重置所有显示属性为默认设置 reset all attributes to their defaults
1 字体加粗 set bold
4 字体加下划线 set underscore
5 字体闪烁 set blink
7 前景色与背景色调转 set reverse video

(2) 前景色与背景色控制代码

前景色控制代码和背景色控制代码都使用两位数表示,前景色使用3开头,而背景色使用4开头,第二位数字表示具体颜色:

前景色代码 背景色代码 颜色
30 40 黑色
31 41 红色
32 42 绿色
33 43 黄色
34 44 蓝色
35 45 紫色
36 46 青色
37 47 白色

因此,要设置红色前景则发送代码ESC [ 31 m,要设置黄色背景可以使用代码ESC [ 43 m;也可以组合使用,比如要设置字体颜色为红色、背景为黄色、且字体加粗,则使用代码ESC [ 31;43;1 m

注意: 上述转义序列代码在实际使用时中间不能有空格,上面用空格隔开只是为了演示时可以看清各组成部分

2. bash修改字符颜色

想在bash命令行或脚本中使用带颜色的字符,可以使用echo命令,像发送普通文本一样,将ANSI转义字符序列发送到终端会话:

1. 使用`^[`这个字符,你需要先按`Ctrl + v`,然后按`ESC`键(你不能直接复制我的哦~)
# echo ^[[31m红色字体

2. 使用bash的ESC转义控制字符,注意echo要使用-e选项,且后面的字符要用引号包括起来,单引号或双引号都可以
# echo -e "\e[31m红色字体"
# echo -e "\033[31m红色字体"
# echo -e "\x1b[31m红色字体"

# echo -e "\E[31m红色字体"  # 大写字母
# echo -e "\x1B[31m红色字体"

上述代码都可以显示红色字体,但是你会注意到在shell打印出echo命令中的文本之后,新的提示符仍然使用该颜色效果,需要使用重置控制码0(即ESC [ 0 m,中间不能有空格哦)将终端重置为正常显示:

# echo ^[[31m红色字体^[[0m
# echo -e "\e[31m红色字体\e[0m"
# echo -e "\033[31m红色字体\033[0m"
# echo -e "\x1b[31m红色字体\x1b[0m"

同时设置多个控制代码,用;隔开,顺序无关:

# echo -e "\e[31;42;1m绿底红字加粗\e[0m"
# echo -e "\e[1;42;31m绿底红字加粗\e[0m"
# echo -e "\e[1;42;31;5m绿底红字加粗,且字体闪烁\e[0m"
# echo -e "\e[1;42;31;5;4m绿底红字加粗,且字体闪烁、带下划线\e[0m"
bash hex octal NOTE
start \e \x1b \033
start \E \x1B - x cannot be capital
end \e[0m \x1b[0m \033[0m
end \e[m \x1b[m \033[m 0 is appended if you omit it
示例:
start green \e[32m<text></text> \x1b[32m<text></text> \033[32m<text></text> m is NOT optional
reset <text>\e[0m</text> <text>\1xb[0m</text> <text>\033[0m</text> 0 is optional (do it as best practice)

3. 修改PS1的颜色

PS1环境变量设置了bash当前的命令提示符的格式:

# echo ${PS1}
[\u@\h \W]\$

说明:
\u: Display the current username.
\h: Display the hostname.
\W: Print the base of current working directory.
\$: Display # (indicates root user) if the effective UID is 0, otherwise display a $.

每个Linux distributions 的 bash 预设的PS1环境变量的內容可能有些许差异,可以使用man bash去查看关于PS1的说明

如果还是使用默认格式,只是修改颜色,那么要注意bash设置字符颜色时,要添加额外的转义字符,否则你使用上/下方向键或Ctrl + r搜索历史命令时会使提示符错乱!

使用额外的转义字符\[\]将ANSI转义字符序列包括起来:

  • \[ is for start of a sequence of non-printable characters
  • \] is for end of a sequence of non-printable characters

这两个额外的转义字符通知 bash,被括起来的字符不占用命令行上的任何空间,这样就使自动换行能够继续正常工作。没有这两个转义序列,尽管您有了一个很漂亮的提示行,但是假如您键入的命令恰好到达终端的最右端,就会造成显示混乱。

1. 假设PS1="[\u@\h \W]\$ ",现在要将它整体显示为绿色加粗字体,那么在\e[32;1m和\e[0m这两个序列的外面都要添加\[\]
# export PS1="\[\e[32;1m\][\u@\h \W]\\$ \[\e[0m\]"

注意,为什么要写成\\$?因为$在bash中需要先转义,所以\\$才能正确显示root用户或普通用户

永久生效

如果要重启后也生效的话:

  • 所有用户都应用新PS1格式,需要修改/etc/bashrc,因为非登录的交互式shell不会访问/etc/profile
  • 只有当前用户应用新PS1格式,需要修改~/.bashrc,因为非登录的交互式shell不会访问~/.bash_profile
# echo 'PS1="\[\e[32;1m\][\u@\h \W]\\$ \[\e[0m\]"' >> ~/.bashrc
# source ~/.bashrc

4. tput命令

请执行man 1 tput查看tput的详细使用说明

4.1 显示控制命令

(1) Foreground & background colour commands

  • tput setab [1-7]: Set the background colour using ANSI escape
  • tput setaf [1-7]: Set the foreground colour using ANSI escape
Num  Colour    #define         R G B

0    black     COLOR_BLACK     0,0,0
1    red       COLOR_RED       1,0,0
2    green     COLOR_GREEN     0,1,0
3    yellow    COLOR_YELLOW    1,1,0
4    blue      COLOR_BLUE      0,0,1
5    magenta   COLOR_MAGENTA   1,0,1
6    cyan      COLOR_CYAN      0,1,1
7    white     COLOR_WHITE     1,1,1

There are also non-ANSI versions of the colour setting functions (setb instead of setab, and setf instead of setaf) which use different numbers, not given here.

(2) Text mode commands

tput bold    # Select bold mode
tput dim     # Select dim (half-bright) mode
tput smul    # Enable underline mode
tput rmul    # Disable underline mode
tput rev     # Turn on reverse video mode
tput smso    # Enter standout (bold) mode
tput rmso    # Exit standout mode

(3) Cursor movement commands

tput cup Y X # Move cursor to screen postion X,Y (top left is 0,0)
tput cuf N   # Move N characters forward (right)
tput cub N   # Move N characters back (left)
tput cuu N   # Move N lines up
tput ll      # Move to last line, first column (if no cup)
tput sc      # Save the cursor position
tput rc      # Restore the cursor position
tput lines   # Output the number of lines of the terminal
tput cols    # Output the number of columns of the terminal

(4) Clear and insert commands

tput ech N   # Erase N characters
tput clear   # Clear screen and move the cursor to 0,0
tput el 1    # Clear to beginning of line
tput el      # Clear to end of line
tput ed      # Clear to end of screen
tput ich N   # Insert N characters (moves rest of line forward!)
tput il N    # Insert N lines

(5) Other commands

tput sgr0    # Reset text format to the terminal's default
tput bel     # Play a bell

4.2 示例

1. 红色字体,没有重置代码,在shell打印出echo命令中的文本之后,新的提示符仍然使用该颜色效果
# tput setaf 1; echo "this is red text"

2. shell变量 - 红字和绿字,且有重置代码
# red=`tput setaf 1`
# green=`tput setaf 2`
# reset=`tput sgr0`
# echo "${red}red text ${green}green text${reset}"

3. 子命令 - 直接在echo中使用tput
# echo "$(tput setaf 1)Red text $(tput setab 7)and white background$(tput sgr0)"

tput accepts scripts containing one command per line, which are executed in order before tput exits. Avoid temporary files by echoing a multiline string and piping it:

1. set fg white and bg red
# echo -e "setaf 7\nsetab 1" | tput -S
分类: Linux
标签: \033 bash PS1 tput 修改颜色
未经允许不得转载: LIFE & SHARE - 王颜公子 » 如何修改PS1命令行提示符的颜色

分享

作者

作者头像

Madman

如果博文内容有误或其它任何问题,欢迎留言评论,我会尽快回复; 或者通过QQ、微信等联系我

0 条评论

暂时还没有评论.

发表评论前请先登录