うっかりエンジニアのメモ

未来の自分に宛てたメモ

専門性が心理的安全性をもたらす

最近、心理的安全性の高い職場に必要なのは「個人の専門性」だと考えるようになった。

ある仕事を進めるのにスキルA~Eが必要だとして

  • XさんがA,B
  • YさんがC
  • ZさんがD,E

というスキルを持っていると、互いに自分にない専門性(スキル)を持っているので、意見や提案を尊重できる。その結果、心理的安全性が醸成される。

が、その仕事を進めるのに必要なスキルを持っていないWさんがチームにいると様子は変わってくる。仕事を進める上でWさんの意見や提案を真剣に取り扱う価値はないので、周りはスルーしたり価値のないものとして取り扱う。Wさんは自分の意見に自信が無くなり、無能なのではないかと不安になる。

Wさんにとって心理的安全性を回復するためには

  • 自分のスキルが生きる場所(案件or部署or会社)に行く
  • 今必要とされる専門性を獲得する

のどちらかだと思う。

心理的安全性を声高に叫ぶくせに、現実には特定個人の意見を無視したりぞんざいに扱う環境がたまにある。これは「お母さん全然怒ってないよ」と言葉では発しながら不機嫌そうな表情を子供に向けるやつと同じで、言語的なメッセージと非言語的なメッセージが矛盾している典型的なダブルバインドであり、他人を不安にさせるには十分すぎるやり方。

hrmos.co

DeNA南場さんの「球の表面積」の考え方が良い。
新人~ベテランまで、面積の大小はあれど自分の持ち場があり、共通の目的に向かって貢献している。持ち場が違うから互いをリスペクトできる。

心理的安全性の研修を受ける」とかクソほど役にも立たない。とにかく専門性。

ブルベに向けて

entropiajp.hatenablog.com

10月に納車されたロードバイクに隙あらば乗っています。
冬は寒いけど、晴れの日が多いのでとにかく気持ち良い!

先日100kmはどうにか走れたので、来年はブルベに挑戦しようと思ってる。12月1日が春のブルベのエントリー受付開始日だったので、BRM323神奈川200km横浜湘南に申し込んだ。 翌朝、スポーツエントリーを見ると1月6日の逗子200kmは満員御礼。数年前はエントリー峠が厳しかったらしいけど、今はよほどの人気BRMに限った話なのかな?

今日は鎌倉を経由して、逗子の湘南国際村に。お世話になっているショップの店員におすすめされたコース。

寝坊したのが幸いし、ちょうど丘の上から沈む夕陽を見れて良かった。この数日間は日の入りが1年で一番早いらしい。

ロードバイクをお迎えした

エンデュランスロードバイク TREK Domane SL6 gen4 をお迎えした。

3年クロスバイクに乗ってみて「もっと楽に遠くに行きたい。いろいろな景色を見たい」と思って購入。妻からのダイエット圧力とちょっとした幸運があったことも後押し。

盗難対策はAlterLock

Twitterで「ロードバイク 盗難」で検索するとすごい量の事例がヒットする。自転車盗難ってかなりポピュラーの犯罪(?)で、被害届が出ているものだけでも年間10万件らしい。

とりあえず安定のABUSの鍵。

ちなみにこのABUS BORDO LITE MINI 6055K/60はTOPEAK cage bag XLにシンデレラフィットするのでおすすめ。

ちょっと検討したのは盗難保険。ZuttoRide自転車盗難保険は良さそうだったが、やはり車体価格(≒補償金額)に比例して保険料が数万円とかなり高くなる。そうなると、そもそも盗難が起こらないようにするような対策が良さそう。ということで導入したのがAlterLock

これ凄い。ロックを有効化した状態で車体が揺れると95dBのアラームが鳴り、注目されることを嫌がる犯人に諦めさせる効果がある。同時に、所有者のアプリに通知され、すぐに自転車に駆け付ける必要があることを知らせてくれる。さらに、それでも持ち去られてしまった場合はGPSとSigfoxという通信規格により、現在の位置情報を送信し続けることができる。実際、イギリスでは持ち去られてしまってから犯人の家を特定し、警察により検挙された例もあるとのこと。

