Rust製のCLI電子メールクライアントのHimaraya

Rust製のCLI電子メールクライアントのHimarayaというものを見かけたので少し試してみました.

Himarayaは単体ではCLIのクライアントでバッチ的に利用できます.VIm/Neovimのプラグインを使うとTUIで直感的に操作できるようになるようです.
Windows/macOS/Linux(amd64)はリリースページからバイナリが入手できます.今回はLinux amd64環境で試しました.

$ wget https://github.com/soywod/himalaya/releases/download/v0.2.2/himalaya-linux.tar.gz (1)
$ tar tvf ./himalaya-linux.tar.gz (2)
-rwxr-xr-x runner/docker 9090192 2021-04-05 00:50 himalaya.exe
$ tar xf ./himalaya-linux.tar.gz (3)
$ sudo install -m 755 ./himalaya.exe /usr/local/bin/himaraya (4)
$ rm ./himalaya.exe
$ mkdir ~/.config/himalaya (5)
$ vi ~/.config/himalaya/config.toml (6)
$ cat ~/.config/himalaya/config.toml
name = "Kenichiro Matohara"
downloads-dir = "~/.config/himalaya/gmail/"
signature = "Regards,"

[matoken_gmail]
default = true
email = "matoken@gmail.com"

imap-host = "imap.gmail.com"
imap-port = 993
imap-login = "matoken@gmail.com"
imap-passwd-cmd = "gpg2 --no-tty -q -d ~/.msmtp-password-gmail2.gpg"

smtp-host = "smtp.gmail.com"
smtp-port = 487
smtp-login = "matoken@gmail.com"
smtp-passwd-cmd = "gpg2 --no-tty -q -d ~/.msmtp-password-gmail2.gpg"
  1. Linuxリリースバイナリのダウンロード
  2. アーカイブの内容確認
  3. アーカイブの展開
  4. /usr/local/binhimaraya として導入
  5. 設定ファイルディレクトリの作成
  6. 設定ファイル作成

設定ファイルは README.md にgmailの例が書かれているので,imap4/smtpの場合はそのまま真似すると良さそうです.
設定ファイルのパスワード部分の imap-passwd-cmd , smtp-passwd-cmd は平分でも書けるようですが,コマンドが書けるのでmsmtpで使っているgpg2のものを使いました.opensslなども使えます.パスワードマネージャを使っても良さそうです.

$ himaraya list

UID    |FLAGS |SUBJECT                                           |SENDER                     |DATE
403387 |       |[oss-security] CVE-2021-29136: umoci: malicious … |Aleksa Sarai               |2021-04-06 11:13:14
403386 |       |[oss-security] Django: CVE-2021-28658: Potential… |Mariusz Felisiak           |2021-04-06 09:10:32
403385 |       |Ingress Damage Report: Entities attacked by taar… |Niantic Project Operations |2021-04-06 07:52:16
403384 |       |Ingress Damage Report: Entities attacked by taar… |Niantic Project Operations |2021-04-06 07:52:14
403383 |       |Ingress Damage Report: Entities attacked by taar… |Niantic Project Operations |2021-04-06 07:52:15
403382 |      |CPUのコアを増やせば、コア間の通信が増え処理速度が上がらないのではありませんか?         |Quoraダイ
ジェスト                |2021-04-06 06:35:23
403381 |      |In October, you had 4.8K users visit your websit… |Google Analytics           |2021-04-05 22:44:18
403380 |      |Daily activity summary for Nextcloud              |Nextcloud                  |2021-04-05 21:30:06
403379 |       |Re: [oss-security] Risk of local privilege escal… |Leo Famulari               |2021-04-05 20:20:55
403378 |       |Re: [oss-security] Risk of local privilege escal… |Leo Famulari               |2021-04-05 20:19:15

いくつかのコマンドを使いバッチ的にメールボックスを操作できます.しかし普通のMUAとして使うには面倒です.

Vim/Neovimのプラグインを使うとTUIで利用できるらしいので試してみます.

Note
※前提条件として,vim-plugが使える状態になっている必要があります.
junegunn/vim-plug: Minimalist Vim Plugin Manager
$ echo "Plug 'soywod/himalaya', {'rtp': 'vim'}" >> ~/.vimrc

Vimの設定ファイルの ~/.vimrc にHimaraya pluginを追記します.
vimを起動して, :PlugInstall を実行してHimaraya Pluginを導入します.

その後,Vimの中で :Himaraya で起動します.

Himarayaの設定ができていればそのままTUIで使えるようになります :)

今の時点ではあまり使いやすくはなくAlpineやMutt/NeoMuttのほうが良さそうです.でも開発も活発そうなのでこれからに期待したいです.

ところで名前の Himaraya は山つながりで Alpine のインスパイアなのでしょうか?

環境
$ himalaya --version
himalaya 0.2.2
$ dpkg-query -W vim gpg
gpg     2.2.27-1
vim     2:8.2.2434-3
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ arch
x86_64

dnsクエリをスパイする dnspeep

dnspeep というRust製のdnsのクエリ内容を表示するプログラムを知ったので少し試してみました.

GitHubのReleaseページにLinux x86_64とmacOS x86_64のバイナリが置いてあるのでその環境だとそれをダウンロードして会伊藤するだけで使えます.他の環境では cargo build すればいいのかな?

$ wget https://github.com/jvns/dnspeep/releases/download/v0.1.1/dnspeep-linux.tar.gz
$ tar tvf ./dnspeep-linux.tar.gz
-rwxr-xr-x runner/docker 5570536 2021-04-02 06:20 dnspeep
$ file dnspeep
dnspeep: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a917041c223b18db709ff3c563ee1a6a3c82ba6e, for GNU/Linux 3.2.0, with debug_info, not stripped
$ ./dnspeep -h|xsel
Usage: ./dnspeep [options]

Options:
    -p, --port PORT     port number to listen on
    -f, --file FILENAME read packets from pcap file
    -h, --help          print this help menu

What the output columns mean:
   query:     DNS query type (A, CNAME, etc)
   name:      Hostname the DNS query is requesting
   server IP: IP address of the DNS server the query was made to
   response:  Responses from the Answer section of the DNS response (or "<no response>" if none was found).
              Multiple responses are separated by commas.

