某クラウドのサーバに、iTermで多段SSHログインしたら下記の事象に遭遇したのでメモ
事象
リモートのサーバにログインする
numbers
という、1から100までの数字が表示されたファイルをless
で表示する。
$ cat numbers | less
下記のような表示になる。ここまでは想定した動作。
そこから、ウィンドウサイズを変える。ちょっと大きくして、同じことをする。
$ cat numbers | less
すると表示がくずれる。
くずれる……。
原因
ローカルのウィンドウサイズの変更が、リモート側の端末デバイスまでうまく反映されていない模様。ウィンドウサイズが変更されると、リモートホストのカーネル1にもその情報を伝える必要があるが、できていない。多段SSHのために中継したサーバで損失しているのかも?このクラウド以外では発生しないため、特定のサーバ固有の問題っぽい。
そのためvim
やless
など、対話スクリーンを独自に開くソフトウェアはレイアウト崩れに見舞われてしまう。
$ stty size
と打つことで、端末デバイスが認識している端末の行数と列数が表示できる2が、端末エミュレータのウィンドウサイズを変更してもそれが変更されない。
ウィンドウサイズ変更前
14 x 62 を指している。
ウィンドウサイズ変更後
サイズが変わったにもかかわらず、同じ値である14 x 62 を指している。
解決方法
stty
コマンドで端末デバイスに適切な端末サイズを教えてあげれば、レイアウトは戻る。
$ stty rows <列数> cols <行数>
iTermの場合、ウィンドウサイズを変更しようとしてウィンドウの端をドラッグすると、入力できる文字の端末サイズを表示してくれるので、その値を入れる。
なおる。
TMUX Pluginを使う
いちいちstty
なんちゃらと入力するのも面倒だが、普段tmuxを使っている人には、もっと簡単な方法がある3。tmuxのウィンドウ、あるいはペインサイズをstty
コマンドの引数として渡して実行してやればレイアウトは戻るからだ。
<tmuxのprefix> + a
キーを入力するだけで、上記のstty rows <列数> cols <行数>
を入力してくれるtmuxのプラグインを作った。キーバインドは変更可能であるため活用されたし。導入方法は下記のリンクにあり。
Github: tmux-adtty
実行例
一番下のペインで開いているvi
のレイアウトが崩れてるため、一旦vi
を抜けて、<tmuxのprefix> + a
キーを入力。
すると、なおる(^_^)v
-
stty
の説明より。例えばstty rows
コマンドの説明として "tell the kernel that the terminal has N rows" とあり、カーネル側に端末の行数と列数を教えている模様。 http://man7.org/linux/man-pages/man1/stty.1.html ↩ -
bashでは
LINES
とCOLUMNS
という変数に行数と列数の情報が入る。 ↩ -
そもそも、リモート側に端末サイズが伝わるようにするのが理想的だが、大人の事情でできない人はここにあるような方法で頑張るしかない、のかもしれない。 ↩