以前の記事で
『WezTerm』 を使って Sixel プロトコルを使い、ターミナルに直接画像を表示させてみました。

合同会社タコスキングダム|蛸壺の技術ブログ
【シェルコマンド】weztermとlibsixelを使ってDebian&MacOSのターミナルで画像をそのまま表示してみる

「img2sixel」コマンドをDebian LinuxとMacOSを導入する手順



WezTermから利用できるターミナル画像描画プロトコルはこのSixel以外にも、
『iTerm2』『Kitty』 があり、これらを使ってWezTerm上への画像表示方法を簡単に比較させてみます。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

WezTerm組込のiTerm2プロトコルを使った画像描画



WezTermが問題なくインストールできて利用可能の状態ならば、デフォルトで利用できる
『iTerm2』 ベースの組込みサブコマンド・ 「imgcat」 からそのままターミナルに画像表示することができます。

            $ wezterm imgcat cat.jpg

        


826x677
合同会社タコスキングダム|蛸壺の技術ブログ


単純にターミナルに画像を直接表示したいだけであればWezTermをインストールするだけなので、他に悩む必要はありません。
ですが、現状WezTermに対応していないOSプラットフォームターゲットも多数あるため、そのような「非WezTerm環境」の下では、別の方法を考える必要があります。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

Kittyグラフィックプロトコルを利用する



iTerm2は基本的にmacOSユーザーを念頭にした技術ですので、Linuxなどの他のOSでも使えて、ターミナルに直接画像を表示できることで知られる
「Kitty」 を試してみます。
インストール手順としては以下のように公式で説明されている内容に従います。

参考|Install kitty

作業自体は簡単で、ターミナルから以下のインストーラースクリプトを実行します。

            $ curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin

        

これでKittyのバイナリ版がインストールされました。
なおバイナリは、macOSでは
/Applications/kitty.app 、Linuxでは ~/.local/kitty.app に置かれます。
Kittyをインストール後に起動するには、

            $ . ~/.local/kitty.app/bin/kitty

        

などとする必要があります。
毎回これで起動するのはちょっと面倒ですので、シンボリックリンクを貼ります。

            $ sudo ln -sf ~/.local/kitty.app/bin/kitty ~/.local/kitty.app/bin/kitten /usr/bin/

        

では、kittyおよびkittenコマンドが呼び出せるようになったので、早速WezTermからJPG画像を表示させてみましょう。

            $ kitty +kitten icat cat.jpg

        


934x693
合同会社タコスキングダム|蛸壺の技術ブログ


こちらも手元のDebian OS環境下では、WezTerm/iTerm2同様、上手くターミナルに直接画像を描画することができました。
なお、kitty/kittenのサブコマンド
icat のオブションは色々と設定できますが、詳細は以下のドキュメントをご覧ください。

参考|icat - Display images in the terminal
合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

Raspberry PiにFlatPakからWezTermをインストール(現状は失敗!)



基本的にデスクトップパソコンにDebian OSなどのメジャーなOSプラットフォームをインストールして利用できるならば、iTerm2/Kitty/Sixel/etc...のどのグラフィックプロトコルを用いてもさほど苦労することなく正常に動作するはずです。
最近の個人的な興味ごととして、ラズパイなどのシングルボードコンピューターにWezTermを導入し、SSH越しに画像を表示してみたい、ということが念頭ありました。
節の見出しから薄々ダメそうな予感は感じとっていただけるかと思いますが、ラズパイにWezTermをインストールするところから実験していきましょう。

FlatPakからラズパイにWezTermをインストールできる?



手始めに
『flatpak』 を使ってWezTermを簡単導入する方法から紹介します。
もしまだFlatPakを導入していない場合には、以下の簡易ガイドに従い、DebianOS等にFlatPakをインストールするところから始めてみましょう。

Debian Quick Setup - FlatPak

最近のDebianではプラグインを噛ます必要もなく、以下のコマンドだけで導入も一発OKです。

            $ sudo apt install flatpak
$ sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo

        

flatpakが使えるようになったら、WezTermをインストールしてみましょう。

            $ flatpak install flathub org.wezfurlong.wezterm

Note that the directories

'/var/lib/flatpak/exports/share'
'/home/*********/.local/share/flatpak/exports/share'

