Btrfsのbtrfs-transactionでioが100%になって困る

デスクトップ検索のRecollを試してみようと recollindex コマンドでindexを作ってみました.すると様々なアプリケーションがフリーズ.indexが出来るまでの辛抱だろうと1日ほど放置してみましたが解消しません.
1つのコマンドを発行して実行されるまで何分も掛かってしまいます.

cpuやmemoryはガラガラです.
iotop を叩いてみると btrfs-transaction がほぼ100%で張り付いています.

マウントオプションはこんな感じ.

$ mount | grep \ /\
/dev/mapper/t430s--vg-root on / type btrfs (rw,noatime,nodiratime,ssd,discard,space_cache,subvolid=5,subvol=/)

discard を `btrfs(5) ` で確認するとちょっと怪しいような?

       discard, nodiscard
           (default: off)

           Enable discarding of freed file blocks. This is useful for SSD devices, thinly provisioned LUNs, or virtual machine images; however, every storage layer must
           support discard for it to work. if the backing device does not support asynchronous queued TRIM, then this operation can severely degrade performance, because a
           synchronous TRIM operation will be attempted instead. Queued TRIM requires newer than SATA revision 3.1 chipsets and devices.

       If it is not necessary to immediately discard freed blocks, then the fstrim tool can be used to discard all free blocks in a batch. Scheduling a TRIM during a period
       of low system activity will prevent latent interference with the performance of other operations. Also, a device may ignore the TRIM command if the range is too
       small, so running a batch discard has a greater probability of actually discarding the blocks.

       If discarding is not necessary to be done at the block freeing time, there’s fstrim(8) tool that lets the filesystem discard all free blocks in a batch, possibly not
       much interfering with other operations. Also, the device may ignore the TRIM command if the range is too small, so running the batch discard can actually discard the
       blocks.

SATAのバージョンを確認すると 3.2 なので問題無さそう?

$ sudo smartctl --info /dev/sda | grep ^SATA
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)

でも一旦無効にしてみます.
#ついでに付けた compress=lzo は別でやるべきだった…….

$ time sudo mount -o remount,rw,noatime,nodiratime,ssd,nodiscard,compress=lzo,space_cache /
real    42m32.840s
user    0m0.014s
sys     0m15.209s
$ mount | grep \ /\
/dev/mapper/t430s--vg-root on / type btrfs (rw,noatime,nodiratime,compress=lzo,ssd,space_cache,subvolid=5,subvol=/)

これが当たりだったようでioは一気に空きました!
SATA 3.2 だけど何か別の条件が良くないのでしょうか?

忘れないうちに fstab も修正しておきます.(nodiscard は既定値なので書いていない)

 sudo git -C /etc diff HEAD^ -- /etc/fstab
diff --git a/fstab b/fstab
index b029749..386278f 100644
--- a/fstab
+++ b/fstab
@@ -5,7 +5,7 @@
 # that works even if disks are added and removed. See fstab(5).
 #
 # <file system> <mount point>   <type>  <options>       <dump>  <pass>
-/dev/mapper/t430s--vg-root /               btrfs   noatime,nodiratime,ssd,discard,space_cache 0       0
+/dev/mapper/t430s--vg-root /               btrfs   noatime,nodiratime,ssd,compress=lzo,space_cache 0       0
 # /boot was on /dev/sda2 during installation
 UUID=cba2591a-12da-481e-b239-c002faca22e1 /boot           ext2    defaults        0       2
 # /boot/efi was on /dev/sda1 during installation

これで暫く様子を見てみます.
問題なければ別途TRIMを設定したほうがいいかな?

環境

$ dpkg-query -W btrfs-progs iotop smartmontools
btrfs-progs     5.2.1-1
iotop   0.6-24-g733f3f8-1
smartmontools   7.0-2
$ sudo smartctl -i /dev/sda | grep -E '^Device Model:|Firmware Version:|SATA Version is:'
Device Model:     Seagate BarraCuda SSD ZA1000CM10002
Firmware Version: STAS1024
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Google PhotoにHEIC形式でアップロードして16MP制限を回避する

