然后直接写出了我的新的 PS1:
1 |
PS1='`a=$?;if [ $a -ne 0 ]; then a=" "$a; echo -ne "\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]"; fi`\[\e[1;32m\]\u@\h:\[\e[0m\e[1;34m\]\W\[\e[1;34m\]\$ \[\e[0m\]' |
非常复杂唉……让我自己再看一次都头晕……
转载者注:若想一直保存效果 可将代码添加至$HOME/.bashrc文件中 之后每次启动终端都会自动加载当前代码
分解这个提示符
上面看到这个 PS1 写的非常之复杂,不过其实拆解开来也没什么了不起的,只不过看起来蛋疼罢了~
这个 PS1 可以分为两个部分,第一个部分是:
`a=$?;if [ $a -ne 0 ]; then a=" "$a; echo -ne "\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]"; fi`
第二个部分是:
\[\e[1;32m\]\u@\h:\[\e[0m\e[1;34m\]\W\[\e[1;34m\]\$ \[\e[0m\]
我们先来研究第二部份,这个部分看起来比较简短。其中我们可以看到一个 PS1 里面非常基本的结构:\u@\h:\W\$ ,这个结构在我的电脑里就显示为 upsuper@upsuper-laptop:~$ 大家大概可以猜到里面是什么意思了吧。
这个基本骨架理出来,剩下的是看过去最蛋疼的那堆莫名其妙的符号了~我们看到很多 \e[ 这样的东西,事实上这个叫做 ANSI 控制码,在 Linux 和 Windows 的命令行里面都是通用的,\e 是 Escape 键的键码,\e[ 是一切 ANSI 控制码的开头。首先来到 \e[1;32m 这个控制码,这表示设置这个符号之后的字符为亮绿色,而 \e[0m 则是清除所有格式,这样看有没有一点清晰了呢?更多用法可以参考维基百科条目ANSI escape code。
之后还有两个东西不清楚,就是 \[ 和 \],这两个并不是 ANSI 控制码,而是 Bash 提供的转义符。他们的解释说实话我没看太懂,不过我的理解大概就是,夹在 \[ 和 \] 之间的部分 Bash 假定他们的宽度为0,不正确地标注这两个符号会导致 Bash 的换行错误。总之在所有控制符两侧都加上这两个就对了~
第二个部分解决了,下面来看蛋疼的第一部份
`a=$?;if [ $a -ne 0 ]; then a=" "$a; echo -ne "\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]"; fi`
很明显,整个结构被一个正引号引起来,表示执行并返回其中的结果。这样我们就可以把这个部分分解开来了:
a=$?
if [ $a -ne 0 ]; then
a=" "$a
echo -ne "\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]"
fi
稍微懂点编程就会觉得这也没什么技术含量嘛,其中 $? 就是上一个程序运行的返回值,我们获取并判断他,如果不为零就进行下面的操作。a=” “$a 这句我们待会而再看,先看下面那个 echo -ne 的语句。echo 我们知道是显示字符串,而 -ne 实际上是两个参数 -n 和 -e,-n 表示输出字符串后不输出换行符,-e 表示解析后面的转义符。
最后就剩分析那个打印的东西了。我们发现主要部分其实和上面是一样的,无非就是一些设置格式的事情,我们去掉格式设置,发现主要是这样的:
\e[s\e[1A\e[$((COLUMNS-2))G${a:(-3)}\e[u
这个部分仍然包含许多 ANSI 控制符,第一个是 \e[s,表示保存当前光标位置,与最后一个表示恢复光标位置的控制符 \e[u 遥相呼应,由于我们需要大规模移动光标,所以我们要备份一下位置。然后我们看到 \e[1A,这个控制符表示将光标上移一行。然后之后有一个很复杂的东西 \e[$((COLUMNS-2))G,这个对应的控制符是 \e[*G,表示设置光标到第几列,而 $((COLUMNS-2)) 表示这个列数为当前可显示的最大列数-2。后面有一个 ${a:(-3)},也就是取前面的后三位显示(返回值的范围是0-255)。
现在我们回到前面的 a=” “$a,发现这个的目的其实是和 ${a:(-3)} 对应,让这个部分无论如何保证有三个字符可以出现。事实上最初我并不是这么写的,而是写 $((COLUMNS-${#a}+1)),表示 $a 有多长就显示多长。但这样感觉不美观,就改成了固定3字符长。
到这里也就结束了,然后我们发现,其实看过去很复杂的东西,拆开来还是挺简单的嘛~