保管は室内に 2x4材でラックをDIY

盗難と雨風による痛みを避けたかったので、屋内保管できるようにバイクラックをDIYした。もともと屋外保管していたTrek FX-3も掛けられるようにした。美しい…

  • ラブリコ 強力タイプ
  • ミノウラ バイクハンガー 2x4

今回、強度比較のためにラブリコ強力タイプでバイクラックを、ディアウォールでギター&ラケットバッグラックを作ってみたところ、明らかにラブリコ強力タイプの方が耐荷重大きく安定している印象がある。自転車をディアウォールで掛けるのはたとえ1台であっても外れるリスクが高くお勧めできない。逆に、ディアウォールはそこそこの強度で突っ張るので、設置後も簡単に位置を調整できるメリットがある。

トラブル対策はBycle

パンク、チェーン切れ、体調不良などでライドが続行不可能、自転車ショップどころか最寄り駅までの搬送も厳しい…そんな事態に備えて自転車ロードサービスに加入した。調べてみて良さそうだったau損保のBycleに加入した。

www.au-sonpo.co.jp

火災保険に3億円までの個人賠償責任保険が付いてるので、個人賠償責任保険は外して契約した。2年間で4000円くらい。これで万一の時に50kmまでロードサービスでピックアップしてくれるのはありがたい。

old.cyclesports.jp

ただ、ロードサービスを呼ぶにも携帯がつながらないと詰むので

  • 電波の圏内でライドする
  • モバイルバッテリーを携帯する

ことは順守する。

今後の目標

レーシーな走りは興味がなく、できるだけ遠くに行き、美しい景色、おいしいものを楽しめればと思う。
今年中に100kmライド、来年はブルベ200kmに挑戦したい。

SAN ZANG MASTER製SSDエンクロージャをM1 Macで半年使ってみた

結論:めちゃくちゃお勧めです。

主にDTMで使っているMacBook Pro、CPUはM1 Pro、メモリは32GBということで楽曲制作中にソフトウェア音源やエフェクトをバリバリ差しまくってもファンすら回らず涼しい顔できびきび動いてくれており何不自由ないのですが、ストレージだけは購入時に増量するかどうか迷いました。というのも、MacBook Proは構造上、後からストレージを交換することが不可能で、デフォルトの容量では足りない場合は購入時に内蔵ストレージをカスタマイズして増量するしかないためです。

たとえば現行MacBook Proのストレージはデフォルトで512GB。これを1TBにすると+28,000円、2TBにすると+84,000円(!)になります。先日の自作PC記事でも書いた通り、NVMe SSDの価格はここ半年でかなり下落したので、素のNVMe SSD 2TBであれば13,000円程度で買えてしまいます。いくら円安とはいえ、これはコスパが悪すぎる。

内蔵が高ければ外付け。M1 MacBook ProはすべてのUSB-C端子がThunderbolt 4規格になっており、できるだけ高速に使いたい。ところがThunderbolt 3対応の外付けSSDを買うと6万円前後とこれ また高い。
※Thunderbolt4は3と転送速度は変わらない(40Gpbs)ので気にしなくて良い

NVMe SSDエンクロージャという選択肢

NVMe SSDを入れるとそれを外付けSSDとして使えるケース。

速いほど良いので40Gbps接続を謳うものを選択。最安値1万円ちょっと。ちなみに20Gbpsでも十分であれば5,000円台でも手に入ります。

これとKIOXIA EXERIA PRO 2TBのNVMe SSDを用意しました。

導入手順は以下の記事が詳しいです。 sundaygamer.net

転送速度

3000MB前後で読み書きできており、非常に高速です。RND4Kに至っては、MacBook Proの内蔵SSDよりも高速という結果になっています。

エンクロージャで接続したSSDの転送速度
内蔵SSDの転送速度

一部のSSDはストレージの空き容量が少なくなると性能悪化するものがありますが、EXCERIA PROにしたおかげ(?)なのか、速いままで良かったです。

動作温度

smartctlでS.M.A.R.T情報を確認すると、使用中おおむね45度~50度で推移しており、適正温度内に収まっていると言えます。アルミ筐体の排熱が上手くできているということでしょう。実際、筐体の温度を測ると46度前後になります。火傷はしないですが、ずっと触り続けるのは難しい温度です。