※このエントリを書いてるうちにHEIC形式のファイルが縮小されないのはバグだという記事がでてきました.そのうち修正されてこの回避方法は使えなくなるはずです.

Google Photoの設定でアップロードサイズを「高画質」にしておくと16MPを超えるサイズの画像は16MPに縮小されますが容量を気にせず無制限でアップロードできます.
最近iPhoneの写真は16MPを越えていても無制限にアップロードできると話題になりました.これはiPhoneの写真はHEIF形式で保存され,これを16MPにするためにデコード&エンコードすると元の画像より大きくなるのでそのままにしているのではないかと言われたりしています.

この理由が正しいのであればiPhoneでなくともHEIF形式に変換してアップロードした画像はオリジナルサイズで保存されるではないかと試してみました.

先ず手持ちのカメラ(Pentax K-5)でRAW撮影して現像したファイルを確認してみます.

$ identify ./H-IIBF8_HTV8.TIFF
./H-IIBF8_HTV8.TIFF TIFF 4942x3276 4942x3276+0+0 16-bit sRGB 73.7626MiB 0.000u 0:00.000
$ echo $(($(identify -format "%w*%h" ./H-IIBF8_HTV8.TIFF)))
16189992

4942 x 3276 = 16189992ピクセルで制限の16MPを少し超えていそうです.
2**20*16 = 16777216 よりは小さい(MiP?)

この画像をアップロードしてみます.アップロードにはgpupを使いました.

$ gpup ./H-IIBF8_HTV8.TIFF

アップロードしたファイルの情報を見るとこうなっていました.16.2MPで縮小されていないようです.

H-IIBF8_HTV8.TIFF
16.2 MP
4942 × 3276
77.3 MB

念の為設定を確認.

