如何在LinuxVPS上自定义Bash提示

来自菜鸟教程
跳转至:导航、​搜索

介绍


在管理 Linux 服务器时,您将花费大量时间使用命令行。 对于大多数人来说,这意味着要花费大量时间使用 Bash shell。

虽然大多数发行版都为用户和根提示的样式提供了合理的默认值,但自定义提示以添加自己的偏好会很有帮助。 您可以包含许多有用的信息,这些信息可以帮助您保持方向感,并在您使用提升的权限进行操作时提醒您。

我们将使用 Ubuntu 12.04 VPS 进行实验,但几乎所有现代 Linux 发行版都应该以类似的方式运行。

验证您的 Shell 是 Bash


在我们开始实际定制 shell 之前,您应该验证您当前的 shell 实际上 Bash。

对于绝大多数系统来说,这应该是正确的,但有时发行版维护者会选择不同的 shell,或者用户测试一个新的 shell。

通过检查 /etc/passwd 文件很容易验证。 在寻呼机中打开文件,如下所示:

less /etc/passwd

此文件中的每一行都包含有关不同用户的信息。 在第一列中找到您的用户和 root 用户,用冒号 (:) 分隔。 在最后一个字段中,将列出该用户的默认登录 shell:

root:x:0:0:root:/root:/bin/bash
. . .
demouser:x:1000:1000:,,,:/home/demouser/bin/bash

如果最后一个字段是 /bin/bash,那么您已经准备就绪。

如果最后一个字段是 not /bin/bash 并且您希望将默认 shell 更改为 Bash,您可以使用 root 权限编辑此文件并更改与您的用户关联的最后一个字段:

sudo nano /etc/passwd

进行更改后,注销并重新登录以使用 Bash shell。

查看当前值


首先,让我们探索一下配置文件中已有的内容来定义 Bash 提示。

Bash 通过使用 PS1PS2 环境变量来配置它的提示。

PS1 定义了您将看到的主要提示。 每次登录时都会看到这一点。 默认情况下,在 Ubuntu 系统中,这应该采用以下形式:

用户名@主机名: current_directory $

注意末尾的 $。 这表示 shell 是普通用户 shell。 对于 root 用户,这被替换为 # 以区分并让您知道您正在使用提升的权限进行操作。

PS2 提示符用于多行命令。 您可以通过在终端中键入以下内容来查看当前 PS2 变量的设置:

echo \

在反斜杠后直接按回车键即可看到提示。 默认情况下,在 Ubuntu 中,这是 >

通常,我们定义这些变量将保存在我们的 ~/.bashrc 文件中,当我们的交互式 shell 启动时读取该文件。

在 Ubuntu 12.04 上的这个文件中,我们可以找到这样的部分:

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
# force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

我们可以看到一些逻辑指示提示何时会被着色。 如果需要彩色提示,则需要取消注释 force_color_prompt=yes 行。 现在执行此操作以利用我们稍后将进行的自定义。

force_color_prompt=yes

我们关心的部分是设置提示的部分。 这嵌套在 if-else 构造中,根据您是否使用颜色,会有不同的提示:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

顶部增加了颜色支持。 我们先看第二部分,不带颜色先掌握一些基础知识:

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

这看起来相当复杂,并且有些部分似乎与我们在正常 shell 使用中看到的任何内容都不匹配。

包含debian_chroot的部分表示如果您在更改root环境下操作,会修改提示以提醒您。 您可能希望保持提示的这一部分完整,因为这是一个有用的功能。

提示定义的其余部分如下所示:

\u@\h:\w\$: 

这描述了我们一直看到的主要提示,使用了一些转义序列。

Bash 转义序列


