undoはシェルの直前操作をファイル単位で戻す安全網
プロジェクト概要:最後のシェルコマンドがファイルシステムに対して行ったことを元に戻します。フック。シェルフック (zsh、bash、fish) は、実行するすべてのコマンドに小さな LD_PRELOAD ライブラリ libundo.so を装備します。
ひと目でわかる
- これは何?
- edaywalid/undoは、zsh、bash、fishのフックとLD_PRELOADライブラリでコマンドのファイル変更を記録し、最後の操作を取り消せるGo製CLIです。
- 誰に向いている?
- undoは、rm、rm -rf、mv、リダイレクト、chmodなどでファイルを誤って変更したとき、直前の一つのコマンドだけを戻したいLinux利用者に向く小さな安全網です。時間単位で木全体を戻すスナップショットでも、バックアップでもありません。
- 商用利用できる?
- できます。MIT は寛容なライセンスで、著作権表示とライセンス表示を残せば、使用・改変・販売が可能です。
- 今もメンテナンスされている?
- されています。最後のコミットは 35 日前です。
- 何の言語で書かれている?
- 主に Go です(GitHub の言語統計による)。
回答はプロジェクトの GitHub データ(最終同期:2026年9月15日)と当サイトの分析に基づくもので、法的助言ではありません。
オープンソース詳細解説
時間ではなく一つのコマンドを戻す
undoが狙うのは、シェルに一般的な取り消し機能がないという不便です。READMEでは、rmをゴミ箱へ送るエイリアスに変えたり、事故の前にbtrfsやzfsのスナップショットを用意したりする従来の対策と対比しています。undoでは通常のrmを入力し続けられ、ビルドツールの内部で複数プロセスを経て削除が起きた場合も、フックが届く範囲ならそのコマンドの変更を扱います。
復元の単位は時刻ではなく、ファイルシステムを変更した一つのコマンドです。スナップショットがディレクトリ全体をある時点へ戻すのに対し、undoはその操作が触れたファイルに絞って戻します。よって、直前の作業だけを取り消して、その後に行った正しい編集を残したい場合に考え方が合います。ただし、対象外の書き込みが混ざれば復元範囲も狙い通りにならないため、バックアップの代用にはなりません。
シェルフックからlibundo.soへ渡る変更記録
undoには常駐デーモンがなく、コマンドとコマンドの間で別のサービスが動く構成でもありません。zsh、bash、fishのシェルフックが、実行するコマンドの周囲で小さなLD_PRELOADライブラリlibundo.soを有効にします。ライブラリはunlink、rename、書き込みフラグ付きのopen、rmdir、mkdir、chmodなどの破壊的なlibc呼び出しを捕捉し、処理が通る前に影響を受けるファイルをコマンド単位のセッションへ保存します。
各変更はジャーナルへ一行ずつ追加されます。削除されたファイルはハードリンクで保管されるため、rm -rfで大量のデータを削除しても、その削除だけで同じデータを丸ごとコピーするわけではありません。undoは後でジャーナルを逆順に再生し、削除されたファイルを再リンクし、名前変更を戻し、切り詰められたファイルを保存版と交換し、誤って作られたファイルを取り除き、ディレクトリを元のモードで再作成します。
セッションストアとディスク容量の設計
変更を含むコマンドごとに一つのセッションディレクトリが作られます。そこにはコマンドラインを示すcmd、変更を並べるjournal、実行中かどうかを示すpidとdone、保存バイト数を共有するbudget、復元用のdataが置かれます。ストレージは通常のファイルとして確認でき、READMEの既定パスはユーザーのローカルデータ領域にあるsessionsディレクトリです。実行中のセッションをundoが触らないよう、状態マーカーも使われます。
既定では最新30セッションを1GiBの予算内で保管し、保持数と容量は設定で変えられます。削除はハードリンクで済む一方、上書きでは古い内容を保持するためコピーが必要です。ファイルごとのUNDO_MAX_BYTESには既定256MiBの上限があります。単独で予算を超えた最新セッションは、直近の操作を戻せるよう保管されます。何も変更しなかったコマンドにはセッションが残らず、undo purgeを実行すればストア全体を消去できます。
取り消し、再適用、差分確認のCLI
undoを単独の行で実行すると、ファイルを変更した最新コマンドを戻します。undo -iではセッションを選び、個別の項目を復元できます。undo redoは取り消したセッションを再適用し、undo diffは内容差分を表示します。undo listとundo showは保存されたセッションを調べるための入口で、特定のIDを指定して適用する操作も用意されています。
初回確認にはundo doctorがあり、インストール済みの構成を確認した後、テスト用ファイルを実際に削除して復元します。フックを設定できないスクリプトやCIでは、undo run -- cmdで一つのコマンドだけにshimを付けられます。READMEはundoを&&で連結しないよう注意しています。連結行全体がシェルの一コマンドとして扱われ、取り消しを実行するundo自身がまだ完了していないセッションの内部へ入るためです。
LD_PRELOADが届かない変更は戻せない
この方式は、動的リンクしてlibcを通るプログラムに依存します。静的バイナリ、直接システムコールを行うプログラム、sudoやsetuidプログラム、セッション開始前に開かれたファイルディスクリプタへの書き込み、mmapによる書き込みは捕捉できません。chmodや対象となるディスクリプタへのftruncateのように記録される操作がある一方、chownなどモード以外のメタデータ変更は対象外です。フックされたシェルの外で起きた操作は、undo runを使わない限り見えません。
この境界は、undoを安全装置として紹介する際に明示すべき点です。コマンドが終了した後にジャーナルを読めても、対象外の処理まで自動で発見できるわけではありません。README自身が安全網であってバックアップではないと警告しています。ファイルシステム全体の復旧、ハードウェア障害、ランサムウェア対策、別ホストへの保管を必要とする場合は、別のバックアップ機構が必要です。
シェル、Linux、muslの対応条件
自動フックの対象はzsh、bash 5以降、fish 3.4以降です。どのシェルでもundo runを使えば、一回限りのコマンドへshimを付けられます。Linuxではglibcのamd64とarm64が中心で、READMEはglibc 2.6以上を条件として挙げ、WSL2も対応範囲に含めています。Alpineのようなmusl環境ではソースからのビルドが必要です。macOSはシステム整合性保護がライブラリ注入を妨げるため非対応で、SnapとFlatpakも構造上の理由から対象外です。
導入経路は、インストールスクリプト、Homebrew、DebianとUbuntu向けdeb、FedoraとopenSUSE向けrpm、ArchのAUR、Nixのflake、make installによるソースビルドです。ワンライナーは通常ユーザーのローカル領域へ入れ、シェル設定へフックを追記する前に確認を求めます。対話できないCIでは設定を勝手に変更せず、環境変数で追記するかどうかを選べます。パッケージごとにフックの場所が異なるため、導入後は自分のシェルが実際にどのファイルを読み込むか確認してください。
容量、除外、ライセンスを導入前に決める
設定はUNDO_KEEP、UNDO_MAX_STORE、UNDO_DATA_DIR、UNDO_IGNOREなどの環境変数で行い、READMEはフックを読み込む前に設定するよう説明しています。ビルド生成物を大量に追跡すると保存領域を使い切りやすいため、何を記録し何を除外するかを先に決める必要があります。容量上限に達したときも、最新操作を戻せるよう残すという挙動と、継続的な保存を保証することは別です。運用では定期的なpurgeと外部バックアップの責任者を決めておく方がよいでしょう。
プロジェクトはMITライセンスで公開されています。READMEとライセンスの記載は、使用、コピー、変更、結合、公開、配布、サブライセンス、販売を許可し、保証を提供しないという範囲です。ライセンスはundoが捕捉できる操作や復元の成功を保証しません。日常のシェル事故に対する軽い復旧手段として評価し、動的リンクの前提、権限の境界、保存データの機密性、対象外の書き込みを自分の環境で確認してから常用へ進むべきです。
編集部の結論
undoは、rm、rm -rf、mv、リダイレクト、chmodなどでファイルを誤って変更したとき、直前の一つのコマンドだけを戻したいLinux利用者に向く小さな安全網です。時間単位で木全体を戻すスナップショットでも、バックアップでもありません。導入前に動的リンクとglibcの条件、フック対象のシェル、保存領域と容量上限、静的バイナリやsudoを捕捉できないことを確認し、重要データのバックアップは別に用意してください。
コミュニティノート