皆サーン、間違ってssh先の本番マシンを落としたことはアリマスカー? 私はアリマース!
ssh先に応じてイロイロ色を変更する、という安全策は古今東西たくさんありますね。
プロンプト、iterm2のprofileなど...
https://qiita.com/search?q=ssh+色
そんなn番煎じですが、今回はtmuxの機能を用いて背景色を変更し、ついでに昼と夜で別の色にします(いわゆるダークモード対応)。
概要
- ノートパソコンを地下鉄や新幹線といった場所で使っていても、安定して遠隔マシンを操作
- 遠隔マシンから更に別のマシンにsshしたとき、背景色を変える
- 昼と夜では別の色
hostB, hostC, hostD, hostE... で背景色を変えます。
もちろんhostAの中でtmuxを使っている時も有効なお話です。
レシピ
- フルカラー表示可能なターミナル
- 今回はmacos iterm2としていますが、ghosttyやその他端末、OSでも適用可能です
- mosh
- etでは新幹線車内など不安定な回線では使いにくいため、古式ゆかしくudpベースのmoshを使います
- iterm2のprofile切り替えOSCはmoshを通りませんので、遠隔側で色を変更します
- tmux
- gnu screenでもいいのですが、ここはモダンにtmuxを使います
- sunwait
- iterm2のprofileを切り替える場合、昼夜のライトテーマ、ダークテーマの自動切り替えが可能となります
- しかし(遠隔の)tmuxで背景色を設定する場合はその機能が使えません
- そこで、tmuxが動いているホストの中で昼夜の判定をします
- iterm2が動いているマシンと物理的に距離がある場合は時差が発生しますので海外出張の時は緯度経度を端末から渡す操作が必要となることでしょう
- tmuxと同じマシンに入れる必要があります (hostAでtmuxなら、hostAに入れる)
では以下、個別に...
mosh
「mosh捨ててetだ!」という声もありますが、列車内など安定しない回線での利便性ではmoshに一日の長があります。
etは復旧に10秒程かかりますが、moshは1秒も経たずに復旧してくれます。
vpnの復旧の時間と併せても数秒でプロンプトと戯れることができます。
そのmoshですが、iterm2のOSC 1337のprofile変更を通してくれません。
etは通してくれます。
moshでも通すようにするパッチもありますが、メンテナンスされていないようですので今回はtmux側で色を変更することにします。
sunwait
緯度・経度から日の出・日没時刻を計算してくれます。
make一発。
macosの自動ダークモード・ライトモード切り替え時刻とは微妙に一致しない1こともありますが、そこはご愛嬌。
tmux
24bitカラー対応
もう既に設定されている方が大半かとは存じますが、24bit色を表示可能にしておきます。
set -g default-terminal "xterm-256color"
set -ga terminal-overrides ",xterm-256color:Tc"
無事16M色になったかの確認はこちらで。
curl -s https://raw.githubusercontent.com/JohnMorales/dotfiles/master/colors/24-bit-color.sh | bash
windowタイトル設定
こちらも多くの方はすでにプロンプトと併せて設定されているかとは思いますが、sshしたときにwindowタイトルをホスト名を含むものにします。
今回は背景色の記事ですが、背景色設定スクリプトではwindowタイトルから色を決定していますので、windowタイトルも変更します。
sshをラップするshell functionまたはスクリプト等を用意し、ssh前後で設定します。 tmuxのwindowタイトルの変更は、
echo -n -e "\033kタイトル文字列\033\\"
となります。
tmuxのwindowタイトルから、tmuxの背景色を設定するスクリプト
window単位で変えます。
#!/bin/sh
# tmuxのwindow_nameに基づいて、背景色を変える
target="$1"
if [[ "$target" ]]; then
targetarg="-t $target"
fi
windowname=$(tmux display $targetarg -p '#{window_name}')
light="default"
dark="default"
case "$windowname" in
*${HOSTNAME}:*)
# 同じならdefault
light="default"
dark="default"
;;
*hoge:*)
# solarized
light="#fcf6e2"
dark="#02232b"
;;
*fuga:*)
# solarizedを少し緑気味に
light="#f6fcf6"
dark="#022b23"
;;
*piyo:*)
# solarizedを少し赤気味に
light="#fef6fe"
dark="#2b0223"
;;
esac
# 東京の緯度・経度
if sunwait report 35.7N 139.7E | grep -q "It is: Day"; then
tmux set $targetarg window-active-style "bg=$light"
else
tmux set $targetarg window-active-style "bg=$dark"
fi
こんな感じのスクリプトを用意し、windowタイトル変更後に呼びます。
長時間ssh対応
このままですと、昼間にsshすると日没後もlightなままになります。
bg=default
の場合はiterm2の設定で昼夜テーマが反映されますが、tmuxで明示的設定をしている場合はテーマを上書きしてしまいます。
- tmuxの適当なhookを使って変更
- 例えばウィンドウを切り替える度に更新するとしたら、
set-hook -g session-window-changed 'run-shell "tmux-change-color.sh"'
- 例えばウィンドウを切り替える度に更新するとしたら、
- 手作業で変更する
- tmuxの
bind-key
やdisplay-menu
の中でrun-shell
する
- tmuxの
- sshラッパーの中で時限爆弾を設置
でもいいのですが、日の出・日没ごとに全windowを一括で更新するスクリプトを裏で動かしておくか、
#!/bin/sh
while sunwait wait 35.7N 139.7E; do
tmux list-windows -F '#{window_id}' | while read -r windowid ; do
change-tmux-color.sh $windowid
done
done
cronで毎日12時と24時に sunwait wait ; tmux list-windows ...
と実行します(白夜・極夜がある場合を除く)。
なお、sunwait waitした直後にsunwait reportをするとズレることがありますので注意。
ちなみに、遠隔のtmuxではなく手元(hostA)で動作するtmuxかつmacosであれば、こちらのpluginのような方法で変更できます。
免責事項😆
本記事の設定が正しく動作するか否かに関わらず、利用者が意図しない遠隔マシンを吹っ飛ばしたことによる損害に対して本記事の筆者は何ら責任を負いません。
-
緯度経度を高精度に指定すれば一致するのかもしれません。薄明の扱いかもしれません。 ↩