paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

kittyでLXC containerを触るとバックスペースが効かない問題

ubuntuデスクトップ環境をKDEに変更してからterminalもkittyに変更したのですが、container環境でバックスペースが効かないという問題に出くわしました。
正確には効くのですが、文字が削除されず画面に残ってしまうという事象です。

ターミナルを変えれば解決するのですが、メインのものを使い続けたいのでこの問題に決着を付けたいと思います。

事象

今回はLXC環境のdebianで試します。

root@debian:~# ls /etc
adduser.conf        gai.conf       locale.gen      profile    shells
alternatives        group        localtime       profile.d    skel
apt         group-       login.defs      protocols    ssh
bash.bashrc     gshadow        logrotate.d     rc0.d      subgid
bindresvport.blacklist  gshadow-       machine-id      rc1.d      subuid
binfmt.d        gss      mke2fs.conf     rc2.d    sysctl.conf
cron.d          host.conf      modules-load.d  rc3.d      sysctl.d
cron.daily      hostname       motd      rc4.d    systemd
dbus-1          hosts        mtab        rc5.d    terminfo
debconf.conf        init.d       netconfig       rc6.d    timezone
debian_version      iproute2       network       rcS.d    tmpfiles.d
default         issue        networks        resolv.conf  update-motd.d
deluser.conf        issue.net      nsswitch.conf   rmt    vim
dhcp            kernel       opt         rpc      xattr.conf
dpkg            ld.so.cache    os-release      security     xdg
e2scrub.conf        ld.so.conf     pam.conf        selinux
environment     ld.so.conf.d   pam.d         services
ethertypes      libaudit.conf  passwd        shadow
fstab           locale.alias   passwd-      shadow-

3文字削除してEnterを押すと/のディレクトリが表示されます。
画面上には残ってますね。

root@debian:~# ls /etc   
bin   dev  home  lib64  mnt  proc  run  srv  tmp  var
boot  etc  lib  media   opt  root  sbin  sys  usr

debianにはrogue cloneをインストールしていてたまに遊ぶのですが、これもエラーで遊べません。
これは困った。

root@debian:~# /usr/games/rogue 
Hello root, just a moment while I dig the dungeon...Error opening terminal: xterm-kitty.

困ったらググる

linux backspace できない」等の検索だと大体sttyの記事が出てきてeraseとの関連付けで終わりです。
ubuntuとコンテナではsttyの差分が無いことは確認済みなので困った。

「lxc container kitty」で検索すると似た記事が出てきました。

xterm-kitty and Containers · Discussion #4104 · kovidgoyal/kitty · GitHub

これはkittyでdocker containerを操作した際の内容ですが、lxcのヒントになるかもしれません。
その中でこんな文字が、

Just set TERM and make sure the corresponding terminfo file exists, there is nothing special about it. Maybe you need to check your OS and shell inside the container.

terminfoとは

terminalの情報が格納されているデータベースの様です。
binaryファイルなので中身は確認できませんでした。

masashi@PC-ubuntu:~$ locate $TERM
/usr/share/terminfo/x/xterm-kitty
masashi@PC-ubuntu:~$ file /usr/share/terminfo/x/xterm-kitty
/usr/share/terminfo/x/xterm-kitty: Compiled terminfo entry "xterm-kitty"
masashi@PC-ubuntu:~$ less /usr/share/terminfo/x/xterm-kitty
"/usr/share/terminfo/x/xterm-kitty" may be a binary file.  See it anyway? 

manを見ると中身はinfocmpコマンドで見れるようです。

masashi@PC-ubuntu:~$ infocmp $TERM
#  Reconstructed via infocmp from file: /usr/share/terminfo/x/xterm-kitty
xterm-kitty|KovIdTTY,
    am, ccc, hs, km, mc5i, mir, msgr, npc, xenl,
    colors#0x100, cols#80, it#8, lines#24, pairs#0x7fff,
    acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
    bel=^G, bold=\E[1m, cbt=\E[Z, civis=\E[?25l,

...

コンテナで確認するとkitty用のファイルが無い。
まあ標準のターミナルではないのでしょうがないです。

root@debian:~# echo $TERM
xterm-kitty
root@debian:~# infocmp $TERM
infocmp: couldn't open terminfo file /usr/share/terminfo/x/xterm-kitty.

対策

ターミナル用のファイルが無いのでホストや他のターミナルと挙動が違ったということですね。
どちらかで解決できそうです。

  1. コンテナ環境にkitty用のファイルを作成する
  2. コンテナを操作するときは環境変数を変えてxtermとして使う

デプロイ済みのインスタンスを考えると変数変えて済むなら2番で終わらせたいところです。
試しにTERM変数を変えてみると...

root@debian:~# export TERM=xterm
root@debian:~# echo $TERM
xterm
root@debian:~# echo

root@debian:~#

ちゃんとバックスペース効きますね。 (ログだけだと何やってるか分かりにくいですが)

こんな簡単なことで良かったんだ。
GNOME時代に使っていたのはgnome terminalでxterm環境だったので動くと思います。

コンテナ内で都度設定は面等なのでログイン時に指定できるようにします。

Flags:
      --cwd                    Directory to run the command in (default /root)
  -n, --disable-stdin          Disable stdin (reads from /dev/null)
      --env                    Environment variable to set (e.g. HOME=/home/foo)

lxcのhelpを見たら--envでいけそうですね。

masashi@PC-ubuntu:~$ lxc exec debian --env 'TERM=xterm' -- /bin/bash
root@debian:~# echo $TERM
xterm

OK。変わってます。
rougeをプレイしてみます。

root@debian:~# /usr/games/rogue 

プレイできました!
またプレイできて嬉しいですw

久しぶりにやったら3階でやられてしまいました。

背景もうっすら透けながらプレイできてかっこいいですね。

まとめ

今回の問題を解決するためにterminal周りについて色々調べました。
結局環境変数を変えるだけで済んでしまったので調べた結果をまとめるまでもありませんでした。

文字が残ってしまう原因まで突き止めたかったのですが、とりあえず正常動作したので調査は一旦ここまでにします。
container内はkittyのterminfoが無かったのでどこ見て動いていたのかもわからないままですが、container内ターミナルのバックスペース周りのエスケープコードがおかしかったという事ですよね。

Linuxばかり触る私の様な環境だとterminfoを意識したりいじる機会は少ないかもしれません。
昔のコンピュータとかはterminal環境がたくさんあったと思うので古いOSを触る機会があれば今回の件を思い出したいと思います。