$ sudo ./dnspeep
query name                           server IP            response
A     tweetdeck.twitter.com.         192.168.1.102        CNAME: td.twitter.com., A: 104.244.42.132, A: 104.244.42.4, A: 104.244.42.68, A: 104.244.42.196
  :

libpcapからパケットを引っ張ってdnsのクエリを整形して出力しているようです.こんな感じでtcpdumpでもいいのですが,dnsに特化しているのでオプションとか覚えなくていいのはいいですね.

$ sudo tcpdump -i eth0 udp port 53 or tcp port 53
環境

dnspeep v0.1.1

$ dpkg-query -W libpcap0.8 tcpdump
libpcap0.8:amd64        1.10.0-2
libpcap0.8:i386 1.10.0-2
tcpdump 4.99.0-2
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ arch
x86_64

カラフルでかわいい prettyping

pingのカラフルなラッパーの prettyping というものを知りました.

少し試してみました.

$ curl -O https://raw.githubusercontent.com/denilsonsa/prettyping/master/prettyping
$ install -m 755 ./prettyping ~/bin/
$ ls -l ~/bin/prettyping
-rwxr-xr-x 1 pi pi 23396 Apr  1 22:08 /home/pi/bin/prettyping
$ ~/bin/prettyping 1.1.1.1
0 ▁ 10 ▂ 20 ▃ 30 ▄ 40 ▅ 50 ▆ 60 ▇ 70 █ 80 ▁ 90 ▂ 100 ▃ 110 ▄ 120 ▅ 130 ▆ 140 ▇ 150 █ 160 ▁ 170 ▂
180 ▃ 190 ▄ 200 ▅ 210 ▆ 220 ▇ 230 █ ∞
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
▂▅█▁▄▂█
 0/  7 ( 0%) lost;   76/ 107/ 178ms; last:   76ms
 0/  7 ( 0%) lost;   76/ 107/ 178/  27ms (last 7)

カラーで見るときれいです.

prettyping

安定した回線だと緑で面白くないので不安定な回線や遠くのアドレスを指定するといいかもしれません.今回は電波状況の悪い携帯回線で試しました.(-120dBM前後の圏外になったり戻ったりな場所)


https://www.youtube.com/watch?v=gL87DBohRaQ
環境
$ dpkg-query -W iputils-ping curl coreutils
coreutils	8.30-3
curl	7.64.0-4+deb10u1
iputils-ping	3:20180629-2+deb10u2
$ lsb_release -dr
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
$ arch
armv7l
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2

カレンダーをWebhooksでDiscordに投稿

以下の記事でDavCalやGoogleカレンダーをコマンドラインで閲覧できるようになりました.

せっかくなのでDiscordにも毎朝その日のイベントを投稿するようにしてみます.

DiscordはWebhooksを使ってかんたんにメッセージを投稿することが出来ます.

投稿したいチャンネルの⚙アイコン「チャンネルの編集」から「連携サービス」→「ウェブフック」から操作できます.
新しいウェブフックを作成し,投稿チャンネルを確認して「ウェブフックURLをコピー」でWebhooks URLを入手します.

curlで投稿テストをしてみます.

$ curl -X POST -H "Content-Type: application/json" \
  -d '{"username": "ボット", "content": "こんにちは🤖"}' \
  'https://ptb.discord.com/api/webhooks/826777625053495306/QZoG2LLZOFlsKO_Auf1IQcXHVFozlgU37EGO9bhQKAifzZ0VAkyIYuQjRSzuOvC7U1gR'

Discord bot

これで投稿できました :)

Discordにメッセージを投稿できるようになったので,以下のエントリで書いた khal コマンドで今日1日分の予定タイトルを入手してDiscordに投稿するようにしてみます.

以下の適当なScriptを用意しました.

2021-04-01 編集)
イベントがない日にも投稿してしまっていたのを修正&Bashismだったのをshで動くよう修正

#!/bin/sh
# khalコマンドで今日の予定を入手してDiscordにpostする
# https://matoken.org/blog/2021/03/31/post-your-calendar-to-discord-with-webhooks/

# DiscordのWebhook URL
# 以下のURLを参考に入手して設定する
# https://support.discord.com/hc/ja/articles/228383668-%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB-Webhooks%E3%81%B8%E3%81%AE%E5%BA%8F%E7%AB%A0
DISCORD_WEBHOOK='https://ptb.discord.com/api/webhooks/…………'

# khal
#   list -> 一覧表示
#   --format "{title}" -> タイトルだけ表示
#   today -> 今日から
#   today -> 今日まで
# sed -> jsonの改行形式に変換
CAL=$(khal list --format "{title}" today today | sed -z -e "s/\n/\\\\\\\\n/g")

# イベントのない日は投稿せず終了
if [ "${CAL}" = 'No events\\n' ]
then
  echo "${CAL}"
  exit
fi

MSG=$(printf '{"username": "今日のイベント📅", "content": "%s"}\n' "${CAL}")
echo "$MSG"

# Discord WebHock でKagolug の#random へpost
curl -X POST -H "Content-Type: application/json" \
	-d "${MSG}" \
	"${DISCORD_WEBHOOK}"

試しに実行すると投稿されました.

手動で叩くのは面倒すぎるので自動実行するようにcrontabに登録しておきます.

$ crontab -l | grep calpost
58 4 * * *      /home/matoken/bin/calpost.sh 2>&1 > /home/matoken/tmp/cron/calpost.sh.log

毎日04:58に実行するようにしました.

環境
$ dpkg-query -W vdirsyncer khal curl bash
bash    5.0-4
curl    7.64.0-4+deb10u1
khal    1:0.9.10-1.1
vdirsyncer      0.16.7-2
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
x86_64

カレンダーのDavCalをコマンドラインに出力したい

何らかの日程を決めるときに未来の日程を見ながら決めたいことがあります.
Webベースでいいかと思ったのですが,特に低解像度だとタイトルの一部しか表示されずよくわかりません.コピーペーストしてEtherPadなどに貼るといいですが時間がかかるし面倒です.
DavCalなどの情報を範囲指定して表示出来ると便利そうだなと思いました.

