Add an ASCII Banner to Your Terminal: bash, zsh, fish, PowerShell, and SSH Login
Use a quoted heredoc or a file so backslashes survive, and print only in interactive shells so scp keeps working.
A banner with your name or the machine’s name each time you open a terminal is a nice touch, and it tells you at a glance which computer you are on. This guide shows how to put a banner made on lab.ascii into your shell’s startup files.
The examples use “DEV” in the Small font. It contains backslashes (\), so you will see right away if it gets mangled.
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
Two things to know first
Keep the backslashes
If you print a banner with echo "...", the shell treats \ and $ as special characters, so parts of the art can disappear or change. Use one of these instead:
- A quoted heredoc: quote the end marker, as in
cat <<'EOF', and the shell prints everything inside exactly as written. - A file: save the result with the TXT button and print it with
cat. Then no character needs escaping.
Print only in interactive shells
scp, rsync, and sftp start a shell on the remote machine, and that shell may read your startup files. If a banner is printed then, file transfers can fail. Print the banner only in interactive shells, the ones a person opened.
bash: ~/.bashrc
Add this to the end of ~/.bashrc:
if [[ $- == *i* ]]; then
cat <<'EOF'
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
EOF
fi
- If
$-containsi, the shell is interactive. - The closing
EOFmust start at the beginning of the line. With spaces in front, bash will not recognize it.
If you saved the TXT file as ~/.banner.txt, one line is enough:
[[ $- == *i* && -r ~/.banner.txt ]] && cat ~/.banner.txt
The default shell on macOS is zsh, so on a Mac use the zsh section below.
zsh: ~/.zshrc
zsh reads ~/.zshrc only in interactive shells, so no extra check is needed. The same heredoc works:
cat <<'EOF'
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
EOF
If you use Powerlevel10k with instant prompt, you may get a warning about console output during startup. Move the banner code above the instant prompt block at the top of ~/.zshrc.
fish: fish_greeting
fish runs the fish_greeting function at startup to show its greeting. Define your own and the banner replaces the default message. Put this in ~/.config/fish/config.fish:
function fish_greeting
cat ~/.banner.txt
end
Single-quoted strings in fish turn \\ into a single \, so printing a file is safer than pasting the banner into a string.
Adding color
Print an ANSI color code before the banner and a reset code after it. In bash or zsh:
printf '\033[36m' # cyan
cat ~/.banner.txt
printf '\033[0m' # back to normal
| Code | Color |
|---|---|
\033[31m |
Red |
\033[32m |
Green |
\033[33m |
Yellow |
\033[35m |
Magenta |
\033[36m |
Cyan |
\033[1m |
Bold |
If you forget the final \033[0m, everything you type afterwards stays colored.
PowerShell: $PROFILE
PowerShell runs the file at $PROFILE when it starts. If the file does not exist yet, create it and open it in Notepad:
if (!(Test-Path $PROFILE)) { New-Item -Path $PROFILE -ItemType File -Force }
notepad $PROFILE
Add this and save:
$banner = @'
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
'@
Write-Host $banner -ForegroundColor Cyan
- Nothing between
@'and'@is changed. The closing'@must start at the beginning of the line. - If a new window says “running scripts is disabled on this system”, change the execution policy for your user:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned. - Block-character fonts such as ANSI Shadow can break in Windows PowerShell 5.1. Save the profile as UTF-8 with BOM in Notepad, or use PowerShell 7.
SSH login screen: /etc/motd
On a Linux server, the text in /etc/motd is shown at every SSH login, to everyone who connects.
sudo nano /etc/motd
Paste the banner, save, and it appears from the next login. Putting the server’s name in the banner makes it hard to confuse production with staging. You cannot know what terminal each person uses, so pick an ASCII font such as Standard, Slant, or Small rather than block characters. Ubuntu also shows messages generated by the scripts in /etc/update-motd.d/.
In your own CLI tool
The same rule applies to a tool you write in Python or Node.js: do not print the banner when the output goes to a file or another program.
import sys
BANNER = r"""
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
"""
if sys.stdout.isatty():
print(BANNER)
const banner = String.raw`
___ _____ __
| \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
`;
if (process.stdout.isTTY) console.log(banner);
The README banner guide covers string escaping in more detail.
Which font works best?
Terminals are usually 80 columns wide, and many people split their window in half, so a banner of 60 columns or less fits almost everywhere. For long names, choose a narrow font such as Small or Small Slant. You can compare widths in How to choose a FIGlet font.
If you install the
figletprogram, you can draw a banner at startup with something likefiglet -f slant "$(hostname)". It has to be installed on every machine, though, and fonts such as ANSI Shadow need a separate download. Pasting a finished banner needs no installation at all.