標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

Linux のゴミ箱への拙作のライブラリや、はてなブログ コマンドラインクライアントの対応

最近、作り込んでいる はてなブロククライアント だが、投稿テキストをテキストエディターで編集した後、os.Remove で削除していた。だが、何らかのトラブルがあって投稿が失敗したのに検知できなかったという最悪ケースのため、完全削除よりは、復元できた方が安全だ。こういう場合に OS ゴミ箱が使うとよいかもしれない。

Windows の場合は、OS自体にゴミ箱機能が組み込まれていて、

  1. COM: Shell.Application の MoveTo メソッド
  2. Shell32.dll の SHFileOperationW

などを使って、任意のファイルをゴミ箱へ移動させることができる。

Linux の場合、デスクトップ環境が統一されていないため、ゴミ箱について OS としての統一の API はなく、かわりに各デスクトップ環境で共通化するための仕様がある。

抜粋すると次のようなものになる

  • システムには一つ以上のゴミ箱ディレクトリがある
    • どんなユーザでも "home trash" ディレクトリは利用可能でなくてはいけない
      • "home trash" ディレクトリの場所と名前は $XDG_DATA_HOME/Trash
        • $XDG_DATA_HOME が定義されていない時のデフォルトは ~/.local/share/Trash (※ そうではない OS もある)
      • "home trash" は自動的に作成されるべき
      • あらゆる場所のファイルを "home trash" に捨てられるようにしてもよいし、 他所のファイルシステム上にあるファイルはサポート対象外としてもよい
    • ファイルシステムがマウントするディレクトリ $trash に対して、 $topdir/Trash というゴミ箱ディレクトリを作ってもよい
      • (なくても良い。実際、Ubuntu のデスクトップ環境にはなかったし、Go言語で実装されたライブラリ rkoesters/xdg のゴミ箱でも未実装だった。考えてみれば、ホームディレクトリ以外のファイルをユーザがゴミ箱機能で削除するというシチュエーション自体が面倒な割に危険で益も少いので、なくてもおかしい話ではない )
  • ゴミ箱ディレクトリには、files, info という二つのサブディレクトリがある
    • files には元ファイルそのものを、(ユニークな名前) に改名して移動する
      • (ユニークな名前) は他と衝突しない名前であればよいが、削除したファイルの名前をそのまま使ってはいけない(同じ名前のファイルを何回も捨てることだってある)
    • info には元ファイル情報を記録する (ユニークな名前).trashinfo というテキストファイルを削除単位ごとに作成する
      • .trashinfoファイルのフォーマットは次のとおり。 DeletionDate は削除実施日時(ISO8601表現。ローカル時刻でよい)、Path は削除前のパス位置。"home trash" の場合のみフルパスが許されるが、そうでない場合は $topdir からの相対パスを用いる。そして相対パスには ... は使ってはいけない
[Trash Info]
Path=foo/bar/meow.bow-wow
DeletionDate=20040831T22:32:08
  • ディレクトリをゴミ箱に放り込んだ場合は、ゴミ箱の総容量カウントのために $(topdir)/directorysizes というファイルにそのディレクトリの容量を記録しなくてはいけない
    • directorysizesの更新は要排他制御
    • 記録しなくてはいけないのはディレクトリの場合のみで、ファイルは不要
    • フォーマットは次のとおり (mtime は Epoch 秒数なので、(time.Time) Unix でよいようだ)
[size] [mtime] [percent-encoded-directory-name]

以上を踏まえて、以前、Rust で作ったゴミ箱コマンド を Go に移植してライブラリ化し、あわせて、非Windows にも FreeDesktop.org 準拠型として対応した。

v0.2.0 時点では

  • "home trash" のみ。各ファイルシステムごとの $topdir/.Trash には未対応
  • ファイルシステムが違っていて move できないファイル・ディレクトリについては、対象を copy & move する。それゆえレスポンスが悪い場合がある
  • "home trash" や、そのサブディレクトリ files , info が存在しない場合でも、自動的に作成する
    • GUI なしの WSL 環境では、これらが存在しないため
  • (ユニークな名前) として、UUIDv4 を使用
    • 手動で復元するやつなんて、おらんやろ…

テストとして WSL 以外に、VirtualBox上のUbuntu 環境で、本ライブラリで削除したファイルがデスクトップのゴミ箱できちんと表示され、そこから復元もできることを確認した。

そして、はてなブログクライアントも、これを使うよう修正した。