are not in the search path set by the XDG_DATA_DIRS environment variable, so
applications installed by Flatpak may not appear on your desktop until the
session is restarted.

Looking for matches…
error: Nothing matches org.wezfurlong.wezterm in remote flathub

        

うーん...失敗。
この時点ではインストールがコケた原因も良くわからないので、FlatPak周りのマニュアルを確認してみます。
少し気になっていたのは、
FlatPak公式 にはこんな文言で、

            Important note: As of March 2021, Raspberry Pi computers still ship with the 32-bit version of Raspberry Pi OS.
However Flathub started phasing out support for that architecture.
If you consider Flathub as an important source of applications, it is recommended to use Raspberry Pi OS 64-bit as newer applications are more likely to be available for that platform.

        

これから察するに、古いラズパイ用の32bitアーキテクチャには注意しないといけないようです。
そこで別のRaspberry PiにRaspberry Pi OS (64bit)をインストールし再チャレンジしてみます。

            $ flatpak install flathub org.wezfurlong.wezterm

Note that the directories 

'/var/lib/flatpak/exports/share'
'/home/**********/.local/share/flatpak/exports/share'

are not in the search path set by the XDG_DATA_DIRS environment variable, so
applications installed by Flatpak may not appear on your desktop until the
session is restarted.

Looking for matches?
error: Nothing matches org.wezfurlong.wezterm in remote flathub

        

うーん、症状が変わらず。
あまり拘っても仕方ないので、ここでFlatPakからの導入を諦め、サードパーティのレポジトリからaptインストールしてみます。

            $ curl -fsSL https://apt.fury.io/wez/gpg.key | sudo gpg --yes --dearmor -o /usr/share/keyrings/wezterm-fury.gpg

$ echo 'deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *' | sudo tee /etc/apt/sources.list.d/wezterm.list

$ sudo apt update
#...中略
N: Skipping acquire of configured file '*/binary-armhf/Packages' as repository 'https://apt.fury.io/wez * InRelease' doesn't support architecture 'armhf'
#...

$ sudo apt install wezterm
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package wezterm

        

なるほど、WezTermは
armhf アーキテクチャに対応していないみたいです。
そもそもまだRaspberry Piでサラリと利用できるようになってはいないようで、WezTermの直接導入は簡単ではなさそうです。
まぁ、
dpkg コマンドでマルチアーキテクチャを有効にすれば良いだけかもしれませんが、また更なる落とし穴が潜んでいてドツボに嵌るのも厭らしいので、この時点でラズパイへのWezTermの導入は一旦諦めます。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

Raspberry PiにKittyを導入しSSH越しに画像をターミナル表示させる



若干、当初甘く考えていたラスパイへのWezTermの導入の内容が尻切れトンボな話になりましたので、Kittyからターミナルに画像表示させてみましょう。
ラズパイ側へSSH接続し、
Kitty をバイナリインストールします。

            $ curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin
$ sudo ln -sf ~/.local/kitty.app/bin/kitty ~/.local/kitty.app/bin/kitten /usr/bin/

        

で、一見、Kittyのインストールが成功したかに見えました。

            $ kitten
-bash: /usr/bin/kitten: No such file or directory
$ kitty
-bash: /usr/bin/kitty: No such file or directory

        

実行ファイルの実体はあるのに、肝心の実行にはコケてしまいます。
少しこの実行ファイルの中身を詳しく確認していきます。

            $ file kitty
kitty: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=30223e137a4e1427a05d857d5fce6cccc61cd922, for GNU/Linux 3.7.0, stripped

        

これでKittyのバイナリは少なくともアーキテクチャが
aarch64 で対応していることがわかります。
現在のラズパイ4のCPU側の設定がどうなっているかというと、

            $ uname -a
Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr  3 17:24:16 BST 2023 aarch64 GNU/Linux

$ arch
aarch64

        

ハードウェア的なスペックは十分満たしているのが確認できます。
更にlddコマンドでKittyのバイナリファイルの共有ライブラリ依存性を確認してみます。

            $ ldd kitty
	not a dynamic executable

        

アーキテクチャは整合してそうなのに、実行可能ファイルじゃないと言われます。
他方で、dpkgコマンドでは、

            $ dpkg --print-architecture
armhf

        