smartctl 7.3 2022-02-28 r5338 [Darwin 21.6.0 x86_64] (sf-7.3-1)
Copyright (C) 2002-22, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Number:                       KIOXIA-EXCERIA PRO SSD
Serial Number:                      626A20E8KA44
Firmware Version:                   EIFA10.1
PCI Vendor/Subsystem ID:            0x1e0f
IEEE OUI Identifier:                0x8ce38e
Total NVM Capacity:                 2,000,398,934,016 [2.00 TB]
Unallocated NVM Capacity:           0
Controller ID:                      1
NVMe Version:                       1.4
Number of Namespaces:               1
Local Time is:                      Sat Jul  1 15:44:46 2023 JST
Firmware Updates (0x12):            1 Slot, no Reset required
Optional Admin Commands (0x0017):   Security Format Frmw_DL Self_Test
Optional NVM Commands (0x005f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x08):         Telmtry_Lg
Maximum Data Transfer Size:         512 Pages
Warning  Comp. Temp. Threshold:     84 Celsius
Critical Comp. Temp. Threshold:     89 Celsius

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     8.80W       -        -    0  0  0  0        0       0
 1 +     7.10W       -        -    1  1  1  1        0       0
 2 +     5.20W       -        -    2  2  2  2        0       0
 3 -   0.0620W       -        -    3  3  3  3     2500    7500
 4 -   0.0440W       -        -    4  4  4  4    10500   65000

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        49 Celsius
Available Spare:                    100%
Available Spare Threshold:          5%
Percentage Used:                    0%
Data Units Read:                    12,492,155 [6.39 TB]
Data Units Written:                 5,707,046 [2.92 TB]
Host Read Commands:                 46,231,697
Host Write Commands:                7,541,317
Controller Busy Time:               138
Power Cycles:                       29
Power On Hours:                     3,772
Unsafe Shutdowns:                   13
Media and Data Integrity Errors:    0
Error Information Log Entries:      1
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Thermal Temp. 1 Transition Count:   3
Thermal Temp. 1 Total Time:         2020

Error Information (NVMe Log 0x01, 16 of 63 entries)
No Errors Logged

HaswellおじさんはRaptor Lakeおじさんに

『おばあさんは川へ洗濯に、おじいさんはTSUKUMOへパーツを買いに出かけました』

ということで、Haswellおじさんは無事にRaptor Lakeおじさんになりました。 世代にして第4世代→第13世代の跳躍。完全に桃太郎、失礼、浦島太郎。

entropiajp.hatenablog.com

あれ?おじさん去年の9月に「Haswellでまだあと2年は戦える」って言ってたよね…?

いやいや、今は「時期が良い!」

  • パーツがありえない程安くて絶好の自作時期が到来
  • HDDの稼働時間が3万5千時間を超えてそろそろ怪しい
  • Stable Diffusion触ってみたい
  • Windows11非対応という死刑宣告

構成

パーツ メーカー 型番 価格(税込)
CPU Intel Core i7-13500 ¥30,000
マザーボード ASUS TUF GAMING B760M-PLUS WIFI D4 ¥19,980
メモリ CFD W4U3200CS-16G 16GB 2枚組 ¥6,480
OSストレージ Western Digital WD BLACK SN770 1TB ¥8,670
データストレージ Samsung 980 PRO 2TB ¥18,210
グラフィックボード ASUS DUAL-RTX3060-O12G-V2 ¥41,655
合計金額 ¥124,995

パーツがありえない程安くて絶好の自作時期が到来

今回データ保管用SSDとして購入したSamsung SSD 980 PROの価格推移グラフなんですが、やばくないですか。 年始に38,000円だったのが18,000円と半値以下になってます。

他の製品も軒並み急落

メモリも16GB×2枚で6,480円、グラボもRTX 3060が42,000円を切るなど、「今は時期が悪いおじさん」も流石に黙るレベルの相場。ここで待てば更に安くなる可能性があるものの、6月26日現在1ドル143円ということで再び円安による価格改定がありそうなので、絶好の買い時と判断しました。

