11 KiB
第五章 - PS* 介绍
这一章介绍了PS1, PS2, PS3, PS4, 以及PROMPT_COMMAND.
所谓的这些PS,实际上就是我们看到的提示符, 比如在终端上你看到的name@host~ $.
各位看官且跟我走~
Hack-38 PS1
PS1
PS1就是你每次打开终端, 首先显示的提示符, 比如 kity@cat ~$.
在你的~/.bashrc中已经定义了默认的PS1:
➤ cat .bashrc | grep 'PS1'
# PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
➤
那你就会说, 哎, 为啥你的终端和我的不一样啊, 你的怎么是个箭头呢?
那是因为我修改过呀:
if [ `whoami` == root ]; then
PS1='\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\[\033[10;31m\]# \[\033[00;31m\]\[\033[00m\]'
else
PS1='\[\033[00;31m\]➤ \[\033[00;31m\]\[\033[00m\]'
fi
是不是很 low...
言归正传, 解释一下上面的每个参数都代表什么:
\u代表用户名, 取决于whoami\h主机名,取决于hostname\w当前目录的绝对地址, 取决于pwd
还有好多作者没有介绍的, 我在此把他写的另一篇文章放上来:
算是个扩展阅读吧!
Hack-39 PS2
PS2
PS2是当你敲命令换行的时候所提示你输入的字符, 比如:
➤ echo "hi
> hello world!
> "
hi
hello world!
➤
在这里, '>'就是PS2, 如果更改PS2的值之后:
➤ PS2='#'
➤ echo "hi
#hello world!
#"
hi
hello world!
➤
就会这样了~
你可以按照你的喜好改成别的字符或是字符串.
Hack-40 PS3
PS3
PS3这个变量只存在于一个地方, 即select选择的时候, 提示输入选择的内容:
ramesh@dev-db ~> cat ps3.sh
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done
ramesh@dev-db ~> ./ps3.sh
1) mon
2) tue
3) wed
4) exit
#? 1
Monday
#? 4
默认的提示符是#?.
然后我们更改一下:
ramesh@dev-db ~> cat ps3.sh
PS3="Select a day (1-4): "
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done
ramesh@dev-db ~> ./ps3.sh
1) mon
2) tue
3) wed
4) exit
Select a day (1-4): 1
Monday
Select a day (1-4): 4
如果不在文件中更改的话, 也可以export一下(还是用第一个未更改过的脚本):
➤ cat ps3.sh
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done
➤ export PS3='yoooo--> '
➤ bash ps3.sh
1) mon
2) tue
3) wed
4) exit
yoooo--> 2
Tuesday
yoooo--> 4
➤
Hack-41 PS4
PS4
这可不是游戏机哦~
PS4这个变量存在于调试过程中, 也就是开起了set -x之后:
➤ cat ps4.sh
set -x
echo "PS4 demo script"
ls -l /etc/ | wc -l
du -sh .
➤
➤ bash ps4.sh
+ echo 'PS4 demo script'
PS4 demo script
+ ls -l /etc/
+ wc -l
285
+ du -sh .
4.9M .
默认的PS4是一个加号.
下面更改一下
➤ export PS4='$0.$LINENO+ '
➤ bash ps4.sh
ps4.sh.3+ echo 'PS4 demo script'
PS4 demo script
ps4.sh.4+ ls -l /etc/
ps4.sh.4+ wc -l
285
ps4.sh.5+ du -sh .
4.9M .
➤
其中$0是脚本名字, $LINENO是命令所在的行号.
Hack-42 PROMPT_COMMAND
PROMPT_COMMAND
PROMPT_COMMAND指的是当命令运行结束后所输出的字符.
比如:
➤ echo $PROMPT_COMMAND
echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"
➤ echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"
➤
➤
这个是啥也没有的输出...
咱改一改:
➤ PROMPT_COMMAND='echo "Hello world!"'
Hello world!
➤ whoami
mr
Hello world!
➤ pwd
/home/mr/test
Hello world!
➤ date
2016 年 01 月 04 日 星期一 22:17:24 CST
Hello world!
➤
看到了? 把PROMPT_COMMAND改成"Hello world!"之后, 每次命令结束都会再输出一个"Hello world!", 我们可以在这里做一点小动作:
作者把它改成了时间:
export PROMPT_COMMAND="date +%H:%M:%S"
➤ pwd
/home/mr/test
22:21:34
➤ whoami
mr
22:21:36
➤
我觉着没卵用, 倒不如这样好玩:
先自定义一个函数:
function ttt() { [[ $? -eq 0 ]] && echo -n yes || echo -n no; }
然后:
export PROMPT_COMMAND="ttt"
这样每次命令完成都有反馈啦~
(虽然也没什么卵用...
Hack-43 自定义 PS1
自定义 PS1
1.在提示符里输出用户名,主机名, 当前目录:
export PS1="\u@\h \W> "
其中:
\W是当前目录的 basename, 也就是目录名, 不带绝对路径的.
其他的在之前已经说过, 不再重复.
2.在提示符里输出当前时间:
export PS1="\u@\h [\$(date +%H:%M:%S)]> "
PS1中可以带命令, 正如上面的例子, 输出时便会附带当前时间.
上面的$(date +%H:%M:%S)可以替换为: \t
或者用\@输出当前的小时和分钟.
3.显示任何命令:
其实,这个说法并不是很准确, 因为自定义的命令不会运行, 除非像上一篇那样, 在外部定义了一个自己的命令, 否则, 只会输出第一次命令运行得到的结果, 听起来可能有点啰嗦, 你自己动手试一下就好了.
这里再多说几个:
......
妈蛋, 原作者说的都是些啥啊, 越来越水了... 没用的就不翻译了.
说点自己的经验:
- 这些变量是类似于一个子 shell 运行的, 外部命令不会对内部产生影响
- 变量可以是一条命令, 但是这条命令必须是系统自带的, 自己写的函数不会起作用.
- 自己在外部写的函数会在里面被引用, 不知道是替换还是什么, 总之能够运行.
- 不动手试一下你就不知道我说的是什么...
4.用内部已有的代码自定义 PS1
如果你看过之前的那篇文章(Hack-38 的扩展阅读部分), 这里的东西就当是复习了.
先列举一下那些内部代码, 类似于\n代表换行符一样:
\a响铃\d日期\D{format}自定义的日期\e逃逸字符\h主机名(前半部分)\H主机名(完整的)\j当前 shell 下的后台 job 数量, 相当于jobs\lshell 终端的 basename... (这个都给定义了...|n换行\r你知道\r和\n的区别嘛 (这个是回车, 上面的是换行哦~)\sshell 的名字\t24 小时制的时间 - HH:MM:SS\T12 小时制的时间 - HH:MM:SS\@12 小时制带上下午的时间 - am/pm (真啰嗦啊...\A24 小时制的时间 - HH:MM\u当前用户名\v当前 Bash 的版本号 (我真是醉了...\VBash 的发布版本号 4.3.42 (可以理解为较长的那个\w当前目录(绝对路径)\W当前目录的短名字 (可以理解为目录名\!这条命令在历史记录中的编号\#这条命令在当前 shell 中的编号\$如果$UID -eq 0那么这个就输出#, 否则输出$\nnnnnn 表示一个八进制的数字, 整体就表示这个八进制的字符\\一个反斜杠\[转义开中括号\]转义闭中括号
5.在PS1中运行自定义 function
哈哈, 我翻译PROMPT_COMMAND那一部分的时候还没看到这里呢, 所以不算剧透哦, 因为我也不知道作者写了这一部分, 而且上面的在PS*变量中自定义功能可是我举一反三得来的哦~
所以, 这里作者说的是定义了一个外部function, 然后在从PS1里面调用.
这样你的选择就多了去了, 随你想干什么, bash 都满足你哦~ 哈哈~
6.在PS1中运行脚本
在PS1变量中既然可以运行命令, 那么同样也可以运行脚本.
假如你在~/bin/totalfilesize.sh中存放着一个内容如下的脚本:
#!/bin/bash
for filesize in $(ls -l . | grep "^-" | awk '{print $5}')
do
let totalsize=$totalsize+$filesize
done
echo -n "$totalsize"
正如你所看到的, 这个脚本的作用是计算当前目录下文件的大小.
然后我们将PS1的值改掉:export PS1="\u@\h [\$(totalfilesize.sh) bytes]> "
那么每当你敲回车的时候都会看到当前目录下的文件总大小:
ramesh@dev-db [534 bytes]> cd /etc/mail
ramesh@dev-db [167997 bytes]>
PS:可以把脚本内容改成:
ls -l | awk '/^-/ { sum+=$5 } END { printf sum }'
这样会简练一些.
Hack-44 给点颜色给 PS1
给点颜色给 PS1
这里介绍了一堆关于彩色显示的代码...
1.字体颜色
用下面的代码可以让PS1变成蓝色:
export PS1="\e0;34m\u@\h \w> \e[m "
知道这是为什么嘛?
因为我们在中间嵌入了颜色代码:\e[0;34m 以及关闭颜色的代码:\e[m
下面的命令会让颜色变得更亮, 还带有加粗效果:
export PS1="\e[1;34m\u@\h \w> \e[m "
慢慢介绍里面的东西都是什么意思:
\e[颜色开启x;ym颜色的类型: x,y 自己定义\e[m关闭颜色
下面是一张颜色代码表:
| 颜色 | 代码 |
|---|---|
| 黑色 | 0;30 |
| 蓝色 | 0;34 |
| 绿色 | 0;32 |
| 青色 | 0;36 |
| 红色 | 0;31 |
| 紫色 | 0;35 |
| 棕色 | 0;33 |
如果把上面代码中的0替换成1就会使颜色加深, 字体加粗.
2.字体背景色
我们不仅可以更改显示的字体的颜色, 我们还可以改变字体的背景颜色:
export PS1="\e[47m\u@\h \w> \e[m "
上面的命令使我们得到了一个浅灰色的背景.
3.组合
没错, 我们当然可以把上两种结果组合起来, 实现任何你想要的结果:
export PS1="\e[0;34m\e[47m\u@\h \w> \e[m "
`
比如利用上面的代码就可以得到一个字体颜色为蓝色, 字体背景色为浅灰的效果.
下面是我自己截的图, 不要看花眼...
![promopt_color
每一行命令都对应它下一行开头的颜色.
这里还是希望你亲自实验一下, 而不是看一遍...
4.tput 命令
说实话, 我对这里也是第一次见, 长知识了.
例子:
$ export PS1="\[$(tput bold)$(tput setb 4)$(tput setaf
7)\]\u@\h:\w $ \[$(tput sgr0)\]"
其中:
tput setb [1-7]- 设置背景色tput setf [1-7]- 设置前景色tput setab [1-7]- 用 ANSI escape 设置背景色(我查了,但不懂...)tput setaf [1-7]- 用 ANSI escape 设置前景色
前两个好使, 就算用echo输出也是很漂亮的.
还有一些设置字体的选项:
tput bold粗体tput dim亮度减半tput smul开启下划线tput rmul关闭下划线tput rev颜色反转, 类似于高对比度那种tput smso开启高对比度模式tput rmso关闭高对比度模式tput sgr0关闭所有特效
颜色代码:
0– 黑色1– 红色2– 绿色3– 黄色4– 蓝色5– 洋红6– 青色7- 白色
扩展阅读
9 UNIX / Linux tput Examples: Control Your Terminal Color and Cursor