はじめはコマンドを叩いて範囲指定して表示するようなものがないかと思ったのですが見つかりませんでした.少し面倒ですが, vdirsyncer でリモートのカレンダーをローカルにコピーして khal コマンドで表示するようにしてみました.

Vdirsyncer の導入と設定

Vdirsyncer はカレンダーとコンタクトをローカルと同期できるソフトウェアです.これでリモートのDavCal の情報をローカルに同期します.

$ sudo apt install vdirsyncer (1)
$ mkdir ~/.config/vdirsyncer
$ vi ~/.config/vdirsyncer/config (2)
$ cat ~/.config/vdirsyncer/config
[general]
status_path = "~/.vdirsyncer/status/"

[pair my_calendars]
a = "my_calendars_local"
b = "my_calendars_remote"
collections = null
metadata = ["color"]

[storage my_calendars_local]
type = "filesystem"
path = "~/.calendars/"
fileext = ".ics"

[storage my_calendars_remote]
type = "caldav"
url = "https://files.matoken.org/remote.php/dav/public-calendars/YW5gc6gMG8tC63AH?export"
  1. Vdirsyncer の導入
  2. 設定ファイル作成

これでとりあえず Vdirsyncer を導入して,リモートの CalDav 形式のカレンダーをローカルのストレージに同期できます.
設定ファイルは以下のページを参考にしました.相互同期はせず,リモートのデータをローカルに同期するだけの動作のつもりです.

$ vdirsyncer discover my_calendars (1)
Discovering collections for pair my_calendars
my_calendars_local:
my_calendars_remote:
  - "YW5gc6gMG8tC63AH" ("onlin_event (matoken)")
warning: No collection "YW5gc6gMG8tC63AH" found for storage my_calendars_local.
Should vdirsyncer attempt to create it? [y/N]: y
Saved for my_calendars: collections = ["YW5gc6gMG8tC63AH"]
$ vdirsyncer sync (2)
Syncing my_calendars/YW5gc6gMG8tC63AH
Copying (uploading) item 05f764a4-8c30-46ed-a0fe-62c67d3975a8 to my_calendars_local/YW5gc6gMG8tC63AH
Copying (uploading) item 1acc3691-a12b-4534-a4e2-6ee6213ecff1 to my_calendars_local/YW5gc6gMG8tC63AH
Copying (uploading) item 202e727b-0431-40b5-8008-9ada1269c7c8 to my_calendars_local/YW5gc6gMG8tC63AH
Copying (uploading) item 2312a403-b2e6-4716-9c6f-45aa94519654 to my_calendars_local/YW5gc6gMG8tC63AH
  :
$ ls ~/.calendars/YW5gc6gMG8tC63AH/ | head (3)
05f764a4-8c30-46ed-a0fe-62c67d3975a8.ics
1acc3691-a12b-4534-a4e2-6ee6213ecff1.ics
202e727b-0431-40b5-8008-9ada1269c7c8.ics
2312a403-b2e6-4716-9c6f-45aa94519654.ics
263c2df9-ad9b-40d5-a946-614af7bc10ae.ics
29cbecc8-0b88-41da-b7d0-0c71062eb6b4.ics
2c66d40f-f5bd-4a67-bfb9-9bbb0258a966.ics
2e81f5bd-1aad-435a-bfa4-4a3ebe75e489.ics
30d41952-4dc3-4f10-bb6d-3311593f1d25.ics
3335be8d-9dd6-4b5e-81e9-a292d56fa17e.ics
  1. 設定を探索して初期化.設定を作ったときに実行.
  2. カレンダーを同期.定期的に実行.
  3. 同期されたデータが .ics ファイルとして作られているのを確認.

カレンダーがローカルに同期されました :)
vdirsyncer sync は定期的に実行して同期するようにします.

$ crontab -l | grep 'vdirsyncer sync'
4 4 * * *       chronic vdirsyncer sync

crontab に設定して1日1回同期するようにしました.
chronic を挟んでいますが,これはmoreutils のコマンドの1つで,正常終了時にはメッセージを出力しないというものです.エラー時だけメールが飛ぶはず.

khalの導入と設定

カレンダーの同期は出来ましたが,icsファイルがあるだけなので閲覧が不便です.閲覧するために khal コマンドを利用します.

$ sudo sudo apt install khal
$ mkdir ~/.config/khal
$ vi ~/.config/khal/config
$ cat ~/.config/khal/config
[calendars]
  [[event]]

    path = ~/.calendars/YW5gc6gMG8tC63AH/
    readonly = True

[locale]
timeformat = %H:%M
dateformat = %Y-%m-%d
longdateformat = %Y-%m-%d
datetimeformat = %Y-%m-%d %H:%M
longdatetimeformat = %Y-%m-%d %H:%M

khalを導入して設定を書いてみました.pathは Vdirsyncer で同期された場所を指定します.
この状態でkhalを叩くとこんな感じで表示されました.

$ khal
    Mo Tu We Th Fr Sa Su     Tomorrow, 2021-03-31
Mar  1  2  3  4  5  6  7     20:00-21:30 TechLION vol.37 〜TechLION出演者に聞く、この1年とこの10年。そして未来〜 :: # 視聴方法  本イベントはYouTubeにて配信します  視聴URLは決まり次第掲載します  #
     8  9 10 11 12 13 14     プログラム  2011年3月に旗揚げしたTechLIONが10周年を迎えるにあたり、記念試合をオンラインイベントとして行います。   ト
ークセッションでは、これまでTechLIONに出演してくださった皆さんに、IT業界の最近の状況、
    15 16 17 18 19 20 21     10年間の変化、今後の予想などをお聞きします。事前に実施したアンケート結果を見ながらMCの2名が進行しますが、回答によっ
ては出演者の方もトークにご参加いただきます。
    22 23 24 25 26 27 28     TechLION旗揚げ記念日でもある3月31日の夜、お酒を片手にお楽しみください!    * 出演:これまでのTechLIONにご出演の皆さ