設定画面( https://photos.google.com/settings )にアクセスして,「高画質 (容量制限なし、無料)」にチェックが入っているのを確認します.

問題ないようです.

ちなみに,「元のサイズ」に設定した状態でアップロードした動画を「容量を解放」することで16MPに変換してGoogleドライブの容量を解放することも可能です.

HEICとJPEGも同様にアップロードしてみます.

$ convert ./H-IIBF8_HTV8.TIFF ./H-IIBF8_HTV8.heic
$ convert ./H-IIBF8_HTV8.TIFF ./H-IIBF8_HTV8.jpg
$ ls -1HSs ./H-IIBF8_HTV8.*
75536 ./H-IIBF8_HTV8.TIFF
 2632 ./H-IIBF8_HTV8.jpg
  688 ./H-IIBF8_HTV8.heic
$ gpup ./H-IIBF8_HTV8.heic ./H-IIBF8_HTV8.jpg

これも縮小されませんでした.

この画像は16MPを少し超えている程度なので縮小されないのかもしれません.もっと大きな画像で試してみます.

といっても自分の手持ちのカメラではこれが最大なので,画像を結合して作成します.(ちなみに処理時間はHEIC:56s, JPEG:3s)

$ convert -append H-IIBF8_HTV8.heic H-IIBF8_HTV8.heic 32MP.heic
$ convert -append H-IIBF8_HTV8.heic H-IIBF8_HTV8.heic 32MP.jpg
$ ls -1Ss 32MP.*
3572 32MP.jpg
1260 32MP.heic
$ identify 32MP.*
32MP.heic HEIC 4942x6552 4942x6552+0+0 8-bit YCbCr 0.010u 0:00.000
32MP.jpg JPEG 4942x6552 4942x6552+0+0 8-bit sRGB 3.4858MiB 0.000u 0:00.000
$ gpup 32MP.heic 32MP.jpg

結果はHEICは約32MPのまま 未圧縮 ,JPEGは 16 MP 3473 × 4605 になっていました.

同様に倍を試してみると HEIC 64.8 MP(9884 × 6552)未圧縮 となりました.
convertでキャッシュリソースが足りなくて転けたりしつつ更に倍( 9884 x 13104 )を試してみるとgpupでは「Failed: There was an error while trying to create this media item. (code=3)」,Chromiumでは「アップロードできません」というエラーメッセージが表示されアップロードに失敗しました.
容量は4.3MBほどしかないのでそのあたりは問題ないはずで解像度のリミットがありそうです.

てことで,少なくとも HEIC 64.8 MP(9884 x 6552) までは未圧縮でアップロード可能でなようです.
64.8 MP〜129.6MP の間に最大値があると思いますが今の所手持ちの機材では関係がないので確認していません.

環境
$ dpkg-query -W imagemagick chromium
chromium        76.0.3809.100-1
imagemagick     8:6.9.10.23+dfsg-2.1+b2
$ gpup -h 2>&1|grep Version
Version 1.x
$ git -C ~/go/src/github.com/int128/gpup/ log --oneline -1
fb48ce5 (HEAD -> master, origin/master, origin/HEAD) Merge pull request #27 from harupong/patch-1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Imagemagickで画像変換時にキャッシュリソースが足りなくて転ける

Google Photoにheic形式でファイルをアップロードすると「高画質」(16MPに縮小される)設定でも縮小されないようなのでどのくらいのサイズまでOKなのかを試していたのですが,倍々で画像結合していたら128MPほどのファイル作成時に失敗しました.

$ convert -append out.heic out.heic out128.heic
convert-im6.q16: cache resources exhausted `out.heic' @ error/cache.c/OpenPixelCache/4083.

処理しているファイルは無駄にでかいです.

$ identify ./out.heic
./out.heic HEIC 9884x6552 9884x6552+0+0 8-bit YCbCr 0.020u 0:00.010

このあたりのページを参考にポリシーファイルを修正してメモリを増やしてみます.

$ sudo git -C /etc diff /etc/ImageMagick-6/policy.xml
diff --git a/ImageMagick-6/policy.xml b/ImageMagick-6/policy.xml
index 59d2fc6..4c6d088 100644
--- a/ImageMagick-6/policy.xml
+++ b/ImageMagick-6/policy.xml
@@ -57,8 +57,8 @@
   <!-- <policy domain="system" name="memory-map" value="anonymous"/> -->
   <!-- <policy domain="system" name="max-memory-request" value="256MiB"/> -->
   <!-- <policy domain="resource" name="temporary-path" value="/tmp"/> -->
-  <policy domain="resource" name="memory" value="256MiB"/>
-  <policy domain="resource" name="map" value="512MiB"/>
+  <policy domain="resource" name="memory" value="2048MiB"/>
+  <policy domain="resource" name="map" value="4096MiB"/>
   <policy domain="resource" name="width" value="16KP"/>
   <policy domain="resource" name="height" value="16KP"/>
   <!-- <policy domain="resource" name="list-length" value="128"/> -->

うまく行くようになりました :)

$ time convert -append out.heic out.heic out128.heic; echo $?

real    2m33.128s
user    6m42.527s
sys     0m4.704s
0
$ ls -l out128.heic
-rw-r--r-- 1 matoken matoken 4286359 Oct 20 00:30 out128.heic
$ identify out128.heic
out128.heic HEIC 9884x13104 9884x13104+0+0 8-bit YCbCr 0.000u 0:00.010

でも割り当て過ぎな気もするのでも少し減らそう.

$ dpkg-query -W imagemagick
imagemagick     8:6.9.10.23+dfsg-2.1+b2
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Google KeepのデータをCarnetにインポートする

Google Keep代替にCarmetを試してみようと思い先ずはCarnetのLinuxアプリにGoogle Keepのインポート機能があるのでそれを試してみました.

CarnetのLinuxアプリは以下のページからElectron製のi386, amd64 それぞれのAppImageが入手できます.

今回はamd64の current64.AppImage を利用しました.
ダウンロード後,実行権を付与して起動します.

$ wget https://qn.phie.ovh/binaries/desktop/current64.AppImage
$ mv ./current64.AppImage ./Carnet.AppImage
$ chmod u+x ./Carnet.AppImage
$ ./Carnet.AppImage

Settings で設定画面を開き, Import from Google Keep (only on desktop client) で Google Keep のImport画面に移動します.

Keep2Carnet 20191018 22:10:06 32370.jpg.s

先ずは Follow this link からGoogle Takeout に移動します. https://takeout.google.com/settings/takeout

Keep2Carnet 20191018 22:10:20 32675.jpg.s

Google Takeoutにて,「新しいアーカイブの作成」の「追加するデータの選択」で「選択を全て解除」した上で「Keep」にだけチェックを付けて一番下の「次のステップ」を押し,「アーカイブを作成」します.

Keep2Carnet 20191019 05:10:50 19472.jpg.s

しばらくすると(データ量により時間は変わる)Takeoutのデータをダウンロードできるようになるので適当な場所にダウンロードして展開しておきます.

展開したらCarnetアプリに戻り,「PATH TO EXTRACTED ARCHIVE」ボタンを押し,展開したKeepのパスを指定します.

Keep2Carnet 20191018 22:10:44 831.jpg.s

パスを指定したら「PICK FOLDER」ボタンを押してインポート対象を選択して「IMPORT」ボタンでインポート開始.

Keep2Carnet 20191018 22:10:13 1597.jpg.s

順調に行けばこれで終わりですが,いくつかの日本語ファイルでインポートが止まりました.

Keep2Carnet 20191018 22:10:17 1731.jpg.s

一旦画面を閉じて確認すると止まったファイルはインポートできているようでした.そのファイルを削除して再度インポート.
しかしまた止まったのでそのファイルがインポートされているのを確認してファイル削除して再度インポートすることで読み込みが終わりました.

自分の環境では2回止まりそのどちらも日本語ファイル名でした.日本語ファイル名だと必ず止まるというわけではなく問題なくインポートされた日本語ファイルのほうが多かったです.

とりあえずインポートできたのでGoogle Keep代替として試してみようと思います.

add)
インポートしたKeepのTodoリストは
☐ hoge
☑ fuga
な感じのテキストになっていました.Todoに戻すのが少し面倒.

環境
$ curl -s https://qn.phie.ovh/binaries/desktop/current_version
0.18.5
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

LinuxとAndroidで動作するGoogle Keep代替を探す

Google Keepはメモアプリです.Evernoteに似ていますがもう少し機能が少ない感じ.

自分は主にTodoや買い物リストなどにKeepを利用しています.PCやAndroidで買い物をメモしてお店でAndroidのメモを見ながら買い物してチェックボックスをチェックしていく感じです.
メモの数もまだ少ないし使っている機能も少ないので代替になるものがあるのではと探してみました.

要件としてはこんな感じ

  • OSS
  • サーバ側はWebDAVなどでセルフホストが利用可能
    • 若しくはクラウドサービスを使うけどE2EEが利用可能
  • LinuxとAndroidで動作する
    • Android版では買い物メモをデスクトップウィジットで表示したい

Joplin

現在EvernoteとZim Wikiから乗り換えて作業メモなどに利用しています.サーバはNextcloudなどWebDAVが利用でき,単体でE2EEが可能です.
LinuxではAppimageやnodeでのcli版もあり,cli版はarmなどでも動作します.

既にあるノートを全部同期するのは大変,同期ディレクトリを分けることは出来ますがクライアントは1箇所しか登録できないので難しい.ノートブック単位で同期できればいいのですが今の所出来ないようです

それとAndroidでのウィジットはフレームワークでサポートされていないので今の所サポートされないようです(◞‸◟)

とりあえず見送りです.

Carnet

Google Keep代替のアプリのようです.Linux,Android,Webで利用でき,デスクトップ版はElectron製のAppimageが用意されていてGoogle Keepからのインポート機能も付いています.これはGoogle TakeoutでExportして展開したものを指定することでインポートできるようです.
同期先サーバはNextcloudかCarnetのサービスの https://carnet.live です.

今の所暗号化は未対応.

AndroidでのウィジットはIssueに上がっています.

Linux armで動作しない&暗号化未対応だけれどelectronではないLinuxアプリを開発中だし暗号化もウィジェットもIssueにあがっているので将来に期待しつつGoogle Keepをインポートして試してみようと思います.(Takeout待ち……)

add)
Web版はhttps://carnet.live だけかと思っていたのですが,NextcloudアプリのCarnetを導入することでNextcloudでWeb版が利用できます.

add)
インポートしてみました.

localeが足りなくてmcomixが起動しなくなっていた

mcomix が起動しなくなりました.こないだのエンバグ?と思ったけど

エラーが違う.

$ mcomix
Traceback (most recent call last):
  File "/usr/bin/mcomix", line 11, in <module>
    load_entry_point('mcomix==1.2.1', 'console_scripts', 'mcomix')()
  File "/usr/lib/python2.7/dist-packages/mcomix/run.py", line 127, in run
    i18n.install_gettext()
  File "/usr/lib/python2.7/dist-packages/mcomix/i18n.py", line 71, in install_gettext
    locale.setlocale(locale.LC_ALL, '')
  File "/usr/lib/python2.7/locale.py", line 581, in setlocale
    return _setlocale(category, locale)
locale.Error: unsupported locale setting

localeぽいので適当に指定してみると起動.

$ LC_ALL=C mcomix

しかし,C だと日本語ファイル名などでエラーとなる.

UnicodeEncodeError: 'ascii' codec can't encode characters in position 25-27: ordinal not in range(128)
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/mcomix/file_chooser_base_dialog.py", line 215, in _response
    if os.path.isdir(path):
  File "/usr/lib/python2.7/genericpath.py", line 49, in isdir
    st = os.stat(s)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 25-27: ordinal not in range(128)

en_US.UTF-8 だととりあえず利用できるけど,ja_JP.UTF-8 とかで日本語を指定すると……うまく行かない?

$ export LC_ALL=ja_JP.UTF-8 mcomix
bash: warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8)

localeを確認するとインストール時に設定していたつもりの ja_JP.UTF-8 がありません.

$ grep -v ^# /etc/locale.gen |uniq

en_US.UTF-8 UTF-8

/etc/locale.gen を編集して,ja_JP.UTF-8 のコメントを外して locale-gen コマンドで生成したら動くようになりました.

$ sudo git diff HEAD~~ /etc/locale.gen
diff --git a/locale.gen b/locale.gen
index c432a9a..afb6141 100644
--- a/locale.gen
+++ b/locale.gen
@@ -287,7 +287,7 @@ en_US.UTF-8 UTF-8
 # it_IT@euro ISO-8859-15
 # iu_CA UTF-8
 # ja_JP.EUC-JP EUC-JP
-# ja_JP.UTF-8 UTF-8
+ja_JP.UTF-8 UTF-8
 # ka_GE GEORGIAN-PS
 # ka_GE.UTF-8 UTF-8
 # kab_DZ UTF-8
$ sudo locale-gen
Generating locales (this might take a while)...
  en_US.UTF-8... done
  ja_JP.UTF-8... done
Generation complete.
環境
$ dpkg-query -W locales mcomix
locales 2.29-1
mcomix  1.2.1-1.1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

略語郎のサンプルテキストをstardict形式に変換してGoldenDictで利用

過去に購入したことのあるEDPさんが新しいその他書籍を公開しました!

略語郎 Ver.144(2015年3月20日版)のテキストデータ
その他書籍 略語郎 Ver.144(2015年3月20日版)のテキストデータ ¥ 150

EDPの英辞郎はStarDict形式に変換して辞書閲覧ソフトのGoldenDictで利用していおます.
略語郎も同様に利用できないかとサンプルテキストで試してみました.

以前英辞郎を変換したときと同じ手順で試しました.

$ time perl eiji2sd-text.pl ryakugoro-sample.txt

Sorting...

Done.

real    0m0.277s
user    0m0.178s
sys     0m0.017s

20190906 21:50:35 8570

変換した辞書ファイルをGoldenDictに設定して試してみるとうまく動いているようです.
150円だし買ってもいいかも.

環境
$ dpkg-query -W perl goldendict
goldendict      1.5.0~rc2+git20181207+ds-1
perl    5.28.1-6
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

awesome wmでパスを追加する

bashだと~/bin とかにパスが通っているのにawesomeからmod4 +r で起動しようとするとコマンドが見当たりません.

20190830 14:08:46 21926

AppImageやFlatpakなんかのアプリを格納したりしているのですがこれだと /home/user/bin/command とかフルパスで書かないと駄目です.

bashだとパスが通っています.

$ type -a MQTT-Explorer
MQTT-Explorer is /home/matoken/bin/MQTT-Explorer
$ ls -l /home/matoken/bin/MQTT-Explorer
lrwxrwxrwx 1 matoken matoken 71 Aug 25 21:22 /home/matoken/bin/MQTT-Explorer -> /home/matoken/opt/AppImage/MQTT-Explorer-0.3.6-no-delete-limit.AppImage

awesomeで,mod4 + r して sh -c "$PATH >> ~/tmp/awesomepath" とかして PATH を確認してみるとこれだけしかパスが通っていません.

$ cat ~/tmp/awesomepath
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

~/.xinitrc でパスを追加してみましたが反映されません.
多分lightdm経由で起動しているので関係なかった.

$ ps auxf|grep -B3 awesome
root     32202  0.0  0.0 309612  5532 ?        SLsl  8月29   0:00 /usr/sbin/lightdm
root     32208  1.2  0.5 430424 82396 tty7     Ssl+  8月29  10:48  \_ /usr/lib/xorg/Xorg :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch
root     32283  0.0  0.0 163604  5856 ?        Sl    8月29   0:00  \_ lightdm --session-child 12 21
matoken  32293  0.1  0.6 350760 99060 ?        Ssl   8月29   1:18      \_ awesome

~/.Xsession に`PATH=$HOME/bin:$PATH` のような感じでパスを追加するとパスが通りました.でもパスの追加しか書いていないと色々と起動しないサービスがあります.
大本の`/etc/X11/Xsession` をcpしてきてそのファイルにパスの設定を追加したらOKでした.

$ cp /etc/X11/Xsession ~/.Xsession
$ echo 'PATH=$HOME/bin:$PATH' >> ~/.Xsession

これパスの管理一緒にしたいですね.

環境
$ dpkg-query -W awesome lightdm
awesome 4.3-4
lightdm 1.26.0-5
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Google Chrome 76 でまた特定のサブドメインが表示されなくなったので表示するようにする

Google Chrome 69 のときも一時的に表示されなくなっていたのですが,

Google Chrome 76 でまた特定のサブドメインが表示されなくなりました.

例えば, www.matoken.orgmatoken.org と省略されます.

20190811 16 08 30 974

ちなみに 69 のときは www.hoge.www.matoken.orghoge.matoken.org に見えるというバグらしき動きもありましたがこれは hoge.www.matoken.org に見えるようになっていました.

20190811 16 08 11 478

今回も Google Chrome 69 のときと同じように chrome://flags/#omnibox-ui-hide-steady-state-url-trivial-subdomains を Disabled にすると以前の挙動に戻ります.

20190811 16 08 11 3832

今回 Chromium 76 でも試してみましたが,この変更は入っていないようでサブドメインは省略されませんでした.

環境
$ dpkg-query -W google-chrome-stable chromium
chromium        76.0.3809.100-1
google-chrome-stable    76.0.3809.100-1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

mono製InlineHtmlImagesでhtml+画像の複数ファイルを単一の画像埋め込みhtmlに変換する

npm の html-inline を試しましたが途中でコケてしまいます.

mono製の InlineHtmlImages を試すとうまくいきました :)

画像作成
$ convert pango:"<span font=\"/Library/Fonts/NotoColorEmoji\" size=\"24576\">😺</span>" cat.jpg
html作成
$ cat << __EOF__ > cat.html
> <html>
> <body>
> <img src="cat.jpg">
> </body>
> </html>
> __EOF__
画像埋め込み
$ mono ~/Downloads/inlinehtmlimages-mono.exe -in ./cat.html -out ./cat_inline.html
埋め込まれているのを確認
$ cat cat_inline.html
<html>
<body>
<img src="data:image/png;base64,
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAmACgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD1jV/EEllqzWqSpEEUH5o9wYkZ554qS38TMSUktvNcDh4D8uffPT8zWX4p0xptegkwRFNH8x916/piokurKK5WxSeBZwuRBvG7HrjrXx+Kx+MoYqpGMtE9t9D2I0aEqMXbVo1P+EubZ5n2D5PM8v8A13Of++aluPErAhIrfymIyWnPH4Y6/mKwvsB8gR+YOJvMzj36U97qymuGsGnhacrkw7xvx6461zrOMbJNKX4L/IuWGw6asvzNbR/EEl7qotWlSUMpOVj27SPTnmiqHhXTWh1y4kPMcUeFPqW6foDRX0eT1KtTDKdV3bb+44MdGEKtqfZE3ifWbC01a2gurgQMsTcyqVQ5K9GI2np2NcUvhJp/GK6/Hfxvas4mAXlicYwD0x/Tiuv8aR3E06Q219dvcld0Vja2ysxHQszsCFH1wOK871K58QaJDBe2NpHdxhNlxZyZYoQThgU2noeQO46Vw46hUhipSpyUXUVtdtvTTY1oNTpK6b5ex0Qudd/4TQ2P2i3/ALO8vz8bPm2dNvrnP+e1Uh4SNt4xfX5b9FtQ5mKtwwJGME9Mc/0rHbxlqAt/tY8LWf2jZt/4/wBy+OuNuc/hmpdLn1/V7W5vb+2jtxKgS3s4wVz8wJY79xzxgZ/SuSWGq4ePMpxSa5Xbrf5fidDjzNKUJX3V1Y9J8L6zYXeqXUFrcCcmNDuiUsgwWzlgNo6jvRUPgyO4hlkguL66W5C7prG6tkRlHRWV1ADD3GRzRX0WAoeww8ab6f538jy68+eo2drWTf6BZag5kZWilPWSM4J+o6GiiuirRp1Y8tRXREKkqbvB2Zl/8IXF5m77Yf8Av0M/nmtWw0Gy09xIitJKOkkhyR9OwoornpZfhqUuaENfv/M2ni61RWlLQ1aKKK7DnP/Z" alt='cat.jpg' >
</body>
</html>
画像ファイルを削除しておく
$ rm ./cat.jpg
ウェブブラウザで確認
$ xdg-open ./cat_inline.html

20190811 02 08 14 32387

他にもLinuxネイテイブなものがありそうな気がします.(shell script + base64 コマンドでも多分行ける?)

環境
$ mono ~/Downloads/inlinehtmlimages-mono.exe -help|head -6|uniq

InlineHtmlImages v1.7
 Build:  3/31/2018
 Author: Dennis Lang
 Web:    home.comcast.net/~lang.dennis
$ dpkg-query -W mono-runtime chromium imagemagick libpango-1.0-0
chromium        76.0.3809.100-1
imagemagick     8:6.9.10.23+dfsg-2.1
libpango-1.0-0:amd64    1.42.4-7
libpango-1.0-0:i386     1.42.4-7
mono-runtime    5.18.0.240+dfsg-3
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64