为终端加上 ASCII 横幅:bash、zsh、fish、PowerShell 和 SSH 登录
用带引号的 heredoc 或文件保留反斜杠,只在交互式 shell 中打印,scp 才不会出问题。
每次打开终端都看到写着自己名字或机器名的横幅,既有趣,又能一眼看出正在操作哪台电脑。本指南介绍如何把在 lab.ascii 制作的横幅放进 shell 的启动文件。
示例使用 Small 字体的“DEV”。它包含反斜杠(\),一旦被破坏马上就能看出来。
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
先了解两件事
保留反斜杠
如果用 echo "..." 打印横幅,shell 会把 \ 和 $ 当作特殊字符,字符画的一部分可能会消失或改变。请改用下面任一方法:
- 带引号的 heredoc:像
cat <<'EOF'这样给结束标记加上引号,shell 就会按原样打印其中的内容。 - 文件:用 TXT 按钮保存结果,再用
cat打印。这样任何字符都不需要转义。
只在交互式 shell 中打印
scp、rsync 和 sftp 会在远程机器上启动 shell,而这个 shell 可能会读取你的启动文件。如果此时打印横幅,文件传输可能会失败。请只在交互式 shell(也就是人打开的 shell)中打印横幅。
bash:~/.bashrc
在 ~/.bashrc 末尾加上:
if [[ $- == *i* ]]; then
cat <<'EOF'
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
EOF
fi
- 如果
$-中包含i,说明是交互式 shell。 - 结尾的
EOF必须从行首开始。前面有空格的话,bash 无法识别。
如果你把 TXT 文件保存为 ~/.banner.txt,一行就够了:
[[ $- == *i* && -r ~/.banner.txt ]] && cat ~/.banner.txt
macOS 的默认 shell 是 zsh,在 Mac 上请使用下面的 zsh 部分。
zsh:~/.zshrc
zsh 只在交互式 shell 中读取 ~/.zshrc,所以不需要额外判断。同样的 heredoc 就能用:
cat <<'EOF'
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
EOF
如果你使用 Powerlevel10k 的 instant prompt,启动时可能会出现关于控制台输出的警告。请把横幅代码移到 ~/.zshrc 开头 instant prompt 代码块的上方。
fish:fish_greeting
fish 启动时会运行 fish_greeting 函数来显示问候语。自己定义这个函数,横幅就会取代默认消息。把下面的内容写进 ~/.config/fish/config.fish:
function fish_greeting
cat ~/.banner.txt
end
fish 的单引号字符串会把 \\ 变成一个 \,所以打印文件比把横幅粘贴进字符串更安全。
加上颜色
在横幅前输出 ANSI 颜色代码,在后面输出重置代码。在 bash 或 zsh 中:
printf '\033[36m' # cyan
cat ~/.banner.txt
printf '\033[0m' # back to normal
| 代码 | 颜色 |
|---|---|
\033[31m |
红 |
\033[32m |
绿 |
\033[33m |
黄 |
\033[35m |
品红 |
\033[36m |
青 |
\033[1m |
粗体 |
如果忘了最后的 \033[0m,之后输入的所有文字都会一直带着颜色。
PowerShell:$PROFILE
PowerShell 启动时会运行 $PROFILE 所指的文件。如果文件还不存在,先创建它并用记事本打开:
if (!(Test-Path $PROFILE)) { New-Item -Path $PROFILE -ItemType File -Force }
notepad $PROFILE
加入以下内容并保存:
$banner = @'
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
'@
Write-Host $banner -ForegroundColor Cyan
@'和'@之间的内容不会被改动。结尾的'@必须从行首开始。- 如果新窗口提示“此系统上禁止运行脚本”,请为当前用户修改执行策略:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned。 - 包含
█ ═等方块字符或非拉丁文字的横幅,在 Windows PowerShell 5.1 中可能会乱。请在记事本中把配置文件保存为 UTF-8(带 BOM),或使用 PowerShell 7。
SSH 登录画面:/etc/motd
在 Linux 服务器上,/etc/motd 中的文字会在每次 SSH 登录时显示给所有连接的人。
sudo nano /etc/motd
粘贴横幅并保存,下次登录时就会显示。把服务器名放进横幅,就不容易把生产环境和测试环境搞混。你无法知道每个人使用什么终端,所以请选择 Standard、Slant、Small 等 ASCII 字体,而不是方块字符。Ubuntu 还会显示 /etc/update-motd.d/ 中脚本生成的消息。
在你自己的 CLI 工具中
用 Python 或 Node.js 编写的工具也遵循同样的规则:输出交给文件或其他程序时,不要打印横幅。
import sys
BANNER = r"""
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
"""
if sys.stdout.isatty():
print(BANNER)
const banner = String.raw`
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
`;
if (process.stdout.isTTY) console.log(banner);
字符串转义的更多细节,请参见 README 横幅指南。
哪种字体最合适?
终端通常是 80 列宽,很多人还会把窗口一分为二,所以 60 列以内的横幅几乎哪里都放得下。名字较长时,请选择 Small、Small Slant 等较窄的字体。可以在如何选择 FIGlet 字体中比较宽度。
安装
figlet程序后,可以用figlet -f slant "$(hostname)"之类的命令在启动时绘制横幅。不过每台机器都需要安装,未随附的字体还得另外下载。直接粘贴做好的横幅则完全不需要安装。