ん   * MC:法林浩之、馮富久  # 開催概要    * 名称:TechLION
Apr 29 30 31  1  2  3  4     vol.37 〜TechLION出演者に聞く、この1年とこの10年。そして未来〜   * 主催:チームTechLION   * 協賛:USP研究所、技術評
論社   * 後援:日本UNIXユーザ会   *
     5  6  7  8  9 10 11     日時:2021年3月31日(水) 20:00開演、21:30終了予定   * 場所:オンライン (YouTubeにて配信)   * 料金:無料   * 公式タグ
:techlion   * 問い合わせ先:チームTechLION
    12 13 14 15 16 17 18     (E-mail:staff[at]techlion.jp)  # イベント詳細  https://techlion.jp/vol37
    19 20 21 22 23 24 25     https://techlion.connpass.com/event/205623/
May 26 27 28 29 30  1  2
     3  4  5  6  7  8  9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
Jun 31  1  2  3  4  5  6

ikhalコマンドを使うとダンプではなく,tuiのhalが起動してインタラクティブに操作できます.

ikhal

ちょっと冗長なので --format "title}" でタイトルだけ表示するようにしてみました.

$ khal list --format "{title}"
Tomorrow, 2021-03-31
TechLION vol.37 〜TechLION出演者に聞く、この1年とこの10年。そして未来〜

今日だけや,今日から7日間など範囲指定も出来ます.

$ khal list --format "{title}" today today (1)
$ khal list --format "{title}" today 7days (2)
$ khal list --format "{title}" 2021-03-01 2021-03-31 (3)
$ faketime 2021-03-03 khal list --format "{title}" today (4)
  1. 今日から今日まで表示
  2. 今日から7日間表示
  3. 03/01〜03/31まで表示
  4. faketimeで03/03としてkhalを実行

URLも表示したいけど,あっても.icsのDiscriptionの中などなのでちょっと面倒そうなので今回は諦めました.必要なときはカレンダーを参照することにします.

複数のカレンダーの設定

2つ目のカレンダーを登録してみます.次は日本の休日カレンダーを登録してみます.

~/.config/vdirsyncer/config に以下の設定を追記します.

[pair holiday_calendars]
a = "holiday_calendars_local"
b = "holiday_calendars_remote"
collections = null
metadata = ["color"]

[storage holiday_calendars_local]
type = "filesystem"
path = "~/.calendars/holiday_calendars/"
fileext = ".ics"

[storage holiday_calendars_remote]
type = "http"
url = "https://www.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics"

設定反映してカレンダーを同期します.

$ vdirsyncer discover holiday_calendars
$ vdirsyncer sync holiday_calendars

次にkhalの設定です.
~/.config/khal/config[calendars] セクションに以下の設定を追記します.

  [[holiday]]
    path = ~/.calendars/holiday_calendars/
    readonly = True

この状態でkhalを実行してみると祝日も表示されるようになりました :)

$ khal list --format "{title}" 2021-03-20 1days
Saturday, 2021-03-20
春分の日
NBUG 2021年3月例会[第250回例会]
Kernel/VM探検隊online part2

ということで当初思っていたより少し面倒でしたが,とりあえずやりたいことが出来るようになりました :)

環境

$ dpkg-query -W vdirsyncer khal faketime
faketime        0.9.7-3
khal    1:0.9.10-1.1
vdirsyncer      0.16.7-2
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
x86_64

標準入力の結果をシームレスに選択してクリップボードにコピーする「yank」

ターミナルからの標準入力の結果をシームレスに選択してクリップボードにコピーしてくれる yank というコマンドを知りました.

yankは各種環境のパッケージが用意されています.
Debian sid amd64 / Ubuntu 21,04 amd64 / Raspberry Pi OS buster armhf では yank というパッケージで提供されているのでこれを導入します.

$ sudo apt install yank (1)
$ yank (2)
bash: yank: command not found
$ dpkg -L yank | grep bin/ (3)
/usr/bin/yank-cli
  1. yank パッケージを導入
  2. yankコマンドが見つからない
  3. Debian系では名前空間の衝突のためにコマンド名が yank-cli になっている.

とりあえず導入できましたが,Debian環境だと yank コマンドが見つかりません.他のパッケージと名前が競合してしまっているので yank-cli として提供されているようです.

The binary is installed at /usr/bin/yank-cli due to a naming conflict.

— ‘https://github.com/mptre/yank
$ apt-file search /bin/yank
emboss: /usr/bin/yank
yank: /usr/bin/yank-cli

競合しているのはなんds楼と検索してみると emboss というパッケージのようです.

ヨーロッパ分子生物学オープンソフトウェアスイート
EMBOSS は、分子生物学のユーザコミュニティ (例: EMBnet) のために開発された オープンソースな解析用ソフトウェアパッケージです。このソフトウェアを 使うことで、様々なフォーマットで書かれたデータを自動的に処理したり、 ウェブから配列データを透過的に取得したりもできます。また、このパッケージには 拡張ライブラリが含まれているので、真のオープンソース精神に則って ソフトウェアを開発しリリースできるプラットフォームです。 さらに、EMBOSS は様々な配列解析用パッケージやツールとシームレスに 統合されています。EMBOSS は、長く続いた商用パッケージソフトウェアへの流れを 断ち切ったのです。

なかなか熱そうなプロジェクトのようです.

使わないならalias等でyankに向けてもいいかもしれません.

とりあえず導入出来たので試してみます.

yank 01

$ apt-cache search yank | yank-cli
elpa-csv-mode - Emacs major mode for editing comma/char separated values
python3-readlike - GNU Readline-like line editing module
yank - interactively select and yank terminal output to stdout or xsel