aarch64 とはアーキテクチャが異なります。
と言うことで、ラズパイで動かしてあげるには、
armhf アーキテクチャのKittyをインストールすべきだと理解できます。
ちなみに、正常に動作しないバイナリファイルを調べる場合、「file」コマンドと「ldd」コマンドを使うととても有用な情報が得られるときがあります。
正常に動作しているバイナリファイルの一例として、標準で動作している例えばbashコマンドのバイナリを覗くと、

            $ file /usr/bin/bash
/usr/bin/bash: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=f12e6d40fb262ad0037b6ec43162208b76d4da71, for GNU/Linux 3.2.0, stripped

$ ldd /usr/bin/bash
	/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v8l.so (0xf7a86000)
	libtinfo.so.6 => /lib/arm-linux-gnueabihf/libtinfo.so.6 (0xf7a41000)
	libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xf7a2d000)
	libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xf78da000)
	/lib/ld-linux-armhf.so.3 (0xf7a9b000)

        

で、バイナリファイルのアーキテクチャターゲット、リンクされているライブラリともに問題はなく、きちんと実行可能になっていることがわかります。

aptからKittyをパッケージインストールする



Kittyの公式において直接的には触れていない内容のようですが、現状のDebian系OS向けにはaptコマンドからインストールパッケージが提供されています。

            $ sudo apt install kitty

        

追加でImageMagickも必要なのでラズパイにインストールします。

            $ sudo apt install imagemagick

        

これで
kitty/kitten をRaspberry Pi OSでも利用できるようになりました。
問題は、ラズパイ側で動作するKittyが、SSH経由でその画像をクライアント側のターミナルへそのまま転送されるのか、と言う点です。
それをSSHクライアント側のWezTermで確認してみましょう。

            $ kitty +kitten icat test-2.jpg
#👇何も起こらない...

$ DISPLAY=:0.0 kitty +kitten icat test-2.jpg
#👇何も起こらない...

$ DISPLAY=:0.0 kitty +kitten icat --transfer-mode=file test-2.jpg
#👇何も起こらない...


        

色々とオプションを変えて
kitten icat サブコマンドをトライしてみたものの、うーん...なにか描画処理はしているような気配はありますが、SSH越しだとクライアント側のターミナルに画像は表示されないようです。
残念ですが、何がバグのようなものなのか、他の内部エラーを起こしているのか、現状では問題をトレースできそうにないので、Kittyからのリモート画像表示はここで諦めます。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

img2sixelコマンドでSSH接続中のRaspberry PIからターミナルに画像表示



前節まででRaspberry PiへSSH接続したまま直接クライアントのターミナルにKittyを使った画像表示は失敗に終わりました。
ただこのままだと後味も悪いので、
前回 使った 『libsixel』 をラズパイ側に導入し、SSHクライアント側へ表示結果を伝えることができるかを最後にサラッと確認してみます。

libsixel 自体は、Raspberry Piでも簡単にインストールすることが可能です。
ラズパイ側にSSH接続し、

            $ sudo apt install libsixel*

        

を行うと
img2sixel コマンドが利用可能になります。
後はWezTermのような
Sixel graphic protocol に対応したターミナルソフトを使い、SSH経由で画像を直接描画します。

            $ img2sixel <表示させたい画像ファイル>

        


600x447
合同会社タコスキングダム|蛸壺の技術ブログ


Kitty/Kittenコマンドでできなかったターミナルでの画像表示があっさりと実行されました。
...回りくどかったですが、当初から使っていた「WezTerm」と「libsixel」の組み合わせがやはり理想的だったことが改めて理解できました。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

まとめ



WezTermを使うと、基本的にはiTerm2(インライン)、kitty、sixelの各グラフィックプロトコルいずれも問題なく画像をターミナルに直接描画することができます。
対してSSH経由で画像を表示させたい場合注意が必要なのは、SSHサーバー側の事情で、対応のCPUアーキテクチャやOS向けに互換性のあるソフトウェアが提供させているのか、が結果に大きく左右されます。
また、ソフトウェアがインストールできたとしても、内部に潜むバグによって思うように動かないことも分かりました。
ということで、SSHクライアント側でWezTermを使う際には、SSHサーバー側(今回はラズパイを想定)にはlibsixelをインストールすることで、無事SSH経由からでも直接ターミナルに画像を表示させることができるようです。