HDDの稼働時間が3万5千時間を超えてそろそろ怪しい

WD Redの3TBのHDDを保管庫として使ってました。WD Redなのでおそらく5万時間は行けるのだと思いますが、昔HDDのデータ消失で中高時代に作ってたサウンドノベル一式など全データを失った悲劇を繰り返したくないのと、上で書いた通りSSDが激安なので、データ保管庫もM.2 SSDにすることに決定。

Stable Diffusion触ってみたい

RTX 3060を選んだ理由です。出始めの頃は「VRAM 12GBを使いきれないスペックww」とか馬鹿にされてたのが、VRChatやStable Diffusionの登場で神コスパグラボに変わるの面白い。

Windows11非対応という死刑宣告

Haswellおじさんが避けて通れないやつ。Core i7-4770→Core i5-13500という完全に同じパターンでHaswell卒業しているYouTuberを見つけて、やっぱりこのタイミングで構成アップデート考えるよね~となった。

カラオケ動画制作 編集後記

YouTubeにカラオケ動画を投稿した。
めっちゃ疲れたので、制作ワークフローを備忘録に残しておきたいと思う。


www.youtube.com

必要なソフトウェア

  • Logic Pro(Mac)
    • 打ち込み、ミックス、マスタリングを行いカラオケ音源を作成する
  • RhythmicaLyrics(Win)
    • タイムコード付き歌詞を作成する
  • ニコカラメーカー2
    • カラオケ風テロップを出力する
  • AviUtl(Win)
  • Melissa(macOS/Win)

mosynthkey.github.io

ワークフロー

音源作成

  • 楽曲を聴き込む
    • 楽曲構成、使用楽器、キー、テンポ、コード進行などの情報を把握
    • ざっくりと大まかな耳コピ
  • DAW上の初期作業
    • オーディオトラックに原曲を読み込む
    • テンポ情報をDAW上で設定する
      • ※のやり方でオーディオからテンポを抽出→細かく取りすぎるので手直し
      • 倍テンの扱いなどの方針は最初に決めておく。途中で変えるとMIDIノートの修正が超面倒
    • MetricABで原曲を読み込む
    • ドラムとベースとメインメロディーをざっくり打ち込む
      • とりあえず楽曲の最初から最後まで打ち込んで、心が折れるのを防ぐ
  • 音色づくり
    • 原曲に近いソフトウェア音源を探す なければハードシンセのパッチも探す
    • エフェクトをかける
  • 残りパートの打ち込み
  • 効果音を探すor自作してトラックに追加
  • ミックス&マスタリング
    • MetricABで原曲とこまめに比較しながらミックス
    • Ozone先生でマスタリング
  • 24bit/48kHzでバウンスして終了

※テンポ抽出のやり方

読み込んだ原曲を右クリック > テンポ > リージョンのテンポをプロジェクトテンポに適用

アーティキュレーションIDはいいぞ

Logic ProのアーティキュレーションIDの超わかりやすい解説動画はこちら↓
これでもうキースイッチの面倒な打ち込みから解放。万歳。

www.youtube.com

タイムコード付き歌詞作成

  • 歌詞をテキストファイルとして用意する
    • ネット上の歌詞は間違っていることが多々あるので注意(特にサンホラ)
    • テロップを意識して適宜改行・スペースを入れておく
  • RhythmicaLyricsで歌詞テキストを読み込み、タイムコードを打ち込む
    • 常に「編集中のデータを保存」で.rlfファイルで保存する
    • 通常の保存ではルビ情報が保存時に失われて、次回開いた時に全てやり直しになるので要注意
  • 「出力」→「ルビ拡張規格でタイムタグ出力」で.lrcファイルを出力する

手順の詳細はこちらの記事がとても参考になる。 note.com

ニコカラメーカー2でカラオケ風テロップ動画を作成

  • 背景画像を探す
    • 利用規約上、動画への利用が許可されている画像を探す
  • 新規プロジェクトに背景画像とRhythmicaLyricsで出力した.lrcファイルを読み込む
  • 必要に応じてテロップの行区切りを追加・削除する
  • パートごとの色分けを設定する
    • 1行の途中で色分けする場合 or 行区切りをマニュアル編集した場合は要注意。例えば歌詞に修正が発生して.lrcファイルを読み込み直すと、これらの編集内容は消えてやり直しになる
  • プレビューで問題なければ無圧縮AVIを出力する
    • このAVIファイルは数十GBになるので出力先ストレージの空き容量に注意

