扩展 Bash 提示符
Bash(Bourne Again Shell)是 Bourne shell 的后代,是 GNU 产品,也是大多数 Linux 机器上的标准命令行界面。它擅长交互性,支持命令行编辑、补全和回忆。它还支持可配置的提示符——大多数人意识到了这一点,但可能没有意识到它有多么有用。
大多数 Linux 系统都有一个默认提示符,以一种颜色(灰色)显示,其中包括您的用户名、您正在工作的机器名称和您当前的工作目录。此外,您可以显示更多信息,使用 ANSI 颜色并操作 xterm 的标题栏以提供有用的信息。
除了看起来很酷之外,提示符对于跟踪系统信息也很有用。许多人感兴趣的一个想法是在不同的机器上使用不同的颜色提示符。如果您在不同的机器上打开了多个 xterm,或者如果您容易忘记您正在工作的机器,您会发现这是一个很好的提醒。
要更改您的提示符,您需要对 shell 编程和 UNIX 实用程序有基本的了解。您了解的越多,您将能够创建的提示符就越复杂。
提示符的外观由 shell 变量 PS1 控制。命令延续由 PS2 字符串指示,可以以完全相同的方式修改。由于控制它完全相同,我将主要修改 PS1 字符串。(PS3 和 PS4 字符串也可用,但普通用户永远看不到。如果您对它们的用途感兴趣,请参阅 Bash 手册页。)要更改提示符的显示方式,请更改 PS1 变量。出于实验目的,可以在提示符处输入 PS1 字符串以立即显示结果。这样做只会影响您当前的会话。如果您想进行永久更改,请通过添加 PS1 的新定义来修改 ~/.bashrc 文件。如果您具有 root 权限,则可以修改 /etc/profile 文件中的 PS1= 行。在某些发行版(至少是 Red Hat 5.1)上,/etc/bashrc 文件会覆盖 /etc/profile 对 PS1 和 PS2 的设置。
我的默认提示符包括我的用户名“giles”、我的工作机器名称“nikola”和我的主目录 /home/giles。最简单的提示符是单个字符。我可以将我的默认提示符更改为简单的 $,方法是输入
[giles@nikola giles]$ PS1="$ "
我使用引号来强制在提示符后添加一个空格,使其更具可读性。
Bash shell 提供了许多转义序列,用于插入到提示符中。请参阅侧边栏,其中显示了 Bash 2.02 手册页。
$ PS1="\u@\h \W> "<\n> giles@nikola giles>
此示例创建一个类似于大多数 Linux 发行版上的默认提示符的提示符。我想要稍微不同的外观,所以我将其更改为包含时间,方法是输入
giles@nikola giles> PS1="[ ][\u@\h:\w]$ "<\n> [21:52:01][giles@nikola:~]$Bash 还提供了一个名为 PROMPT_COMMAND 的环境变量。此变量的内容在 Bash 显示提示符之前作为常规 Bash 命令执行。
[21:55:01][giles@nikola:~] PS1="[\u@\h:\w]$ "<\n> [giles@nikola:~] PROMPT_COMMAND="date +%H%M" 2155 [giles@nikola:~] ls bin mail 2156 [giles@nikola:~]$ unset PROMPT_COMMAND [giles@nikola:~]在此示例中,我通过消除转义序列来更改 PS1,以便时间不再是提示符的一部分。然后我使用 date +%H%M 以我更喜欢的格式显示时间。最后,我使用 unset 命令删除 PROMPT_COMMAND 环境变量。
当我讨论在提示符中使用外部命令时,我将使用 $(command) 约定进行命令替换;也就是说,
$(date +%H%M)
表示“在此处替换来自 date +%H%M 命令的输出。”这在 Bash 1.14.7 和 2.0+ 中有效。在某些旧版本的 Bash 中,您可能需要使用反引号(`date +%H%M`)。反引号可以在 Bash 2.0+ 中使用,但正在逐步淘汰,转而使用 $(),后者嵌套性更好。如果您使用的是早期版本的 Bash,请在您看到 $() 的任何地方替换为反引号。如果命令替换被转义(即 \$(command) ),则使用反斜杠转义您的两个反引号(即 \`command\`)。
您不希望从外部命令向提示符中插入太多内容,因为可能会创建非常长的提示符。您还需要使用快速命令,因为它将在每次提示符出现在屏幕上时执行。当您工作时,提示符出现延迟可能会很烦人。
[giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]$ "[2159][giles@nikola:~]$
请注意命令替换的美元符号之前的反斜杠。如果没有它,外部命令只执行一次:当 PS1 字符串被读入环境时。对于此提示符,无论提示符使用了多长时间,它都将显示相同的时间。反斜杠阻止 shell 立即解释命令,因此每次生成提示符时都会调用 date。
Linux 附带了许多小型实用程序,例如 date、grep 和 wc,它们允许您操作数据。如果您希望在提示符中创建这些程序的复杂组合,则制作一个 shell 脚本并从提示符中调用它可能会更容易。列表 1 中给出了在提示符中使用的小型 shell 脚本的示例。
我将此作为 shell 脚本保存在我的 ~/bin 目录中,该目录在我的路径中。以这种方式在提示符中使用它
[2203][giles@nikola:~]$ PS1="[\u@\h:\w (\$(lsbytesum) Mb)]\$ "[giles@nikola:~ (0 Mb)]$ cd /bin [giles@nikola:/bin (4.498 Mb)]$
非打印转义序列可用于在提示符中产生有趣的效果。要使用这些转义序列,您需要将它们括在 \[ 和 \] 中,告诉 bash 在计算提示符的大小时忽略此材料。未能包含这些分隔符会导致行编辑代码将光标放置在错误的位置,因为它不知道提示符的实际大小。在版本 2 之前的 bash 中,转义序列还必须以 \033[ 开头,而在更高版本中,则以 \033[ 或 \e[ 开头。
此示例修改了 xterm 窗口的标题栏。如果您尝试在控制台中使用提示符更改 xterm 的标题栏,您将在提示符中产生垃圾。为了避免此问题,请测试 term 环境变量以确定您的提示符是否将在 xterm 中。如果 shell 是 xterm,则 shell 变量 (${titlebar}) 已定义。它由适当的转义序列和 \u@\h:\w 组成,这将 user@machine: 工作目录 放在 xterm 标题栏中。这对于最小化的 xterm 特别有用,使它们更容易识别。此提示符中的其他材料应该从我们之前创建的提示符中熟悉。
列表 2 是一个可以合并到 ~/.bashrc 中的函数。然后可以调用函数名称来执行该函数。该函数与 PS1 字符串一样,存储在环境中。一旦 PS1 字符串由函数设置,您可以通过键入 unset proml 从环境中删除该函数。由于提示符无法从 xterm 变为控制台,因此不会在每次生成提示符时测试 TERM 变量。
我在提示符的定义中使用了延续标记(反斜杠),以允许它在多行上继续。这提高了可读性,使其更易于修改和调试。
我将其定义为一个函数,因为这是 Bash Prompt 包处理提示符的方式:这不是唯一的方法,但它效果很好。随着您使用的提示符变得越来越复杂,在提示符处键入它们变得越来越繁琐,而在文本文件中创建它们变得更加实用。要在提示符处测试此示例,请将该函数另存为名为“proml”的文本文件。Bash source 命令可用于通过键入以下内容来读取提示符函数
[giles@nikola:~ (0 Mb)]$ source proml
要执行提示符函数,请键入
[giles@nikola:~ (0 Mb)]$ proml
如前所述,非打印转义序列必须括在 \[\033[ 和 \] 中。对于颜色转义序列,它们还必须后跟小写字母 m。要在提示符中包含蓝色文本
PS1="\[\033[34m\][\$(date +%H%M)][\u@\h:\w]$ "
以 34 颜色代码开头的蓝色永远不会切换回常规灰色,因此您在提示符后键入的任何文本仍然是提示符的颜色。这也是深蓝色阴影(非常难以阅读),因此将其与粗体代码结合使用可能会有所帮助
PS1="\[\033[1;34m\][\$(date +%H%M)][\u@\h:\w]$\[\033[0;37m\] "提示符现在是浅蓝色,并且它通过将颜色切换回灰色来结束,这是我们大多数人在键入时期望的颜色。
背景颜色可以通过使用 44 表示蓝色背景,41 表示红色背景等来设置。没有粗体背景颜色可用。可以组合使用,例如,蓝色背景上的浅红色文本:\[\033[44;1;31m\]。其他可用代码包括 4 表示下划线,5 表示闪烁,7 表示反向和 8 表示隐藏。
我最常用的提示符是基于 Bash Prompt 包中名为“elite2”的提示符,我对其进行了修改,使其在标准控制台上更好地工作(列表 2)。(原始提示符使用特殊的 xterm 字体。)我将颜色定义为临时 shell 变量,以提高可读性——这样更容易使用。GRAD1 变量是检查您所处的终端,只需要执行一次。您看到的提示符如图 1 所示。

图 1. 我的提示符
Bash Prompt 包的 beta 版可在 http://bash.current.nu/ 上获得,是几个人共同完成的作品,由 Rob Current 协调。该软件包提供了一种使用多个提示符或“主题”的简单方法。其中一些提示符使用扩展的 VGA 字符集,因此除非与特殊的 xterm 字体一起使用,否则它们看起来很糟糕。图 2 中显示的“fire”主题需要这些字体。有关安装和使用这些字体的说明,请参阅 Stumpy's ANSI Fonts 页面,网址为 http://home.earthlink.net/~us5zahns/enl/ansifont.html。

图 2. 来自 Bash Prompt 包的 Fire 提示符
您可以使用示例 elite 函数通过键入 source elite(假设 elite 函数文件在您的路径中)然后键入 elite 来更改当前终端中的提示符。这会在您的环境空间中留下一个额外的函数 (elite)——如果您想清理环境,请键入 unset elite。
这似乎是小型 shell 脚本的理想候选者,但脚本在这里不起作用,因为脚本无法更改当前 shell 的环境——它只能更改它运行的子 shell 的环境。当前 shell 的环境变量可以通过环境函数更改。Bash Prompt 包将一个名为 callbashprompt 的函数放入您的环境中,虽然他们没有记录它,但可以调用它来动态加载任何 Bash Prompt 主题。它在它安装的主题目录中查找,获取您请求的函数,加载它,然后取消设置该函数。callbashprompt 并非旨在以这种方式使用,并且没有错误检查,但它工作得很好。
Giles Orr 是佐治亚学院和州立大学的系统图书管理员。他使用 Linux 已经四年了。他不声称自己是编程大师,并欢迎对本文代码的改进。可以通过 giles@interlog.com 与他联系。他是 http://metalab.unc.edu/LDP/HOWTO/Bash-Prompt-HOWTO.html 上的 Bash Prompt HOWTO 的维护者。