如何在 Linux VPS 上自定义你的 Bash 提示符

简介: 如何在 Linux VPS 上自定义你的 Bash 提示符

简介


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

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

我们将使用 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,那么您已经设置好了。

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

sudo nano /etc/passwd

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

查看当前值


首先,让我们探索已经在我们的配置文件中定义 Bash 提示的内容。

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

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

用户名@主机名: 当前目录$


请注意末尾的 $。这表示 shell 是普通用户 shell。对于 root 用户,这将被替换为 #,以区分并提醒您正在使用提升的特权。

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

echo \

在反斜杠后直接按回车键以查看提示。在 Ubuntu 中,默认值为 >

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

在 Ubuntu 12.04 的此文件中,我们可以找到类似以下部分:

# 如果终端具有此功能,则取消注释以获得彩色提示;默认情况下关闭以不分散用户的注意力:终端窗口的焦点应该放在命令的输出上,而不是提示上
# force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # 我们有颜色支持;假设它符合 Ecma-48(ISO/IEC-6429)的规范。(缺乏此类支持非常罕见,这种情况往往支持 setf 而不是 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 的部分指示,如果您正在更改根环境中操作,提示将被修改以提醒您。您可能希望保持提示的这一部分不变,因为这是一个有用的功能。

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

\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     当前时间以 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),最后是普通用户的 “$” 和 root 用户的 “#”。

让我们退出 ~/.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[<span class="highlight">颜色信息</span>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 逻辑复制到下面,使其看起来像这样:

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

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

在第一个 PS1 赋值中,使用您的提示符的彩色版本。在第二个中,使用不带颜色的版本。

if [ "$color_prompt" = yes ]; then
    # PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    PS1=<span class="highlight">"</span>${debian_chroot:+($debian_chroot)}<span class="highlight">[\[\e[0;32m\]\u@\h, load: `cat /proc/loadavg | awk '{ print $1; }'`\[\e[00m\]] (\[\e[00;35m\]\d - \t\[\e[00m\])\n\w \$ "</span>
else
    # PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1=<span class="highlight">"</span>${debian_chroot:+($debian_chroot)}<span class="highlight">[\u@\h, load: `cat /proc/loadavg | awk '{ print $1; }'`] (\d - \t)\n\w \$ "</span>
fi
unset color_prompt force_color_prompt

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

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

结论


有许多不同的方法可以个性化您的配置。给某些项目着色可以使它们更加突出,并且可以帮助您在通过终端历史记录时定位最后一个提示符。

另一个流行的想法是为 root 用户提供特殊的提示符,以便对比提醒您的特权。发挥创造力,尝试找到对您来说在有用信息和混乱之间的平衡点。


目录
相关文章
|
7月前
|
Unix Linux
【Linux】详解信号的分类&&如何自定义信号的作用
【Linux】详解信号的分类&&如何自定义信号的作用
|
3月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
4月前
|
Linux 网络安全 开发工具
内核实验(二):自定义一个迷你Linux ARM系统,基于Kernel v5.15.102, Busybox,Qemu
本文介绍了如何基于Linux Kernel 5.15.102版本和BusyBox创建一个自定义的迷你Linux ARM系统,并使用QEMU进行启动和调试,包括内核和BusyBox的编译配置、根文件系统的制作以及运行QEMU时的命令和参数设置。
314 0
内核实验(二):自定义一个迷你Linux ARM系统,基于Kernel v5.15.102, Busybox,Qemu
|
4月前
|
Unix Shell Linux
在Linux中,什么是 BASH?
在Linux中,什么是 BASH?
|
5月前
|
存储 Shell Linux
Linux|创建和使用 Bash 别名
Linux|创建和使用 Bash 别名
57 6
|
4月前
|
Shell Linux
在Linux中,哪⼀个bash内置命令能够进行数学运算?
在Linux中,哪⼀个bash内置命令能够进行数学运算?
|
4月前
|
缓存 Shell Linux
在Linux中,bash shell 中的 hash 命令有什么作用?
在Linux中,bash shell 中的 hash 命令有什么作用?
|
4月前
|
域名解析 缓存 负载均衡
在Linux中,自定义解析域名的时候,可以编辑哪个⽂件?是否可以⼀个ip对应多个域名?是否⼀个域名对应多个ip?
在Linux中,自定义解析域名的时候,可以编辑哪个⽂件?是否可以⼀个ip对应多个域名?是否⼀个域名对应多个ip?
|
4月前
|
人工智能 物联网 Shell
在Linux中,BASH 和 DOS之间的区别是什么?
在Linux中,BASH 和 DOS之间的区别是什么?
|
4月前
|
Unix Shell Linux
在Linux中,什么是Bash脚本,并且如何使用它。
在Linux中,什么是Bash脚本,并且如何使用它。