動画エンコード

  • Logicでバウンスした2mixのWAVとニコカラメーカーの出力AVIをAviUtlに読み込む
  • 前後のフェードイン/アウトを挿入する
  • 曲名アーティスト名などの常時表示テキストを挿入する
  • YouTube用のプロファイルを選択してx264エンコード
  • YouTubeサムネイル用画像を作成する
    • 適当なフレームにサムネイル用の情報を挿入
    • 編集 > PNG出力 > 現在フレームの画像をPNG形式で出力
    • 出力後にサムネイル用の情報を非表示にする

YouTubeアップロード

  • 特に気をつけることはなし

APFSでフォーマットした外付けSSDが認識されなくなったのでdratで中身をサルベージした

MacBook Proに接続したこの外付けSSDへ巨大なデータをコピーしていると、なぜかコピー処理がハングした。外付けSSDを取り出そうにも「プログラムが使用している可能性があります」とか言われて通常の取り出し操作ができなくなった。選択肢に「強制的に取り出す」があったので一瞬嫌な予感がしたもののしょうがないのでクリックしたところ、案の定、外付けSSDが認識されなくなった。

ストレージ動作不良の時に使う定番のFirst Aidを試すも復旧できず。diskutilでストレージの状態を調べると

% sudo diskutil list
Password:
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *2.0 TB     disk0
   1:                        EFI EFI                     314.6 MB   disk0s1
   2:                 Apple_APFS Container disk1         2.0 TB     disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +2.0 TB     disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            11.2 GB    disk1s1
   2:                APFS Volume Macintosh HD - Data     609.6 GB   disk1s2
   3:                APFS Volume Preboot                 86.6 MB    disk1s3
   4:                APFS Volume Recovery                530.0 MB   disk1s4
   5:                APFS Volume VM                      5.4 GB     disk1s5

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *960.2 GB   disk2
   1:                        EFI EFI                     209.7 MB   disk2s1
   2:                 Apple_APFS Container disk3         960.0 GB   disk2s2

/dev/disk3 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +ERROR      disk3
                                 Physical Store disk2s2

/dev/disk3 のボリューム0のSIZEが ERROR になってる。 「Mac ストレージ 復旧」とかで検索すると復旧できそうなサードパーティーアプリが見つかるものの、怪しい中華製アプリ入れたくないし$100も払いたくないので、もう少し悪足掻きすることにした。

Drat

インターネットを検索していると、DratというOSSのツールに辿り着いた。 github.com

Drat is a tool for analysing and recovering data from APFS (Apple File System) partitions.

DratはAPFSパーティションからデータを復旧するためのツールということで、どうやらこれが使えそう。

実際、

Currently, all of Drat's commands (except modify, which is currently disabled as it is not fit for use) operate in a read-only fashion, as they are intended to be used in situations involving data recovery or data forensics.

とあり、Dratの実行が対象データに変更を加えないことが謳われていることは安心材料にもなった。

Dratの主要機能

Dratには複数のコマンドがあるが、今回使うのは listrecover

list

指定したパスに存在するファイルとディレクトリの一覧を表示する。
たとえば、以下のコマンドでは /dev/disk2s2 コンテナのボリュームIDが 0 のボリュームの / (ルートディレクトリ)に存在するファイルとディレクトリの一覧を表示する。

% sudo ./drat list /dev/disk2s2 0 /
Opening file at `/dev/disk2s2` in read-only mode ... OK.
Simulating a mount of the APFS container.
Validating checksum of block 0x0 ... OK.
Locating the checkpoint descriptor area:
- Its length is 280 blocks.
- It is contiguous.
- The address of its first block is 0x1.
Loading the checkpoint descriptor area into memory ... OK.
Locating the most recent well-formed container superblock in the checkpoint descriptor area:
- It lies at index 169 within the checkpoint descriptor area.
- The corresponding checkpoint starts at index 168 within the checkpoint descriptor area, and spans 2 blocks.

