注目の記事

[macOS] SSHログインしたときだけターミナルの背景色を変えたい (iTerm2)

2017.11.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

SSH で他所のサーバに接続したとき、ターミナルの背景色を変えたくなりませんか?

ぼくはなります。

正道(よくある方法)

iTerm2 にはプロファイルという機能があって、
予め作成しておくと、背景色以外にもいろいろと変更できます。

今回は扱いません。

邪道(趣味の領域)

そもそも何故こういうことをしたいと思ったかというと、
自分の手元だと思ってコマンド打ったら SSH でログインしたお客さまの環境だった、という事故を起こしたくないからです。

「お客さまの環境へログインする場合はこう」、と作業手順を変えるのが本来の姿ですが、
結局のところ思い違いによるミスは防げませんし、
結果として両方の環境を整備しなくてはならなくなり、手間が増え、設定のミスマッチによる事故を起こしたり、そもそも(あきっぽい自分の性格的に)きっと整備しなくなる・・・という恐れもありました。

ssh サーバ名と実行したら、すぐに背景色が変わって欲しい。ログアウトしたら元に戻って欲しい。

幸い iTerm2 には、コマンドラインから背景色を変更するエスケープシーケンスが独自拡張で実装されている ので、今回はこれを使いました。

色の指定は RGB の形式(各ケタそれぞれ16進数で 0〜f )で指定できるので、
例えば下記のようにすると、背景色が暗い赤になります(200 : Red=2, Green=0, Blue=0)。

echo -e '\033]1337;SetColors=bg=200\a'

実装 1

下記の内容のスクリプトを作成して、PATH の通っているところに置きました。

今回の場合 ~/bin/ssh-change-bg という名前で保存し、chmod +xしておきました。

#!/bin/bash

# Ctrl-C
trap 'echo -e "Interrupted.\033]1337;SetColors=bg=000\a"; exit;' INT

echo -ne '\033]1337;SetColors=bg=200\a' # to red
/usr/bin/ssh "$@"
echo -ne '\033]1337;SetColors=bg=000\a' # to black

4行目の trap は、Ctrl-C でスクリプトを強制終了したときでも背景色を元に戻すためのものです。

さらに alias コマンドで、sshと実行したときにこのスクリプトを呼び出すようにしておきます。

そうしておかないと、bash-completion が効かなくなってしまうのでその対策です。

alias ssh='~/bin/ssh-change-bg'

この一行は、.bash_profileなりに記述しておくとよいでしょう。

ちなみに、なぜいきなり ssh という名前でスクリプトを保存しないかというと、
Git 等内部から ssh コマンドを呼び出しているものがあるので、それらに影響を与えないようにするためです。

実際に使ってみた時の挙動はこうなります。

20171113_1

EC2 インスタンスに SSHログインすると、背景色が赤くなりました。

(あまりにどぎつい赤にするとかえって見にくいので、ほんのりと赤くしています)

20171113_2

ログアウトすると、また元の色(黒)に戻ります。

20171113_3

なお、色の指定は RGB あるいは RRGGBB 形式(各ケタそれぞれ16進数で 00〜ff )で指定できるので、ご自分の好みに変更するとよいでしょう。

もし何らかの理由で、このスクリプトを使わずに SSH ログインしたい場合は、下記のようにしてエイリアスを無効にできます。

$ \ssh (コマンドライン引数)

実装 2

これでも目的は十分達成なのですが、
どうせなら「特定のホストやユーザで接続する時だけ赤く、それ以外は黄色」としたくなったので、そのように実装しなおしました。

9行目の正規表現をそのまま egrep に渡してコマンドライン文字列をチェックしているだけなので、お使いの際には環境に合わせて修正して下さい。

この例だと、

  • bastion.example.com
  • ec2-user

どちらかがコマンドラインに含まれた場合に赤くなります。

#!/bin/bash

CMD_SSH=/usr/bin/ssh

BGCOLOR_NORMAL=000
BGCOLOR_WARNING=110
BGCOLOR_CAUTION=200

REGEXP_CAUTION_HOST='bastion.example.com|ec2-user'

# Ctrl-C
trap 'echo "Interrupted."; bg_color_normal; exit;' INT

# Change BG Color (iTerm2)
function bg_color_change(){
  echo -ne '\033]1337;SetColors=bg='$1'\a'
}

# Change BG Color back to normal (iTerm2)
function bg_color_normal(){
  bg_color_change $BGCOLOR_NORMAL
}

# bgcolor change
if egrep -q "$REGEXP_CAUTION_HOST" <(echo $*) 2>&1; then
  bg_color_change $BGCOLOR_CAUTION
else
  bg_color_change $BGCOLOR_WARNING
fi

# SSH Connect
echo "( $CMD_SSH $1 ...)" >&2
echo >&2
$CMD_SSH "$@"

# bgcolor back to normal
bg_color_normal

ちなみに

iTerm2 には Automatic Profile Switching という機能があって、説明だけみると今回やりたかったことが出来そうだったんだんですが、「接続先にも iTerm2 の Shell Integration がインストールされていること」という条件があって今ひとつ使いづらいものでした。

ssh コマンドをシェルスクリプトでラップする方法を使えば、例えば SSH 接続時だけ script コマンドを動かして自動的にターミナルログをファイルに保存するなどのことも出来ます。既存の SSH コマンドやターミナルに満足できない方は、是非ぼくのかんがえたさいきょうのたーみなる環境を模索してみて下さい。