開発

ターミナルにアスキーバナーを表示する:bash・zsh・fish・PowerShell・SSH ログイン

クォート付きのヒアドキュメントかファイルでバックスラッシュを守り、対話シェルでだけ表示して scp を壊さないようにしましょう。

最終更新:

ターミナルを開くたびに自分の名前やマシンの名前のバナーが出ると楽しいうえに、どのコンピューターを操作しているのかがひと目でわかります。このガイドでは、lab.ascii で作ったバナーをシェルの起動ファイルに入れる方法を紹介します。

例では Small フォントの「DEV」を使います。バックスラッシュ(\)を含むので、崩れたらすぐにわかります。

 ___  _____   __
|   \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/

先に知っておきたい2つのこと

バックスラッシュを守る

echo "..." でバナーを表示すると、シェルが \ や $ を特殊な文字として扱うため、アートの一部が消えたり変わったりします。代わりに次のどちらかを使いましょう。

  • クォート付きのヒアドキュメント: cat <<'EOF' のように終わりの目印をクォートで囲むと、シェルは中身を書いたとおりに表示します。
  • ファイル: TXT ボタンで結果を保存し、cat で表示します。エスケープが必要な文字はありません。

対話シェルでだけ表示する

scp・rsync・sftp はリモートのマシンでシェルを起動し、そのシェルが起動ファイルを読むことがあります。そのときにバナーを表示すると、ファイル転送が失敗することがあります。バナーは人が開いた対話シェルでだけ表示しましょう。

bash: ~/.bashrc

~/.bashrc の最後に次を追加します。

if [[ $- == *i* ]]; then
cat <<'EOF'
 ___  _____   __
|   \| __\ \ / /
| |) | _| \ V /
|___/|___| \_/
EOF
fi
  • $- に i が含まれていれば対話シェルです。
  • 終わりの EOF は行頭から始めてください。前にスペースがあると bash が認識しません。

TXT ファイルを ~/.banner.txt として保存したなら、1行で済みます。

[[ $- == *i* && -r ~/.banner.txt ]] && cat ~/.banner.txt

macOS の標準シェルは zsh なので、Mac では下の zsh の項目を使ってください。

zsh: ~/.zshrc

zsh は対話シェルでだけ ~/.zshrc を読むので、追加の確認はいりません。同じヒアドキュメントが使えます。

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 のシングルクォート文字列は \\ を1つの \ に変えるので、バナーを文字列に貼るよりファイルを表示するほうが安全です。

色を付ける

バナーの前に 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)" のようにして起動時にバナーを描くこともできます。ただし、すべてのマシンにインストールが必要で、同梱されていないフォントは別にダウンロードしなければなりません。できあがったバナーを貼るだけなら、インストールはいりません。