定制 Linux 终端登录消息

使用 SSH 登录服务器的时候,会有欢迎信息,那么咱就想能不能给他整好看一点呢?

比如这样?

一个自定义的 motd 消息

通过 Linux 的 motd(Message of the Day)可以很方便的修改登录信息,下面就动手。

本文均以 Debian 系统为例,其他发行版可能略有出入,请自行查证。

motd 消息组成

以 Debian 为例,默认的登录消息是这样的,下面就先来看看这玩意是怎么生成的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Linux HOSTNAME 5.10.0-12-amd64 #1 SMP Debian 5.10.103-1 (2022-03-07) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have no mail.
Last login: Sat Jan  6 17:48:05 2024 from 1.1.1.1

拆解

  1. 进入 /etc/update-motd.d 目录,可以看到一个默认的脚本,可以看下它的内容:

    1
    2
    3
    
    cd /etc/update-motd.d
    ls
    cat 10-uname

    发现是一个标准的 Shell 脚本:

    1
    2
    
    #!/bin/sh
    uname -snrvm

    运行一下 uname -snrvm,就是登录消息的第一部分:

    Linux LH-Shanghai 5.10.0-12-amd64 #1 SMP Debian 5.10.103-1 (2022-03-07) x 86_64

    /etc/update-motd.d 目录下的脚本都应该是数字开头的,会根据从小到大的顺序依次执行,打印 motd 消息。

  2. cat /etc/motd 直接查看 /etc/motd 的内容,会发现我们得到了第二部分,这就是 Debian 默认的 motd 消息,纯文本格式。

    The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.

  3. 最后一部分是 Last Login 消息,是 SSH 打印的,如果想要禁用,可以在 /etc/ssh/sshd_config 中把 #PrintLastLog yes 改成 PrintLastLog no

设置 motd

拆解完 motd 的构成,就可以很方便的来定制自己想要的消息了。基本思路就是在 /etc/update-motd.d 中创建自己的脚本,如果想要去掉 Debian 默认的版权声明,就干掉 /etc/motd 里的内容。

举个🌰:

1
2
3
4
5
sudo -i # 先切换成 root 用户

cd /etc/update-motd.d
touch 00-banner # 创建一个脚本,数字越小消息越靠前
chmod +x 00-banner # 赋予可执行权限

vim 00-banner 编辑它,填入以下内容:

1
2
3
#!/bin/sh
echo "Hello World"
echo "This is a motd message!"

注销重新登录,你就得到了一个最简单的文本消息。

但是,仅仅这样显然是不够好看的,那咱们就来整点字符画。

来点字符画

使用 toilet 生成字符画

咱也不知道为啥这工具叫「马桶」🚽

可以用 toiletfiglet 来比较方便的生成字符画,还可以添加颜色和一些效果,例如下图:

toilet

安装这两个工具,然后就可以使用了:

1
2
sudo apt-get install toilet figlet
toilet "Hello World"

toilet 可以使用 -f 来指定字体,使用 -F 来指定样式。 所有可用的字体可以用 figlist 来查看,可用的样式可以用 toilet -F list 来查看。例如: -F matal 可以添加金属色效果,-F gay 可以添加彩虹效果,-F border 可以添加一个边框。

下面行脚本可以输出所有字体的预览,帮你快速选择一个字体:

1
for font in banner big block bubble digital ivrit lean mini mnemonic script shadow slant small smscript smshadow smslant standard term; do echo "Font: $font"; toilet -f $font "Hello World"; done

确定好样式之后,像上面一样,创建一个脚本,然后把命令填进去,例如:

1
2
#!/bin/sh
toilet -f block -F gay Phoenix

生成固定字符画

toilet 好用是好用,就是可用的字体比较少,如果想要更多更多的样式,可以用 这个网站 来自己生成字符画,可选的字体非常多,可以点击 Test All 来测试所有的字体。

patorjk

复制生成的字符画,再像上文一样创建一个脚本,把内容填进去,并用单引号包裹起来,在最前面加上 echo 命令,比如:

1
2
3
4
5
6
7
8
#!/bin/sh
echo '  _____   ____  ____  ____  _____  ____  ____  '
echo ' |_   _| |_  _||_  _||_   \|_   _||_  _||_  _| '
echo '   | |     \ \  / /    |   \ | |    \ \  / /   '
echo '   | |   _  \ \/ /     | |\ \| |     > `'\'' <    '
echo '  _| |__/ | _|  |_    _| |_\   |_  _/ /'\''`\ \_ '
echo ' |________||______|  |_____|\____||____||____| '
echo '                                               '

就得到了自己想要的字符画了。注意,有些特殊字符是需要转义的,比如我上面的 '\'',就是为了显示 ' 字符。 当然如果觉得比较麻烦,也可以直接创建一个普通的文本文件,把字符画原封不动的填进去,然后在脚本里用 cat 路径 去直接显示文本内容,是一个蛮不错的选择。

给点颜色看看

如果觉得黑底白字太单调了,那就整点颜色看看。下面的示例脚本显示了一个橙色的字符画:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/sh
normal='\e[37m'
color='\e[38;5;202m'
printf "${color}"
echo '  _____   ____  ____  ____  _____  ____  ____  '
echo ' |_   _| |_  _||_  _||_   \|_   _||_  _||_  _| '
echo '   | |     \ \  / /    |   \ | |    \ \  / /   '
echo '   | |   _  \ \/ /     | |\ \| |     > `'\'' <    '
echo '  _| |__/ | _|  |_    _| |_\   |_  _/ /'\''`\ \_ '
echo ' |________||______|  |_____|\____||____||____| '
echo '                                               '
printf "${normal}"

终端可以用 ANSI 颜色代码来给改变颜色,现代终端一般至少支持 xterm-256color 也就是 256 色。当谈到终端中的颜色时,前景色指的是字符的颜色,而背景色则是字符后面的颜色。

在上面的脚本中,为了设置前景色,咱使用了 \e[38;5;色号m 这样的格式,其中 色号 是指特定的颜色代码。例如,\e[38;5;202m 就是设置前景色为橙色。同样,背景色的设置则使用 \e[48;5;色号m 的格式。例如,要将背景色设置为浅蓝色(色号 117),可以使用 \e[48;5;117m

具体的颜色代码可以在 256 Colors - Cheat Sheet - Xterm, HEX, RGB, HSL | DITig 这个网站查看,它提供了一个完整的 256 色 ANSI 颜色代码表, Xterm Number 就是我们要找的色号。

打印完特殊颜色的字符串,记得用 ${normal} 来恢复默认的白色,不然就全都是彩色的了。

抄作业?

原理介绍完了,大家已经可以动手定制自己的 motd 消息了。文章开头是我设置的登录消息,除了固定的字符串,还打印了系统的一些基本消息,下面可以直接抄作业~

分别创建 00-banner01-info,然后填入以下内容,用 chmod +x 00-banner 01-info 添加可执行权限,并干掉系统默认的脚本和 /etc/motd 里的内容,重新登录就得到了本文头图的登录消息了~

00-banner 脚本:

1
2
#!/bin/sh
toilet -f ivrit -F gay -F border -W Pavo

01-info 脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

# 颜色定义
RED='\033[31m'
BOLD='\033[1m'
ITALIC='\033[3m'
NORMAL='\033[0m'

# 获取信息
OS_INFO=$(echo "$(lsb_release -d | cut -f2) $(uname -m)")
KERNEL=$(uname -r)
HOSTNAME=$(uname -n)
USERNAME=$(who | awk '{print $1}' | sort | uniq)
UPTIME=$(uptime -p)
LOAD=$(cat /proc/loadavg | awk '{print $1" "$2" "$3}')
MEMORY=$(free -m | awk '/Mem:/ {print $3"MiB / "$2"MiB"}')
DATETIME=$(date)

# 定义信息内容
titles=("OS" "Kernel" "Hostname" "Current User" "Uptime" "Load Average" "Memory Usage" "Date & Time")
contents=("$OS_INFO" "$KERNEL" "$HOSTNAME" "$USERNAME" "$UPTIME" "$LOAD" "$MEMORY" "$DATETIME")

# 打印信息
toilet -f term -F metal -- "---------------------------------------------"
echo -e " ${BOLD}${ITALIC}System Information:${NORMAL}"
for i in ${!titles[@]}; do
    echo -e " ${RED}${ITALIC}${BOLD}  ${titles[$i]}:${NORMAL} ${contents[$i]}"
done
toilet -f term -F metal -- "---------------------------------------------
0%