Loading the corresponding checkpoint ... OK.
- There are 9 checkpoint-mappings in this checkpoint.

Reading the Ephemeral objects used by this checkpoint ... OK.
Validating the Ephemeral objects ... OK.
The container superblock states that the container object map has Physical OID 0x13fa2d.
Loading the container object map ... OK.
Validating the container object map ... OK.
Reading the root node of the container object map B-tree ... OK.
Validating the root node of the container object map B-tree ... OK.
The container superblock lists 1 APFS volumes, whose superblocks have the following Virtual OIDs:
- 0x402

Reading the APFS volume superblocks ... OK.
Validating the APFS volume superblocks ... OK.

 Volume list
================
 0: Extreme 900
The volume object map has Physical OID 0x13f96d.
Reading the volume object map ... OK.
Validating the volume object map ... OK.
Reading the root node of the volume object map B-tree ... OK.
Validating the root node of the volume object map B-tree ... OK.
The file-system tree root for this volume has Virtual OID 0x404.
Looking up this Virtual OID in the volume object map ... corresponding block address is 0x140fa9.
Reading ... validating ... OK.

Records for file-system object 0x2 -- `/` --
- INODE
- XATTR || name = purgeable-drecs-fixed
- DIR REC || Dirctry || target ID =     0xa4 || name = TownHallOrgan_SP
- DIR REC || Dirctry || target ID =     0xa1 || name = SanDisk
- DIR REC || Dirctry || target ID =     0x9e || name = JGV1_20180521
- DIR REC || Dirctry || target ID =     0x10 || name = .Spotlight-V100
- DIR REC || Dirctry || target ID =     0xa3 || name = STEAM
- DIR REC || Dirctry || target ID =     0x9b || name = e-onkyo
- DIR REC || Dirctry || target ID =     0xa0 || name = PREMIER SOUND FACTORY 2.0
- DIR REC || Dirctry || target ID =     0x9d || name = Ivory Items
- DIR REC || Dirctry || target ID =  0x2dde4 || name = Logic200531
- DIR REC || Dirctry || target ID =     0xa5 || name = V-Metal Library
- DIR REC || Dirctry || target ID =  0x30dab || name = Logic
- DIR REC || Dirctry || target ID =     0x9c || name = Hummingbird
- DIR REC || Dirctry || target ID =     0xa2 || name = Spitfire
- DIR REC || Dirctry || target ID =  0x2dd90 || name = .Trashes
- DIR REC || Dirctry || target ID =     0x1a || name = .fseventsd
- DIR REC || Dirctry || target ID =  0x2ec46 || name = .DocumentRevisions-V100
- DIR REC || Dirctry || target ID =     0x9f || name = Play Libraries
- DIR REC || Dirctry || target ID =  0x2ec4e || name = .TemporaryItems

recover

指定したパスに存在する単一ファイルを抽出する。
たとえば、以下のコマンドでは /dev/disk2s2 コンテナのボリュームIDが 0 のボリュームの /a/b/c.jpg のパスに存在するJPGファイルをカレントディレクトリに同名ファイルとして出力する。

sudo ./drat recover /dev/disk2s2 0 /a/b/c.jpg >& ./c.jpg

Dratで再帰的にディレクトリの中身をサルベージする

残念ながらDratの recover コマンドには重要な欠点がある。2023/1/1時点の最新版であるv0.1.3では、単一ファイルの復元にのみ対応しており、ディレクトリを対象にした復元ができない点だ。このissueによると、v0.2.0でディレクトリを対象とした復元も実装予定だが、現時点では未対応とのこと。(※注:Dratにはやばいトラップがあり、readthedocsのドキュメントはまだリリースされていないv0.2.0の仕様を前提に書かれている。v0.1.3の使用時には参考にしてはいけない

そこで、指定したパスを再帰的に探索し、ディレクトリの構造を維持した状態でパス直下をすべて recover で復元するスクリプトPythonで実装することにした。以下のGitHubレポジトリで公開している。 github.com

実行方法もREADMEに記載した。