更新日:
投稿日:

私は2020年の末あたりからLet's EncryptのDNS-01 challengeをValue-Domainで達成するためのスクリプトであるvalue-domain-dns-cert-register (vddcr)の開発を行ってきていたのだが、メンテが辛くなってきたので、今回Shellscript(Bash)Perlでvalue-domain-dns-utilとして作り直した。その経緯と、開発中の学び、そして最後にどうやって作っていったかについて書いていく。

背景

一年半ほど前からTypeScriptに限界を感じてきたことや、当時の誤った単体テストへの偏執により、vddcrはメンテしたくない状態になってしまっていた。

そこで昨夏、つまり2025年の8月に式年遷宮、つまり全体的な書き直しを行ったのだが、個々の処理をする部品を作ったまではいいものの、それらを繋ぎ合わせるところで飽きてしまい、放置していた。vddcrはこの時点で事実上の放棄状態だった。

しかし、自宅サーバーの運用をしていく中で別の目的でValue-DomainのDNS APIと関わらなければならない必要が出てきたため、今回、vddcrの置き換えも兼ねて新しく作り直すことにしたのだ。

具体的には複数ドメインに対するDDNSをバルクでやりたい要求が生まれたが、Value-DomainにあるDDNS APIは一度に1ドメインしか処理できない上にレートリミットが60秒に1回と極めてキツく、複数ドメインに対して行うには余りにも遅延が大きかった。

例えば10ドメイン更新しようとすると10分もかかるわけで、これでは使い物にならないというので、DNS APIを直に叩いて一気に書き換える必要性が出てきたのだ。どうせ作るならvddcrが担っていたDNS challengeの機能も包含できる形にしたかったので、Value-DomainのDNS APIを便利に叩くためのツールキットとしてvalue-domain-dns-utilを作ることにした。

つまりvddcrの純粋な後継ツールというよりは、vddcrの役目もこなせるツールキットを開発し、vddcrと同等の機能を有するツールを実装サンプルとして同梱したわけだ。

Shellscriptにした理由

ものの数時間でPerlに直したので過去の話となった。移植性の関係でbashはイマイチだった。

ぶっちゃけそんなに大した理由はなくて、単に目の前にターミナルとテキストエディタがあってパッと組めたからという部分が大きい。実際ベースはパッと作れた。まぁ作って半年も放置していたのが…。ただまぁPerlの方が保守性は高いだろうし、移植性もあるだろうとは思うから、気が向いたら書き直すかもしれない。

ちなみに別言語に移植することの検討はvddcrでも行っていたが、最終的には候補になかったShellscript(Bash)での実装に落ち着いた。そもそもこの課題の存在を忘れていたので、検討すらしていなかったのである。

value-domain-dns-utilについて

今回作ったvalue-domain-dns-utilは、vddcrの単純な代替ではなく、Value-DomainのDNS APIを叩くのに便利なShellscriptの関数群だ。DNS challenge以外にも用が生まれたので、このような汎用的な形になっている。

DNS APIから現在のレコードを取得する関数や、取得したレコードから先頭一致のパターンマッチでレコードを取得する関数、レコードリストへの追加や置換をする関数、そして編集したレコードをDNS APIに送り戻す関数を備えており、DNSに関する一連の編集処理ができるように便利に作っている。

結果として、Value-DomainのDNS APIを叩く汎用機能があれば、それを流用してLet's EncryptのDNS-01 challengeもできるし、当然複数ドメインに対するDDNSをバルクでやることも可能になる。

学び

開発中に発見も多くあったので記していく。なんかこういうのまとめた記事かページ作りたいね。

echoでドルマーク始まりのシングルクォート文字列を作ると、その中の改行コードが展開される

例えば以下のようになる。これは一行で改行展開を書けて変数に入れられるので、インデントされているコードなどで物理的にへし折りたくないときなどに有用だし、文字列としてのコードが見えるのでわかりやすい部分もあると思う。

入力

#!/bin/bash