我们可以在 Bash 手册页中找到可能的转义序列的完整列表:

 \a ASCII 钟形字符 (07) \d “Weekday Month Date”格式的日期(例如,“Tue May 26”) \D{format} 将格式传递给 strftime(3),并将结果插入到提示字符串; 空格式会产生特定于语言环境的时间表示。  大括号是必需的 \e ASCII 转义字符 (033) \h 主机名直到第一个 `.'  \H 主机名 \j 当前由 shell 管理的作业数 \l shell 终端设备名称的基本名称 \n 换行符 \r 回车 \s shell 的名称,$0 的基本名称(最后的部分斜线) \t 24 小时制 HH:MM:SS 格式的当前时间 \T 12 小时制 HH:MM:SS 格式的当前时间 @ 12 小时 am/pm 格式的当前时间 \A 以 12 小时制的当前时间24 小时 HH:MM 格式 \u 当前用户的用户名 \v bash 的版本(例如,2.00) \V bash 的发布,版本+补丁级别(例如,2.00.0) \w 当前工作目录, $HOME 用波浪号缩写(使用 PROMPT_DIRTRIM 变量的值) \W 当前工作目录的基本名称,$HOME 用波浪号缩写!     此命令的历史编号 # 此命令的命令编号 $ 如果有效 UID 为 0,则为 #,否则为 $ \nnn 对应于八进制数的字符 nnn \ 反斜杠 [ 开始一系列非打印字符,可用于将终端控制序列嵌入到提示中] 结束一系列非打印字符

如您所见,有一些基本信息和一些您可能不需要的信息(ASCII 响铃字符、Bash 版本等)。

我们的提示现在有用户名 (\u)、@ 符号、主机名的第一部分 (\h)、当前工作目录 (\w),最后是普通用户的“$”和“# ” 对于根用户。

让我们退出 ~/.bashrc 文件,以便我们可以测试一些其他选项。

测试新的 Bash 提示


尽管最终我们会想要编辑我们的 ~/.bashrc 文件以使我们的选择永久化,但尝试从命令行本身更改提示要容易得多。

在我们开始修改之前,让我们将 PS1 的当前值保存到一个新变量中。 这将使我们能够更轻松地切换回原始提示,而无需注销并再次登录以防万一我们犯了错误。

ORIG=$PS1

现在,我们有一个名为 ORIG 的环境变量,它将保存我们默认提示的副本。

如果我们需要切换回原来的提示,我们可以输入:

PS1=$ORIG

让我们从简单的开始,只使用我们的用户名和一个 $ 作为实际提示:

PS1="\u$"

我们应该得到如下所示的东西:

demouser$

让我们留出一点空间让它看起来更漂亮:

PS1="\u $: "

demouser $:

不过,我们可能不想使用“$”字面字符。 我们应该改用 \$ 转义序列。 这将根据我们是否为 root 动态修改提示,从而使我们的 PS1 可以正确地用作 root:

PS1="\u \$: "

我们可以在提示符中添加我们想要的任何文字字符串:

PS1="Hello, my name is \u! \$: "

Hello, my name is demouser! $:

我们还可以使用常规 shell 功能插入任意命令的结果。

在这里,我们可以通过使用反引号插入命令结果来拉动在 /proc/loadavg 找到的负载指标的第一列,让我们的提示符给出我们服务器的当前负载:

PS1="\u, load: `cat /proc/loadavg | awk '{ print $1; }'` \$: "

demouser, load: 0.01 $:

这是了解您是否对系统征税的好方法。

如果日期或时间对您的提示很重要,您可以尝试这样的事情。 让我们也用一些括号和括号对我们的数据进行一些划分,以使其保持井井有条。 让我们也添加 \w 来跟踪我们的工作目录:

PS1="[\u@\h, load: `cat /proc/loadavg | awk '{ print $1; }'`] (\d - \t) \w \$ "

[demouser@host, load: 0.01] (Thu Feb 20 - 13:15:20) ~ $

这开始变得有点笨拙,特别是如果我们将目录更改为路径很长的东西:

cd /etc/systemd/system/multi-user.target.wants

[demouser@host, load: 0.01] (Thu Feb 20 - 13:18:28) /etc/systemd/system/multi-user.target.wants $

如果我们仍然想要所有这些信息,但想让它更短,一种策略是使用 \n 换行符将信息分成两行:

PS1="[\u@\h, load: `cat /proc/loadavg | awk '{ print $1; }'`] (\d - \t)\n\w \$ "

[demouser@host, load: 0.00] (Thu Feb 20 - 13:20:00)
/etc/systemd/system/multi-user.target.wants $

有些人不喜欢多行提示,但这是在提示中提供更多信息的一种方式。

更改提示颜色


现在我们已经很好地掌握了影响提示的不同方式,让我们尝试一些着色。

Bash 允许您通过使用特殊代码在提示中引入颜色。 这些通常是混淆的来源,因为选择的代码不是很具有描述性。

在我们了解实际的颜色代码之前,我们应该谈谈我们如何实际实现它们。 在 Bash 设置中定义颜色代码的方法有对有错。

首先,您必须将整个颜色代码描述包含在 \[\] 标签中。 这些括号指示 bash 存在于第一个序列之后直到最后一个序列的字符应被视为非打印字符。

Bash 需要知道这一点,以便它可以估计在换行到下一行之前要打印多少个字符。 如果您没有在 \[\] 标签中包含您的颜色代码,Bash 会将所有字符计为文字字符,并且会过早换行。

其次,在括号非打印序列中,您需要通过键入 \e[\033[ 来指定颜色提示的开头。 它们都做同样的事情并指示转义序列的开始。 我将在本指南中使用 \e[,因为我认为它更清晰一些。

\] 之前,你需要一个“m”来表示你正在给出一个颜色序列。

所以基本上,每次我们想要修改颜色时,我们都必须在提示符中输入如下内容:

[\e[颜色信息m]

如您所见,这是使我们的提示特别混乱的部分。

至于颜色代码,改变前景文本颜色的基本代码在这里:

  • 30:黑色
  • 31:红色
  • 32:绿色
  • 33:黄色
  • 34:蓝色
  • 35:紫色
  • 36:青色
  • 37:白色

您还可以通过在基值前设置“属性”来修改这些基值,用分号 (;) 分隔。

根据您使用的终端类型,这些终端的行为可能会大不相同。 一些更常见的属性是:

  • 0:普通文本
  • 1:粗体或浅色,取决于端子
  • 4:下划线文字

所以如果你想要带下划线的绿色文本,你会使用这样的序列:

\[\e[4;32m\]

然后我们将输入我们想要的提示。 之后,我们可能希望将颜色重置回其原始值,以便我们在终端中键入的文本不会出现奇怪的颜色。

我们可以通过使用另一个颜色代码来表示 Bash 应该重置提示颜色来做到这一点。 这段代码是:

\[\e[0m\]

因此,带有用户名和主机的简单彩色提示可能如下所示:

PS1="\[\e[4;32m\]\u@\h\[\e[0m\]$ "

我们还可以指定背景颜色以提高复杂性。 背景颜色不能带属性。 他们是:

  • 40:黑色背景
  • 41:红色背景
  • 42:绿色背景
  • 43:黄色背景
  • 44:蓝色背景
  • 45:紫色背景
  • 46:青色背景
  • 47:白色背景

尽管您可以像这样一次性指定背景颜色、属性和文本颜色:

\[\e[42;1;36m\]

如果将背景信息与其他信息分开,通常效果会更好:

\[\e[42m\]\[\e[1;36m\]

有时,如果您只使用“普通”文本属性 (0),则在某些终端中颜色会出现乱码。 您可以通过不使用 0 指定正常值来避免这种情况,因为无论如何它都是默认值。

使您的即时更改永久化


现在我们已经玩了一段时间的提示,我们应该对我们希望提示的外观有一个很好的了解。 您应该能够创建彩色和非彩色提示。

对于我们的示例,我们将使用以下彩色提示:

PS1="[\[\e[0;32m\]\u@\h, load: `cat /proc/loadavg | awk '{ print $1; }'`\[\e[00m\]] (\[\e[00;35m\]\d - \t\[\e[00m\])\n\w \$ "

我们也将使用它的非彩色等效项,因为当我们不希望有彩色 bash 提示时:

PS1="[\u@\h, load: `cat /proc/loadavg | awk '{ print $1; }'`] (\d - \t)\n\w \$ "

现在我们有了我们想要的提示的两个版本,我们可以在我们的 ~/.bashrc 文件中编辑 PS1

nano ~/.bashrc

正如我们在开始时所讨论的,我们文件中的提示现在包含了使我们在 chroot 环境中时变得明显的功能。 让我们把那部分留在里面。 现在看起来像这样:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

注释掉当前的 PS1 赋值并复制下面的 debian_chroot 逻辑,使其看起来像这样:

如果 [ “$color_prompt” = 是 ]; 然后 # PS1='${debian_chroot:+($debian_chroot)}[\033[01;32m]\u@\h[\033[00m]:[\033[01;34m]\w[\033[00m ]$ ' PS1='${debian_chroot:+($debian_chroot)}' else # PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$ ' PS1='${debian_chroot:+ ($debian_chroot)}' fi unset color_prompt force_color_prompt

在提示的最后,就在最后一个引号关闭之前,我们可以添加我们想要实现的提示。 实际上,由于我们的提示使用了单引号,所以我们想更改当前提示中的引号类型使用双引号。

在第一个 PS1 分配中,使用提示的彩色版本。 在第二种情况下,使用非彩色的。

如果 [ “$color_prompt” = 是 ]; 然后 # PS1='${debian_chroot:+($debian_chroot)}[\033[01;32m]\u@\h[\033[00m]:[\033[01;34m]\w[\033[00m ]$ ' PS1= " ${debian_chroot:+($debian_chroot)} [[\e[0;32m]\u@\h,加载:cat /proc/loadavg | awk '{ print $1; }'  [\e[00m]] ([\e[00;35m]\d - \t[\e[00m])\n\w $ " else # PS1='${debian_chroot:+($debian_chroot)}\ u@\h:\w$ ' PS1= " ${debian_chroot:+($debian_chroot)} [\u@\h, 加载:cat /proc/loadavg | awk '{ print $1; }'  ] (\d - \t)\n\w $ " fi unset color_prompt force_color_prompt

完成后,我们可以关闭并保存文件。

现在,当您注销并重新登录时,您的提示将更改为您设置的值。

结论


您可以通过多种不同的方式来个性化您的配置。 对某些项目进行着色可以使它们脱颖而出,并且可以帮助您在滚动浏览终端历史记录时找到最后一个提示。

另一个流行的想法是为 root 用户提供一个特殊的提示,这样对比就会提醒你你的特权。 发挥创造力并尝试在有用的信息和混乱之间找到适合您的平衡点。

贾斯汀·艾林伍德