apt-cache search の結果を yank で受けてカーソルなどで単語単位で移動してEnterで選択した部分をクリップボードにコピーします.
クリップボード貼付けをするとたしかにコピーされていました.
例えばパッケージ名をコピーして, $ sudo apt install \`xsel\` のようにして使うと便利そうです.

その他便利そうなオプションとして, -d があります.cutコマンドの-dと同じようにデリミタが指定できます.

$ nkf -w mntemsadext00_rct.csv | yank-cli -d,

こんな感じでcsvファイルに , を指定してあげると,各項目がコピーできます.

しかし,yankはページ跨ぎが出来ないようです.1ページ目のものしかコピーできません.こういう場合はyankに渡す前にフィルタしてあげるといいようです.grepや,昨日このblogで紹介したyankと同じ作者の「pick」もこういうときに便利です.

$ nkf -w mntemsadext00_rct.csv | grep 田代 | yank-cli -d,`
$ nkf -w mntemsadext00_rct.csv | pick | yank-cli -d,`

なにかの結果の一部が欲しいときに便利そうです.

環境1
$ dpkg-query -W yank pick
pick	2.0.2-1
yank	1.1.0-2
$ lsb_release -dr
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
$ uname -m
armv7l
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2
環境2
$ dpkg-query -W yank pick
pick	2.0.2-1.1
yank	1.2.0-1
$ lsb_release -dr
Description:	Debian GNU/Linux bullseye/sid
Release:	unstable
$ uname -m
x86_64

コマンドライン標準入力からあいまい検索が出来る「pick」

コマンドラインの標準入力をあいまい検索してその結果を主治力出来るpickというコマンドを知ったので試してみました.

たくさんの環境パッケージがあります.今回はDebian sid amd64とRaspberry Pi OS buster armhfで pick パッケージを導入しました.

$ sudo apt install pick (1)
$ ls ~/Downloads/*.pdf | wc -l (2)
181
$ ls ~/Downloads/*.pdf | pick | xargs -I{} xpdf "{}" (3)
rpi (4)
/home/matoken/Downloads/rpi_DATA_CM_3p0.pdf
/home/matoken/Downloads/rpi_MECH_3b_1p2.pdf
/home/matoken/Downloads/RPi-Camera-User-Manual.pdf
/home/matoken/Downloads/rpi_SCH_3b_1p2_reduced.pdf
/home/matoken/Downloads/rpi_SCH_4b_4p0_reduced.pdf
/home/matoken/Downloads/rpi_SCH_ZeroW_1p1_reduced.pdf
/home/matoken/Downloads/RPi_Pi Pico_Digital Edition.pdf
  1. pick パッケージ導入
  2. pdfファイルがたくさんある
  3. lsの結果をpickを挟んでxpdfに渡す
  4. 「rpi」とキーワードを入力することで絞り込まれる

pick 01

上下カーソル入力で結果を選択,Enterで確定.確定された行はSTDOUTに出力され,今回の例では xpdf で開かれる.

コマンド結果が多くて grep を繋いでいくみたいなときに pick を使うとインタラクティブに絞り込まれたりしてわかりやすいです.

似たものに sysboxchoose-stdin というものもあります.

環境1
$ dpkg-query -W pick
pick    2.0.2-1.1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64
環境2
$ dpkg-query -W pick
pick    2.0.2-1
$ lsb_release -dr
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
$ uname -m
armv7l
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2

ターミナルダッシュボードのWTFを少し試す

WTFというGo製のターミナルダッシュボードを見かけたので少し試してみました.

導入はLinuxのamd64/armv6/arm64,macOSのamd64/arm64はGitHub releaseページにあるのでそれを使うのが手っ取り早いです.
今回はarmv6をRaspberry Pi 3 Model BのRaspberry Pi OS armhfで試しました.

$ wget https://github.com/wtfutil/wtf/releases/download/v0.36.0/wtf_0.36.0_linux_armv6.tar.gz https://github.com/wtfutil/wtf/releases/download/v0.36.0/wtf_0.36.0_checksums.txt (1)
$ sha256sum -c ./wtf_0.36.0_checksums.txt 2>&1 | grep wtf_0.36.0_linux_armv6.tar.gz: (2)
wtf_0.36.0_linux_armv6.tar.gz: OK
$ tar tvf ./wtf_0.36.0_linux_armv6.tar.gz (3)
-rw-r--r-- ccummer/staff 34534 2021-03-23 19:20 wtf_0.36.0_linux_armv6/CHANGELOG.md
-rw-r--r-- ccummer/staff 14878 2018-12-01 01:13 wtf_0.36.0_linux_armv6/LICENSE.md
-rw-r--r-- ccummer/staff 39700 2021-03-20 13:46 wtf_0.36.0_linux_armv6/README.md
-rwxr-xr-x ccummer/staff 41615360 2021-03-23 19:35 wtf_0.36.0_linux_armv6/wtfutil
$ tar xf ./wtf_0.36.0_linux_armv6.tar.gz (4)
$ wtf_0.36.0_linux_armv6/wtfutil (5)
  1. Releases ページから最新のバイナリとチェックサムファイルを入手
  2. チェックサムファイルの中を見ると桁数的にsha256のようだったので,sha256sumでチェックサムを確認
  3. アーカイブの確認
  4. アーカイブの展開
  5. WTF起動

バイナリアーカイブをダウンロードして展開しました.
wtf_0.36.0_linux_armv6/wtfutil を実行すると既定値で起動します.しかし娘の設定だとターミナルサイズ固定だったりあまり嬉しくありません.

リポジトリの _sample_configs 以下にサンプルがあるのでこれを指定して起動してみます.

設定ファイルは既定値は ~/.config/wtf/config.yml を使います.存在しない場合はデフォルトのものが生成されます.若しくは wtf の -c, --config= オプションで指定した設定ファイルを指定できます.

$ wtf_0.36.0_linux_armv6/wtfutil --config=../src/wtf/_sample_configs/sample_config.yml

wtf 01

wtfリポジトリの _sample_configs/sample_config.yml を指定して起動するとこんな感じでターミナルサイズにも追従していい感じです.

wtf 02

diff --git a/_sample_configs/sample_config.yml b/_sample_configs/sample_config.yml
index e16690a0..fa3bf5c0 100644
--- a/_sample_configs/sample_config.yml
+++ b/_sample_configs/sample_config.yml
@@ -73,10 +73,21 @@ wtf:
         width: 1
       refreshInterval: 15
       sort: "alphabetical"
+    feedreader:
+      enabled: true
+      feeds:
+        - https://nitter.matoken.org/matoken1/rss
+      feedLimit: 10
+      position:
+        top: 1
+        left: 3
+        height: 1
+        width: 1
+      updateInterval: 14400
     battery:
       type: power
       title: "⚡️"
-      enabled: true
+      enabled: false
       position:
         top: 1
         left: 3

Raspberry Piは電源ステータスは見えないので無効にして代わりにfeedreaderを有効にしてNitter経由でTwitterのRSSフィードを表示してみました.

日本語や絵文字も崩れず表示できて良さそうですね.

その他にもたくさんのモジュールがあるようです.こちらのページから確認できます.(Nitterを通さなくてもTwitterモジュールもあった)

自分の用途に合わせて設定していくと便利そうです.

環境
$ wtf_0.36.0_linux_armv6/wtfutil --version
0.36.0 (2021-03-23T10:33:30Z)
$ lsb_release -dr
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
$ uname -m
armv7l
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2

Raspberry Pi の OSイメージを書き込む Raspberry Pi Imager v1.6 の新機能で書き込み時にカスタマイズ

Raspberry Pi で利用するストレージへのOSイメージ書き込みツールのRaspberry Pi Imagerの最新版のv1.6がリリースされたようです.

自分は出た当初少し試しただけで他のツールに比べて嬉しいことがあまりないと感じたので使っていなかったのですが,このv1.6ではイメージのカスタマイズ機能が入ったようなので試してみました.

Raspberry Pi Imagerの導入

$ sudo apt install rpi-imager

Raspberry Pi OSであればパッケージが存在するのでこれを導入すればokです.

Linux/Windows/macOSはGitHubのreleaseページから入手できます.
若しくは,Raspberry Pi downloadsページにもあります.こちらだとGutHubとファイル名が違いますがamd64の.debをdiffしてみると同じもので署名ファイルもあります..AppImageもありますが試してみると最新ではないようでした.

$ wget https://github.com/raspberrypi/rpi-imager/releases/download/v1.6/rpi-imager_1.6_amd64.deb (1)
$ wget https://downloads.raspberrypi.org/imager/imager_1.6_amd64.deb https://downloads.raspberrypi.org/imager/imager_1.6_amd64.deb.sig (2)
$ diff ./imager_1.6_amd64.deb ./rpi-imager_1.6_amd64.deb (3)
$ gpg2 --verify ./imager_1.6_amd64.deb.sig (4)
gpg: assuming signed data in './imager_1.6_amd64.deb'
gpg: Signature made Tue 16 Mar 2021 08:56:51 PM JST
gpg:                using RSA key 54C3DD610D9D1B4AF82A37758738CD6B956F460C
gpg: Good signature from "Raspberry Pi Downloads Signing Key" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 54C3 DD61 0D9D 1B4A F82A  3775 8738 CD6B 956F 460C
$ gpg2 --verify ./imager_1.6_amd64.deb.sig ./rpi-imager_1.6_amd64.deb
gpg: Signature made Tue 16 Mar 2021 08:56:51 PM JST
gpg:                using RSA key 54C3DD610D9D1B4AF82A37758738CD6B956F460C
gpg: Good signature from "Raspberry Pi Downloads Signing Key" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 54C3 DD61 0D9D 1B4A F82A  3775 8738 CD6B 956F 460C
$ sudo apt install ././imager_1.6_amd64.deb (5)
  1. GitHubからダウンロード
  2. downloads.raspberrypi.orgからダウンロード
  3. ファイル名は違うけど同じ内容なのを確認
  4. 署名確認
  5. インストール

Debian sid amd64環境ではAppImageが古いので.debを導入しました.

Imagerの起動と書き込み設定

Raspberry Pi ロゴのアイコンの「Imager」や, rpi-imager を実行すると起動します.

ここで,「ctrl + shift + x」を押すことで今回のカスタマイズ用の拡張オプション画面が表示されます.

rpi imager01
rpi imager02
rpi imager03
rpi imager04

今回はhostnameの修正,SSHの有効化,ssh公開鍵の登録,Wi-Fi 設定,タイムゾーンの設定を行いました.

「SAVE」して「RASPBERRY PI OS LITE (32-BIT)」を書き込んでみました.

書き込みが終了しても1つ目のパーティション(/boot)がマウントされたままでした.これはバグかな?(1回しか試していないので勘違いかもしれない)

$ mount | grep /dev/mmcblk0p1 (1)
/dev/mmcblk0p1 on /media/matoken/boot type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)
$ sudo umount /dev/mmcblk0p1 (2)
  1. 1つ目のパーティションがマウントされたまま
  2. アンマウントする

カスタマイズ内容確認

書き込まれたメディアの中を見ると /boot/firstrun.sh が作成されていました.Raspberry Pi Imagerは直接設定を書き換えるわけではなく,OSイメージを書き込んだあと子のファイルを作って,Raspberry Pi OSの初回起動時にこのscriptを実行して設定を反映していくようです.

/boot/firstrun.sh
#!/bin/bash

set +e

CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
echo raspberrypi-custom >/etc/hostname
sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\traspberrypi-custom/g" /etc/hosts
FIRSTUSER=`getent passwd 1000 | cut -d: -f1`
FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`
install -o "$FIRSTUSER" -m 700 -d "$FIRSTUSERHOME/.ssh"
install -o "$FIRSTUSER" -m 600 <(echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPgwY9aZPxN/YoBBzd7TOcCk7EuGO0E9PuUjCHPtTuHP mk@x220") "$FIRSTUSERHOME/.ssh/authorized_keys"
echo 'PasswordAuthentication no' >>/etc/ssh/sshd_config
systemctl enable ssh
cat >/etc/wpa_supplicant/wpa_supplicant.conf <<WPAEOF
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
ap_scan=1

update_config=1
network={
	ssid="matoken"
	psk="○○○○○○○○○○○○"
}

WPAEOF
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
rfkill unblock wifi
for filename in /var/lib/systemd/rfkill/*:wlan ; do
  echo 0 > $filename
done
rm -f /etc/xdg/autostart/piwiz.desktop
rm -f /etc/localtime
echo "Asia/Tokyo" >/etc/timezone
dpkg-reconfigure -f noninteractive tzdata
cat >/etc/default/keyboard <<KBEOF
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
KBEOF
dpkg-reconfigure -f noninteractive keyboard-configuration
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0

ちょっと雑かなと感じるところもありますが便利な感じです.
( /etc/wpa_supplicant/wpa_supplicant.confwpa_passphrase コマンドを通してpskにしておきたいとか)

自分はsd card書き込み前にPCでマウントしてパッケージを最新にしたりインストールしたりといったことをしているので,sd card書き込みをしなくてもこのファイルを書き出してくれると嬉しいかなと思いました.

アンインストール

$ sudo apt purge rpi-imager
$ rm -r ~/.config/Raspberry\ Pi/Imager.conf ~/.cache/Raspberry\ Pi/Imager

パッケージを削除して,設定ファイルとキャッシュを削除しました.

環境

$ dpkg-query -W rpi-imager
rpi-imager      1.6
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Debian で Linux Kernel の initramfs の圧縮形式を変更する🐧🗜️

先日「Debian sidでLinux Kernel(5.11)をbuildするメモ 」を書いたのですが,Twitterで@henrichさんからこんなメッセージが.

そういえば圧縮形式色々あったなと試してみました.

現在の圧縮形式を確認する

$ grep COMPRESS /etc/initramfs-tools/initramfs.conf
# COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz | zstd ]
COMPRESS=gzip
$ file --mime-type /boot/initrd.img-`uname -r`
/boot/initrd.img-5.11.8+: application/gzip

設定は gzip で,実際のファイルもgzipになっています.
圧縮形式は gzip 以外に bzip2, lz4, lzma, lzop, xz, zstd が選べるようです.

圧縮形式の比較

$ ls -1sS --block-size=1 ./initrd.img-5.11.8+.*
183033856 ./initrd.img-5.11.8+.raw
 81076224 ./initrd.img-5.11.8+.lz4
 78315520 ./initrd.img-5.11.8+.lzop
 54329344 ./initrd.img-5.11.8+.gzip
 51761152 ./initrd.img-5.11.8+.zstd
 50081792 ./initrd.img-5.11.8+.bz2
 36548608 ./initrd.img-5.11.8+.xz
 36540416 ./initrd.img-5.11.8+.lzma

容量がどのくらいになるのか各アーカイバで圧縮してみました.

$ \time -f %e cat ./initrd.img-5.11.8+.raw > /dev/null
0.03
$ \time -f %e lz4cat ./initrd.img-5.11.8+.lz4 > /dev/null
0.38
$ \time -f %e lzop -d -c ./initrd.img-5.11.8+.lzop > /dev/null
0.42
$ \time -f %e zstdcat ./initrd.img-5.11.8+.zstd > /dev/null
0.44
$ \time -f %e zcat ./initrd.img-5.11.8+.gzip > /dev/null
1.38
$ \time -f %e lzma -d -c ./initrd.img-5.11.8+.lzma > /dev/null
3.22
$ \time -f %e xzcat ./initrd.img-5.11.8+.xz > /dev/null
3.37
$ \time -f %e bzcat ./initrd.img-5.11.8+.bz2 > /dev/null
9.39

展開時間も確認してみました.

圧縮形式 圧縮データ量(byte) 展開時間(秒)

raw

183033856

0.03

lz4

81076224

0.38

lzop

78315520

0.43

gzip

54329344

1.38

zstd

51761152

0.44

bzip2

50081792

9.39

xz

36548608

3.37

lzma

36540416

3.22

圧縮データの圧縮率などは既定値のままで,展開時間は \time -f %e zcat ./initrd.img-5.11.8+.gzip > /dev/null 若しくは \time -f %e lzma -d -c ./initrd.img-5.11.8+.lzma > /dev/null のようにして測りました.

サイズでは raw > lz4 ≒ lzop > gzip ≒ zstd ≒ bz2 > xz ≒ lzma な感じで,
展開速度は bz2 > xz ≒ lzma > gzip > zstd ≒ lzop ≒ lz4 > raw な感じです.

Caution
時間についてはデスクトップ環境で色々動いている状態で1回しか測っていないので目安程度にしてください.
Caution
ここでは既定値で圧縮しましたが,zstd, lz4, xzについてはinitramfs作成時に圧縮オプションなどが既定値と違うようなので目安程度にしてください.

容量的にはxz, lzmaが良さそうですが展開時間がとても増えそうです.zstdはgzipより速くて小さくなって良さそうです.
ということでzstdにしてみます.

initramfsを zstd で作り直す

$ sudo git -C /etc diff HEAD /etc/initramfs-tools/initramfs.conf
diff --git a/initramfs-tools/initramfs.conf b/initramfs-tools/initramfs.conf
index 01bdd85..a0c051b 100644
--- a/initramfs-tools/initramfs.conf
+++ b/initramfs-tools/initramfs.conf
@@ -41,7 +41,7 @@ KEYMAP=n
 # COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz | zstd ]
 #

-COMPRESS=gzip
+COMPRESS=zstd

 #
 # DEVICE: ...

/etc/initramfs-tools/initramfs.conf を編集して, COMPRESSzstd に変更します.

$ update-initramfs -h

Usage: update-initramfs {-c|-d|-u} [-k version] [-v] [-b directory]

Options:
 -k version     Specify kernel version or 'all'
 -c             Create a new initramfs
 -u             Update an existing initramfs
 -d             Remove an existing initramfs
 -b directory   Set alternate boot directory
 -v             Be verbose

See update-initramfs(8) for further details.

$ sudo update-initramfs -k `uname -r` -u -v

update-initramfs で更新を行います.

$ ls -s --block-size=1 /boot/initrd.img-5.11.8+
54542336 /boot/initrd.img-5.11.8+
$ ls -s --block-size=1 /boot/initrd.img-5.11.8+
41611264 /boot/initrd.img-5.11.8+
$ file --mime-type /boot/initrd.img-5.11.8+
/boot/initrd.img-5.11.8+: application/zstd
$ zstd -lv /boot/initrd.img-5.11.8+
*** zstd command line interface 64-bits v1.4.8, by Yann Collet ***
/boot/initrd.img-5.11.8+
# Zstandard Frames: 1
Window Size: 8.00 MB (8388608 B)
Compressed Size: 39.53 MB (41446437 B)
Decompressed Size: 174.55 MB (183032320 B)
Ratio: 4.4161
Check: XXH64

出来上がったファイルを確認すると zstd になっていました.
再起動しても問題ありませんでした :)
上で確認した容量より大分小さ唸っているのは圧縮レベルの差でしょうか?

initramfs圧縮レベルの確認

$ grep zstd /usr/sbin/mkinitramfs
zstd)   compress="zstd -q -19 -T0" ;;

update-initramfs から呼ばれる mkinitramfs を確認するとzstdの圧縮レベルオプションは -19 で最高圧縮率でした.(既定値は -3 )

$ \time -f%e zstdcat -T1 /boot/initrd.img-5.11.8+ > /dev/null
0.50

その分展開時間も少し伸びていそうです.

case "${compress}" in
gzip)   # If we're doing a reproducible build, use gzip -n
        if [ -n "${SOURCE_DATE_EPOCH}" ]; then
                compress="gzip -n"
        # Otherwise, substitute pigz if it's available
        elif command -v pigz >/dev/null; then
                compress=pigz
        fi
        ;;
lz4)    compress="lz4 -9 -l" ;;
zstd)   compress="zstd -q -19 -T0" ;;
xz)     compress="xz --check=crc32"
        # If we're not doing a reproducible build, enable multithreading
        test -z "${SOURCE_DATE_EPOCH}" && compress="$compress --threads=0"
        ;;
bzip2|lzma|lzop)
        # no parameters needed
        ;;
*)      echo "W: Unknown compression command ${compress}" >&2 ;;
esac

周りを見てみると, lz4-9 で最高( -12 )ではないけど既定値( 1 )より圧縮率を高くしてあります.xzには整合性チェックがオプションがあるけど容量にはあまり関係ないかな?
その他は既定値のようです.

$ count=1;while [[ $count -lt 19 ]];do zstdcat /boot/initrd.img-5.11.8+ | zstd -T0 -$count -c - > /tmp/zstd-$count.zstd;count=$(( $count+1 ));done
$ ls -1sS --block-size=1 /tmp/zstd-*
56188928 /tmp/zstd-1.zstd
53272576 /tmp/zstd-2.zstd
51761152 /tmp/zstd-3.zstd
51466240 /tmp/zstd-4.zstd
50061312 /tmp/zstd-5.zstd
49614848 /tmp/zstd-6.zstd
47431680 /tmp/zstd-7.zstd
46690304 /tmp/zstd-8.zstd
46424064 /tmp/zstd-9.zstd
45973504 /tmp/zstd-10.zstd
45850624 /tmp/zstd-11.zstd
45686784 /tmp/zstd-12.zstd
45539328 /tmp/zstd-13.zstd
45371392 /tmp/zstd-14.zstd
45309952 /tmp/zstd-15.zstd
44093440 /tmp/zstd-16.zstd
42987520 /tmp/zstd-17.zstd
41705472 /tmp/zstd-18.zstd
41447424 /tmp/zstd-19.zstd
$ ls -1S /tmp/zstd-* | xargs -I{} -n1 sh -c "echo -n \"{} \"; \time -f%e zstdcat -T0 {} > /dev/null"
/tmp/zstd-1.zstd 0.37
/tmp/zstd-2.zstd 0.36
/tmp/zstd-3.zstd 0.40
/tmp/zstd-4.zstd 0.47
/tmp/zstd-5.zstd 0.44
/tmp/zstd-6.zstd 0.42
/tmp/zstd-7.zstd 0.40
/tmp/zstd-8.zstd 0.37
/tmp/zstd-9.zstd 0.35
/tmp/zstd-10.zstd 0.40
/tmp/zstd-11.zstd 0.41
/tmp/zstd-12.zstd 0.38
/tmp/zstd-13.zstd 0.39
/tmp/zstd-14.zstd 0.39
/tmp/zstd-15.zstd 0.43
/tmp/zstd-16.zstd 0.37
/tmp/zstd-17.zstd 0.42
/tmp/zstd-18.zstd 0.53
/tmp/zstd-19.zstd 0.68

圧縮レベルごとの容量と展開時間はこんな感じになりました.色々動いている環境なのでおかしそうなところがありますが大体の目安として.

Kernel build時の動作

Kernel 5.11.9 が来ていたのでビルドしてみました.

$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/incr/patch-5.11.8-9.xz
$ cd linux-5.11
$ xzcat ../patch-5.11.8-9.xz | patch -p1
$ grep ^COMPRESS= /etc/initramfs-tools/initramfs.conf
COMPRESS=zstd
$ time make -j`nproc` bindeb-pkg
$ ls -1sS ../*5.11.9*
737300 ../linux-image-5.11.9+-dbg_5.11.9+-5_amd64.deb
 59584 ../linux-image-5.11.9+_5.11.9+-5_amd64.deb
  8040 ../linux-headers-5.11.9+_5.11.9+-5_amd64.deb
  1124 ../linux-libc-dev_5.11.9+-5_amd64.deb
     8 ../linux-5.11.9+_5.11.9+-5_amd64.buildinfo
     4 ../linux-5.11.9+_5.11.9+-5_amd64.changes
$ sudo apt install ../linux-image-5.11.9+_5.11.9+-5_amd64.deb ../linux-headers-5.11.9+_5.11.9+-5_amd64.deb ../linux
-libc-dev_5.11.9+-5_amd64.deb
$ file /boot/initrd.img-5.11.9+
/boot/initrd.img-5.11.9+: Zstandard compressed data (v0.8+), Dictionary ID: None
$ ls --block-size=1 -s /boot/initrd.img-5.11.9+
41602048 /boot/initrd.img-5.11.9+
$ sudo shutdown -r now 'kernel upgrade'

問題なく zstd になりました.

参考URL

Debianのinitramfsの圧縮形式をzstdにしようというバグレポート.bullseyeはフリーズされているので入らない.

環境

$ dpkg-query -W initramfs-tools-core zstd
initramfs-tools-core    0.140
zstd    1.4.8+dfsg-2.1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -srm
Linux 5.11.9+ x86_64