# ドルマーク始まりのシングルクォート文字列は改行が展開される
echo $'1:aaa\nbbb'

# つまりこれと同じ
echo "2:ccc
ddd"

# ダブルクォートの中の\nは展開されない
echo "3:eee\nfff"
# ドルマーク始まりのダブルクォートも展開されない
echo $"4:ggg\nhhh"

# 一行で改行展開を書けて変数に入れられるので便利
hoge=$(echo $'5:iii\njjj')
echo "$hoge"

出力

1:aaa
bbb
2:ccc
ddd
3:eee\nfff
4:ggg\nhhh
5:iii
jjj

変数の最後の一文字を削る

これは後方一致除去(${parameter%word})と呼ばれるものらしく、詳しくは調べていないが"hoge"に対してfugaを繋げ、"hogefuga"としたい場合に便利だ。

例えば以下のように書ける。

入力

#!/bin/bash

hoge='"hoge"'
fuga='fuga'
result="${hoge%?}$fuga"'"'

echo $result

出力

"hogefuga"

sedで改行を改行コードに置換(\n\\n

これは見つけた当時sedの記事にも書いているが、以下のようになる。

入力

cat <<'EOF' | sed ':a;N;$!ba;s/\n/\\n/g'
aaa
bbb
ccc
ddd
EOF

出力

aaa\nbbb\nccc\nddd

[]ではGlob展開できないが、[[]]では出来る

今のところこういった形式でGlobを書くことはないのだが、Sonnet 4.6にテストコードを書かせている中で発見したので書き留めておく。

入力

#!/bin/bash

hoge='aaabbbccc'

[ $hoge = *"bbb"* ]
result1=$?
[[ $hoge = *"bbb"* ]]
result2=$?

echo $result1
echo $result2

出力

1
0

あとがき

LLMとの作業分担

今回の開発でもLLMを活用したのでその辺り。

今回の開発では、8ada152~93d58ccのコミットを行った。最も古いコミットである8ada152ではテストコードを除き、私がフルスクラッチで書き、テストコードはClaude Code(Sonnet 4.6)に書かせた。

次の029a951では、私が書いたコードをClaude Code(Sonnet 4.6)に全体的に直してもらって私がレビュー・微修正するという開発形態をとった。それ以降のコミットはコメントなどの微修正なので、再び私が手動で書いている。

こうした分担により、設計の根底にある信条のようなものには私の色が濃く出ているが、実装上の問題点はClaude Codeによって大きく改善されている。特に029a951では、typoや単純な実装ミスの修正に加えて、bashの文字列処理に不慣れなことで生まれたエスケープシーケンスの山が整理された。jqの-rオプションの有無がまちまちだった部分も統一され、可読性がだいぶ向上したと思う。

とはいえ、Claude Codeの言うことを鵜呑みにはしていない。こちらから明示的に指示して直させた箇所もある。例えばテストコードのappend_recordreplace_recordのアサートは元々Globで書かれていたのだが、より厳密にするために全文マッチに直させた。別にレコードの順序がどうなっていようとValue-Domain APIは気にしないどころか勝手にソートされるので実用上の意味はないのだが、こういうのは人としての拘りである。

昨今は過去の記事でもちょいちょい言及している通り、LLMを使った開発をそこそこしていて徐々に馴染めてきているので、その点も含めてよい経験になった。

抽象化した今回の設計と、過去の歪な設計を振り返って

抽象化して再利用性を高めた今回のツールキット方式と、単体テスト大正義とばかりに変な作りになってしまった前回の方式の振り返り。

過去のvddcrでは単体テストへの誤った偏執によりモジュールが具象的な単位で分割され、非常にメンテナンス性が悪く、再利用性もないものになっていたが、今回はちゃんと抽象化して、責務ごとに機能が切れたと思っている。このことによって再利用性が高く、使いやすいものが作れたと考えている。大した規模ではないとはいえ、部品を組み合わせて処理を組むには程よくいい感じだろう。

先ほどのことや、単純に機能を削ったこと、TypeScriptの複雑すぎる型管理や非同期処理から解放されたこともあり、コードもだいぶ見通しがすっきりした。ツールではなく、ツールキットという形で作ったことも奏功し、Value-DomainのDNS API周りのスクリプトは大分作りやすくなったと思う。将来的にバルクのDDNSスクリプトを書くのも楽になるはずだし、重い腰を上げて作れてよかった。

式年遷宮で起きる変遷について

式年遷宮をする以上、元の状態には戻れないという話があり、それが何故起きるのかみたいなところが分ったような、分からないような、そんな話。

しかし世の中には式年遷宮で全く違う姿になるものがある。今回作ったのはまさにそんな感じで、なんというか作者の気持ちがわかった気がする。

分かりづらい例えだが、FF14の外部ツールであるConcept Matrix(CMTool)がAnamnesisに変わったときは、全く別物になった気さえしたし、こういった式年遷宮によって元あったことは一応できるにはできるけど、複雑になったり、なんかかゆいところに手が届かなくなったり…みたいなのは他でもちょいちょいあると思っていて、今回vddcrをvalue-domain-dns-utilにしたのもまさにそうだと思う。

という背景があるのもあり、完全互換を目指したvd-dcr.shを同梱することで、この不便さを少しはなくそうとした。いやまぁ自分のためにやってるので、自分のためのことではあるのだが…。とはいえ、以前のと比べるとプラットフォーム別の互換性は落ちていると思うので、現時点だと動かない環境は増えている気がする。

あとがき2:結局Perlに変えた

動かそうとしてた環境の一つのシェルがashで、bashが使えないことに気が付いたのでSonnet 4.6に頼んでサッとPerlに変えてもらった

関連記事

投稿日:

私は布団を床に敷いている、いわゆる万年床生活を送っているが、ここ数年布団がずれる問題に悩まされていた。

そこですべり止めを色々試していたのだが、ニトリのすべり止めシートが効果的だった。

今回購入したのはニトリの「ハサミで切れるすべり止めシート 130x185cm」だ。

布団はこんな感じに置いていて、奥の棚との間にスペースを作っているのだが、今まではこれが日に日にズレるので困っていた。

今は設置から九日立つが、全くズレていないので、非常に助かっている。

布団の構造としては、敷布団の下に厚手の防湿マットを敷いていて、その下に滑り止めマットを敷く構造になっている。

布団がずれないことによりクイックルワイパーをスムーズに挿入でき、掃除も捗るようになった。

棚と布団が接触していた時は、その隙間に埃が溜まっていて掃除に難儀していたり、右側の電源ボックスが挟み込まれてしまい、奥の引き出しを出すのが手間だったりした。これが解決したので随分楽になった。

あとがき

これまではすべり止めシールや、すべり止めテープを使っていたのだが、どうも接触する面積が少ないからか滑ったり、逆にシールが剥がれたりしてうまく機能していなかった。

今回は接触する面積がほぼ全体になり、摩擦抵抗が増えたからだろうか、うまく機能するようになったという具合だ。

投稿日:

なんか気が付いたら動かなくなってた気がするので作業ログとして残しておく。

確認環境

Env Ver
Windows 11 Pro 25H2 OS build 26200.8740
MSYS2 msys2-x86_64-20251213
zsh 5.8 (x86_64-pc-msys)
nvm-windows 1.2.2

MSYS2 msys2-x86_64-20210725でも動作を確認しているため、MSYS2のバージョンはほぼ関係ないと思われる。

前提条件

  • MSYS2とzshは既にあるものとする。
  • Node.jsは入っていないものとする。

やり方

  1. nvm-windowsからインストーラーを落としてインストール
  2. 任意のシェルでnvm onを実行
  3. nvm install ltsなり適当なインストールコマンドを叩く
  4. node -v && npm -vで両方のバージョンが出ればOK

トラブルシューティング

nodeやnpmのコマンドが見つからない

nvm onを実行していないと上手くパスが通らないのでこれを実行する必要がある。

あとがき

nvm onなんてしなくても動いていた気がしたが、久々にWindowsでnodeを叩こうとしたら動かなかったので、ついでに全部の環境を刷新するついでに書いた。

更新日:
投稿日:

Matomoは標準では直帰ユーザーの滞在時間が取れないが、それをできるようにする方法。

実施前 実施後

確認環境

Matomo Version 5.7.1

やり方

トラッキングコードに_paq.push(['enableHeartBeatTimer', 10]);を追加するだけ。

公式ドキュメントを読む限り、これをすることで10秒以上閲覧した場合に滞在時間が取れるようになると思われる。なお、HeartBeatTimerという名前だが、眺めてみた感じ定期的にAPIリクエストを送ったりはしていないようだった。

取り敢えず10秒以下は0と同じでいいと思ったので10にしておくことにした。ビジット継続時間単位のビジットでも11秒以上の敷居があるので、キリもいい。11秒にしたほうがよりノイズが減り、正確かもしれないが、個人的には運用上10秒が取れても害はないので、細かいことは気にしないでおく。

なお、かつては名前の通り指定時間にポーリングしていたようだ。また5秒未満を指定しても機能しないらしい。

コードの追加例

 <!-- Matomo -->
 <script>
   var _paq = window._paq = window._paq || [];
   /* tracker methods like "setCustomDimension" should be called before    "trackPageView" */
   _paq.push(['trackPageView']);
   _paq.push(['enableLinkTracking']);
   (function() {
     var u="https://analytics.example.com/";
     _paq.push(['setTrackerUrl', u+'matomo.php']);
     _paq.push(['setSiteId', '1']);
+    _paq.push(['enableHeartBeatTimer', 10]);
     var d=document, g=d.createElement('script'), s=d.getElementsByTagName ('script') [0];
     g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
   })();
 </script>
 <!-- End Matomo Code -->

あとがき

公式ドキュメントの説明が薄いので、具体的にどう処理されているかはソースコードを読まないとわからないが、取り敢えず直帰ユーザーの滞在時間が見れるようになったので良かった。

一律で0sだと、内容を見ているユーザーと見てないユーザーが区別できないので、ここが分かるのは便利だ。

因みにGoogle Analyticsでも直帰は0秒扱いらしいが、そもそも最近この項目自体が削除されて、別概念に置き換わったらしい

こういったことを踏まえると、やはり私のような個人サイト運営者にとってはMatomoは非常に便利なツールだ。

投稿日:

昔懐かしのシンプルなメモ帳

Windows 11の新しいメモ帳は、CVE[1]が出たり、Markdownをコピペしたら勝手にエスケープされたり、毎回新機能の設定をOFFさせられたりと、新しいメモ帳に愛想が付いてきたので古いメモ帳に戻すことにしたのでそのログ。

新しいメモ帳にはお亡くなり頂き、古いメモ帳だけにした。

やったこと

  1. 新しいメモ帳をアンインストール
    • 実は普通にアンインストールできてしまう
  2. Win+Rでファイル名を指定して実行を出し、notepadを叩く
  3. 「新しいバージョンのメモ帳が利用可能です」「インストール」とか帯が出るので❌を押して消す
  4. タスクバーにいるメモ帳を右クリックしてスタートにピン留めする
    • この作業を行い、notepadと入力して起動、noteと入力して起動、nと入力して起動のように繰り返すことで、以後の起動が楽になる

もしも復活させたい場合

Microsoft StoreにあるWindows Notepadというやつが恐らく同じものだと思われる。

参考までに、これをインストールすると、前述の「新しいメモ帳をアンインストール」で書いた「メモ帳」が復活した。

あとがき

メモ帳なんかプレーンテキストが書ければそれ以上は要らないので昔のメモ帳に戻ってこれてよかった。

UIも無駄に場所を取っていたのがすっきりした。


  1. CVE-2026-20841でWindows Notepad アプリのリモートでコードが実行される脆弱性