第10章 データー管理

目次

10.1. 共有とコピーとアーカイブ
10.1.1. アーカイブと圧縮ツール
10.1.2. コピーと同期ツール
10.1.3. アーカイブの慣用句
10.1.4. コピーの慣用句
10.1.5. ファイル選択の慣用句
10.1.6. アーカイブメディア
10.1.7. リムーバブルストレージデバイス
10.1.8. データー共有用のファイルシステム選択
10.1.9. ネットワーク経由でのデーター共有
10.2. バックアップと復元
10.2.1. バックアップと復元のポリシー
10.2.2. バックアップユーティリティーのスイート
10.2.3. バックアップのティップ
10.2.3.1. GUI バックアップ
10.2.3.2. マウントイベントがトリガーするバックアップ
10.2.3.3. タイマーイベントがトリガーするバックアップ
10.3. データーセキュリティーのインフラ
10.3.1. Gnupg のためのキー管理
10.3.2. GnuPG をファイルに使用
10.3.3. Mutt で GnuPG を使用
10.3.4. Vim で GnuPG を使用
10.3.5. MD5 和
10.3.6. パスワード キーリング
10.4. ソースコードマージツール
10.4.1. ソースファイル間の相違の抽出
10.4.2. ソースファイルに更新をマージ
10.4.3. インタラクティブなマージ
10.5. Git
10.5.1. Git クライアントの設定
10.5.2. 基本 Git コマンド
10.5.3. Git ティップ
10.5.4. Git リファレンス
10.5.5. 他のバージョンコントロールシステム

バイナリーとテキストのデーターを Debian システム上で管理するツールとティップを記します。

[警告] 警告

競合状態とならないようにするために、アクティブにアクセスされているデバイスやファイルに複数プロセスから調整なく書き込みアクセスをしてはいけません。flock(1) を使ったファイルロック機構がこの回避に使えます。

データーのセキュリティーとそのコントロールされた共有はいくつかの側面があります。

  • データーアーカイブの作成

  • 遠隔ストレージアクセス

  • 複製

  • 変更履歴の追跡

  • データー共有のアシスト

  • 不正なファイルへのアクセスの防止

  • 不正なファイルの改変の検出

こういったことは以下の組み合わせを使うことで実現できます。

  • アーカイブと圧縮ツール

  • コピーと同期ツール

  • ネットワークファイルシステム

  • リムーバブルストレージメディア

  • セキュアーシェル

  • 認証システム

  • バージョンコントロールシステムツール

  • ハッシュや暗号学的暗号化ツール

Debian システム上で利用可能なアーカイブと圧縮ツールのまとめを以下に記します。

表10.1 アーカイブと圧縮ツールのリスト

パッケージ ポプコン サイズ 拡張子 コマンド コメント
tar V:902, I:999 3077 .tar tar(1) 標準アーカイバー (デファクト標準)
cpio V:440, I:998 1199 .cpio cpio(1) Unix System V スタイルのアーカイバー、find(1) とともに使用
binutils V:172, I:629 144 .ar ar(1) 静的ライブラリー生成用のアーカイバー
fastjar V:1, I:13 183 .jar fastjar(1) Java 用のアーカイバー (zip 類似)
pax V:8, I:14 170 .pax pax(1) 新規 POSIX 標準アーカイバー、tarcpio の間の妥協点
gzip V:876, I:999 252 .gz gzip(1), zcat(1), … GNU LZ77 圧縮ユーティリティー (デファクト標準)
bzip2 V:166, I:970 112 .bz2 bzip2(1), bzcat(1), … gzip(1) より高い圧縮比 (gzip より遅い、類似シンタックス) の Burrows-Wheeler ブロック並び替え圧縮ユーティリティー
lzma V:1, I:16 149 .lzma lzma(1) gzip(1) より高い圧縮比の LZMA 圧縮ユーティリティー (非推奨)
xz-utils V:360, I:980 1203 .xz xz(1), xzdec(1), … bzip2(1) より高い圧縮比の XZ 圧縮ユーティリティー (gzip より遅いが bzip2 より早い、LZMA 圧縮ユーティリティーの代替)
zstd V:193, I:481 2158 .zstd zstd(1), zstdcat(1), … Zstandard 高速ロスレス圧縮ユーティリティー
p7zip V:20, I:463 8 .7z 7zr(1), p7zip(1) 高い圧縮比をもつ 7-Zip 圧縮ユーティリティー (LZMA 圧縮)
p7zip-full V:110, I:480 12 .7z 7z(1), 7za(1) 高い圧縮比をもつ 7-Zip 圧縮ユーティリティー (LZMA 圧縮、他)
lzop V:15, I:142 164 .lzo lzop(1) gzip(1) より高い圧縮と解凍の速度 (gzip より低い圧縮比、類似シンタックス) の LZO 圧縮ユーティリティー
zip V:48, I:380 616 .zip zip(1) InfoZIP: DOS アーカイブと圧縮ツール
unzip V:105, I:771 379 .zip unzip(1) InfoZIP: DOS アーカイブ解凍と圧縮解凍ツール

[警告] 警告

何が起こるかを理解せずに "$TAPE" 変数を設定してはいけません。設定すると tar(1) の挙動が変わります。

Debian システム上で利用可能な単純なコピーとバックアップツールのまとめを以下に記します。


rsync(8) を使ってのファイルのコピーには他の方法より豊かな機能があります。

  • 転送元のファイルと転送先の既存ファイル間の相違のみを送信する差分転送アルゴリズム

  • サイズか最終変更時間に変更があったファイルのみを探す (デフォルトで採用される) 急速確認アルゴリズム

  • tar(1) 類似の "--exclude" や "--exclude-from" オプション

  • 転送先に追加ディレクトリーレベルを作成しなくする「転送元ディレクトリ後スラシュ (/) 付加」文法

[ヒント] ヒント

表10.14「他のバージョン コントロール システム ツールのリスト」に記されたバージョンコントロールシステム (VCS) ツールは多方向のコピーと同期のツールとして機能します。

"./source" ディレクトリー中の全内容を異なるツールを用いてコピーするいくつかの方法を以下に記します。

rsync(8):

# cd ./source; rsync -aHAXSv . /dest
# cd ./source; rsync -aHAXSv . [email protected]:/dest

「転送元ディレクトリー後スラシュ付加」文法を上記の代わりに使えます。

# rsync -aHAXSv ./source/ /dest
# rsync -aHAXSv ./source/ [email protected]:/dest

この代わりに、以下のようにも出来ます。

# cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . /dest
# cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . [email protected]:/dest

GNU cp(1) と openSSH scp(1):

# cd ./source; cp -a . /dest
# cd ./source; scp -pr . [email protected]:/dest

GNU tar(1):

# (cd ./source && tar cf - . ) | (cd /dest && tar xvfp - )
# (cd ./source && tar cf - . ) | ssh [email protected] '(cd /dest && tar xvfp - )'

cpio(1):

# cd ./source; find . -print0 | cpio -pvdm --null --sparse /dest

"." を含むすべての例で "." は"foo" で代替でき、ファイルを "./source/foo" ディレクトリーから "/dest/foo" ディレクトリにコピーできます。

"." を含むすべての例で "." を絶対パスの "/path/to/source/foo" で代替でき、"cd ./source;" を削除することができます。これらは使うツール次第で異なる場所にファイルをコピーします。

  • "/dest/foo": rsync(8)、GNU cp(1)、scp(1)

  • "/dest/path/to/source/foo": GNU tar(1) と cpio(1)

[ヒント] ヒント

rsync(8) や GNU cp(1) には転送先のファイルが新しい場合にスキップする "-u" オプションがあります。

アーカイブやコピーコマンド (「アーカイブの慣用句」「コピーの慣用句」を参照下さい) のためや xargs(1) (「ファイルに関してループしながらコマンドを反復実行」を参照下さい) のためにファイルを選択するのに find(1) が使われます。これの操作は find(1) のコマンド引数を使うことで強化できます。

find(1) の基本シンタックスは以下のようにまとめられます。

  • 条件の引数は左から右へと評価されます。

  • 結果が決まった時点で評価は終了します。

  • "論理 OR" (条件間に "-o" で指定) は、"論理 AND" (条件間に "-a" または何もなしで指定) より低い優先順位です。

  • "論理 NOT" (条件前に "!" で指定) は、"論理 AND" より高い優先順位です。

  • "-prune" は常に論理真 (TRUE) を返し、ディレクトリーの場合にはこの点以降のファイル探索を停止します。

  • "-name" はシェルのグロブ (「シェルグロブ」を参照下さい) を使ってファイル名のベースにマッチし、さらに "*" and "?" 等のメタ文字で最初の "." ともマッチします。(新規の POSIX 機能)

  • "-regex" はデフォールトでは emacs スタイルの BRE (「正規表現」を参照下さい) を用いてフルパスをマッチします。

  • "-size" はファイルサイズ ("+" が前に付いた値はより大きい、"-" が前に付いた値はより小さい) に基づいてファイルをマッチします。

  • "-newer" はその引数に指定されたファイルより新しいファイルとマッチします。

  • "-print0" は常に論理真 (TRUE) を返し、フルファイル名を (null 終端処理して) 標準出力へプリントします。

find(1) はしばしば慣用的なスタイルで使われます。

# find /path/to \
    -xdev -regextype posix-extended \
    -type f -regex ".*\.cpio|.*~" -prune -o \
    -type d -regex ".*/\.git" -prune -o \
    -type f -size +99M -prune -o \
    -type f -newer /path/to/timestamp -print0

これは以下のアクションをすることを意味します。

  1. "/path/to" からはじまる全ファイルを探索

  2. 探索開始したファイルシステムに探索を全体的に制約し、デフォールトの代わりに ERE (「正規表現」を参照下さい) を使用

  3. 正規表現 ".*\.cpio" か ".*~" にマッチするファイルを処理停止をすることで探索から除外

  4. 正規表現 ".*/\.git" にマッチするディレクトリーを処理停止をすることで探索から除外

  5. 9MiB(1048576バイトの単位) より大きいファイルを処理停止をすることで探索から除外

  6. 上記の探索条件に合致し "/path/to/timestamp" より新しいファイル名をプリントします

上記例中でファイルを検索から除外するときの "-prune -o" の慣用的な使い方を承知下さい。

[注記] 注記

非 Debian のUnix 的システムでは、一部のオプションは find(1) によってサポートされていないかもしれません。そのような場合には、マッチング方法を調整したり "-print0" を"-print" で置き換えることを考慮します。これに関連するコマンドも調整する必要があるかもしれません。

重要なデーターアーカイブのためのコンピューターデーターストレージメディアを選ぶ時にはそれらの限界について注意を払うべきです。小さな個人的なバックアップのためには、著者としては名前が知られている会社の CD-R と DVD-R を使い、クールで日陰の乾燥した埃の無い環境に保存しています。(プロ用途ではテープアーカイブメディアに人気があるようです。)

[注記] 注記

耐火金庫は紙の文書のためのものです。ほとんどのコンピューターデーターストレージメディアは紙よりも耐熱性がありません。著者は複数の安全な場所に保管された複数のセキュアーな暗号化されたコピーに通常頼っています。

ネット上に散見するアーカイブメディアの楽観的なストレージ寿命 (ほとんどベンダー情報由来)。

  • 100+年: インクと中性紙

  • 100年: オプティカルストレージ (CD/DVD、CD/DVD-R)

  • 30年: 磁気ストレージ (テープ、フロッピー)

  • 20年: 相変化オプティカルストレージ (CD-RW)

これらは取扱いによる機械的故障等は考慮していません。

ネット上に散見するアーカイブメディアの楽観的な書込み回数 (ほとんどベンダー情報由来)。

  • 250,000+回: ハードディスク

  • 10,000+回: フラッシュメモリー

  • 1,000回: CD/DVD-RW

  • 1回: CD/DVD-R、紙

[注意] 注意

ここにあるストレージ寿命や書込み回数の数字はクリチカルなデーターストレージに関する決定に使うべきではありません。製造者によって提供される特定の製品情報を参照下さい。

[ヒント] ヒント

CD/DVD-R や紙は1回しか書けないので、本質的に重ね書きで間違ってデーターを消すことを防げます。これは、利点です!

[ヒント] ヒント

もし高速で頻繁な大量のデーターのバックアップをする必要がある場合、高速のネットワーク接続でつながっているリモートホスト上のハードディスクが唯一の現実的なオプションかもしれません。

[ヒント] ヒント

もし書き換え可能なメディアをバックアップに使っている場合には、 リードオンリーのスナップショットをサポートする btrfszfs のようなファイルシステムを使うのも一策です。

リムーバブルストレージデバイスは以下の何れも指します。

これらは以下の何れかで接続できます。

GNOME や KDE のような最近のデスクトップ環境は、"/etc/fstab" エントリーにマッチが無いリムーバブルデバイスを自動的にマウントする事ができます。

  • udisks2 パッケージは、これらのデバイスをマウントやアンマウントするためのデーモンと関連するユーティリティーを提供します。

  • D-bus は、自動的なプロセスを開始するイベントを作成します。

  • PolicyKit が必要な特権を提供します。

[ヒント] ヒント

自動的にマウントされたデバイスは、umount(8) によって利用される "uhelper=" マウントオプションが設定されているかもしれません。

[ヒント] ヒント

"/etc/fstab" にリムーバブルメディアデバイスの記載が無い時のみ、現代的なデスクトップ環境下での自動マウントは起こります。

最新のデスクトップ環境下では以下のようにしてカスタマイズ可能なマウント点として "/media/username/disk_label" が選ばれます。

  • FAT ファイルシステムでは、mlabel(1) を使います。

  • ISO9660 ファイルシステムでは、genisoimage(1) を"-V" オプションとともに使います。

  • ext2/ext3/ext4 ファイルシステムでは、tune2fs(1) を"-L" オプションとともに使います。

[ヒント] ヒント

符号化方式 (エンコーディング) の選択をマウントオプションとして与える必要があるかもしれません (「ファイル名の符号化方式」を参照下さい)。

[ヒント] ヒント

ファイルシステムをアンマウントする際に GUI メニューを使うと、動的に生成された "/dev/sdc" 等のデバイスノード削除するかもしれません。もしそのデバイスノードの削除したくない場合にはシェルのコマンドプロンプトから umount(8) コマンドを使いアンマウントします。

リムーバブルストレージデバイスを使ってデーターを共有する際には、両方のシステムにサポートされた共通のファイルシステムでそれをフォーマットするべきです。ファイルシステム選択のリストを次に示します。

表10.3 典型的な使用シナリオに合わせたリムーバブルストレージデバイスのファイルシステムの選択肢のリスト

ファイルシステム名 典型的使用シナリオ
FAT12 フロッピーディスク上のクロスプラットフォームのデーター共有 (<32MiB)
FAT16 小さなハードディスク類似のデバイス上のクロスプラットフォームのデーター共有 (<2GiB)
FAT32 大きなハードディスク類似のデバイス上のクロスプラットフォームのデーター共有 (<8TiB, MS Windows95 OSR2 以降でサポート有り)
exFAT 大きなハードディスク類似のデバイス上のクロスプラットフォームのデーター共有 (<512TiB, WindowsXPとMac OS X Snow Leopard 10.6.5とLinux kernel 5.4 リリース以降でサポート有り)
NTFS 大きなハードディスク類似のデバイス上のクロスプラットフォームのデーター共有 (MS Windows NT 以降でネイティブにサポート、Linux 上では FUSE 経由の NTFS-3G でサポート)
ISO9660 CD-R and DVD+/-R 上の静的データーのクロスプラットフォームの共有
UDF CD-R や DVD+/-R 上への増分データーの書込み (新規)
MINIX フロッピーディスク上へのスペース効率の良い unix ファイルデーターのストレージ
ext2 古い Linux システムとハードディスク類似デバイス上のデーターを共有
ext3 古い Linux システムとハードディスク類似デバイス上のデーターを共有
ext4 現行の Linux システムとハードディスク類似デバイス上のデーターを共有
btrfs 現行の Linux システムとハードディスク類似デバイス上のデーターを読み出し専用のスナップショットでの共有

[ヒント] ヒント

デバイスレベルの暗号化を使ったクロスプラットフォームのデーター共有に関しては、「dm-crypt/LUKS を使ったリムーバブルディスクの暗号化」を参照下さい。

FAT ファイルシステムはほとんど全ての現代的なオペレーティングシステムでサポートされていて、ハードディスク類似のメディア経由でのデーター交換目的に非常に有用です。

クロスプラットフォームの FAT ファイルシステムを使ったデーター共有にリムーバブルハードディスク類似デバイスをフォーマットする時の安全な選択肢は次です。

  • fdisk(8) か cfdisk(8) か parted(8) (「ディスクパーティション設定」を参照下さい) を使ってそれを単一のプライマリパーティションにパーティションしそれを以下のようにマークします。

    • 2GB より小さなメディアには FAT16 となるように "6" とタイプします

    • 大きなメディアには FAT32 (LBA) となるように "c" とタイプします

  • 第1パーティションを mkfs.vfat(8) を使って以下のようにフォーマットします。

    • FAT16 となるように "/dev/sda1" 等とそのデバイス名だけを使います

    • FAT32 となるように "-F 32 /dev/sda1" 等と明示的なオプション指定とそのデバイス名を使います

FAT とか ISO9660 ファイルシステムを使ってデーターを共有する際の安全への配慮を次に記します。

  • tar(1) や cpio(1) を使ってアーカイブファイルに最初にファイルをアーカイブすることで長いファイル名やシンボリックリンクやオリジナルの Unix ファイルパーミッションとオーナー情報を保持します。

  • split(1) コマンドを使ってアーカイブファイルを 2GiB 以下の塊に分割してファイルサイズの制約から保護します。

  • アーカイブファイルを暗号化してその内容を不正アクセスから保護します。

[注記] 注記

FAT ファイルシステムはその設計上最大ファイルサイズは (2^32 - 1) bytes = (4GiB - 1 byte) です。古い 32 ビット OS 上の一部アプリケーションは、最大ファイルサイズはさらに小さく (2^31 - 1) bytes = (2GiB - 1 byte) です。Debian は後者の問題に苦しむことはありません。

[注記] 注記

Microsoft 自身も 200MB を越すドライブやパーティションに FAT を使うことを勧めていません。マイクロソフトは、彼らの "Overview of FAT, HPFS, and NTFS File Systems" で非効率的なディスク領域の使用等の欠点をハイライトしています。もちろん私たちは Linux では ext4 ファイルシステムを普通使うべきです。

[ヒント] ヒント

ファイルシステムとファイルシステムのアクセスに関しての詳細は、"Filesystems HOWTO" を参照下さい。

データーをネットワーク経由で他のシステムと共有するときには、共通のサービスを使うべきです。次に一部のヒントを記します。


このようなネットワーク経由でマウントされたファイルシステムやネットワーク経由のファイル転送法はデーター共有のために非常に便利ですが、インセキュアーかもしれませんこれらのネットワーク接続は次に記すようにしてセキュアーにされなければいけません。

  • SSL/TLS を使い暗号化

  • SSH 経由でそれをトンネル

  • VPN 経由でそれをトンネル

  • セキュアーファイアウォールの背後に限定

さらに「他のネットワークアプリケーションサーバー」「他のネットワークアプリケーションクライアント」を参照下さい。

コンピューターはいつか壊れるとか、人間によるエラーがシステムやデーターをへの損害を及ぼすことは皆知っています。バックアップと復元の操作は正しいシステム管理の必須構成要素です。考えうる全ての故障モードはいつかの日にやって来ます。

[ヒント] ヒント

バックアップのシステムは簡単にしておき、システムのバックアップは頻繁にします。バックアップデーターが存在することは、あなたのバックアップ方法が技術的に如何に良いかよりも重要です。

実際のバックアップと復元の方針を決める上で3つの要素があります。

  1. 何をバックアップし復元するかを知っていること

  2. バックアップと復元の方法を知っていること

    • セキュアーなデーターのストレージ: 上書きやシステム障害の防止

    • 頻繁なバックアップ: スケジュールされたバックアップ

    • 冗長なバックアップ: データーのミラーリング

    • フルプルーフなプロセス: 簡単な単一コマンドバックアップ

  3. 関わっているリスクと費用の評価

    • データー消失時のリスク

      • データーはファイルシステム破壊に耐えるように、できれば異なるディスクやマシン上の、最低限異なるディスクパーティション上に置くべきです。重要データーは読み取り専用ファイルシステムに保存するのが好ましい。[4]

    • データ侵害の際のデーターのリスク

      • "/etc/ssh/ssh_host_dsa_key" や "/etc/ssh/ssh_host_rsa_key" や "~/.gnupg/*" や "~/.ssh/*" や "/etc/passwd" や "/etc/shadow" や "/etc/fetchmailrc" や "popularity-contest.conf" や "/etc/ppp/pap-secrets" や "/etc/exim4/passwd.client" 等の慎重に扱うべきアイデンティティ関連のデーターファイルは暗号化してバックアップする必要があります。[5] (「データー暗号化ティップ」を参照下さい。)

      • たとえ信頼できるシステム上でも、システムの login パスワードや暗号化解除パスフレーズは、いかなるスクリプト中にもハードコードしてはいけません。(「パスワード キーリング」を参照下さい。)

    • 故障モードとその確率

      • ハードウエアー (特に HDD) はいずれ壊れます

      • ファイルシステムは壊れるかもしれないし、その中のデーターは失われるかもしれません

      • セキュリティー侵害に関してリモート ストレージ システムは信用できません。

      • 脆弱なパスワードによる保護は簡単に破られます

      • ファイルパーミッションシステムが不正アクセスを許すようになるかもしてません

    • バックアップに必要なリソース: 人的、ハードウエアー、ソフトウェアー、…

      • cron ジョブや systemd タイマー ジョブでする自動スケジュールバックアップ

[ヒント] ヒント

debconf の設定データーは "debconf-set-selections debconf-selections" で、dpkg の選択データーは "dpkg --set-selection <dpkg-selections.list" で復元できます。

[注記] 注記

/proc/sys/tmp/run 上にある擬似ファイルシステム (「procfs と sysfs」「tmpfs」 参照) の内容をバックアップしてはいけません。あなた自身が自分がしていることの意味を余程よく分かっていなければ、これらの内容は巨大で無用なデーターです。

[注記] 注記

データーをバックアップする際には MTA (「メール転送エージェント (MTA)」を参照下さい) 等のアプリケーションデーモンを停止するのも一計です。

Debian システム上で利用可能でバックアップユーティリティーのスイートのなかで際立った選ばれたリストを記します。

表10.5 バックアップスイートのユーティリティーのリスト

パッケージ ポプコン サイズ 説明
bacula-common V:8, I:10 2305 Bacula: ネットワークバックアップ、復元および検証 - 共通のサポートファイル
bacula-client V:0, I:2 178 Bacula: ネットワークバックアップ、復元および検証 - クライアントメタパッケージ
bacula-console V:0, I:3 112 Bacula: ネットワークバックアップ、復元および検証 - テキストコンソール
bacula-server I:0 178 Bacula: ネットワークバックアップ、復元および検証 - サーバーメタパッケージ
amanda-common V:0, I:2 9897 Amanda: Advanced Maryland Automatic Network Disk Archiver (ライブラリー)
amanda-client V:0, I:2 1092 Amanda: Advanced Maryland Automatic Network Disk Archiver (クライアント)
amanda-server V:0, I:0 1077 Amanda: Advanced Maryland Automatic Network Disk Archiver (サーバー)
backuppc V:2, I:2 3178 BackupPC は高性能でエンタープライズ級の、PC をバックアップするためのシステム (ディスクベース)
duplicity V:30, I:50 1973 (リモート) 増分バックアップ
deja-dup V:28, I:44 4992 duplicity の GUI フロントエンド
borgbackup V:11, I:20 3301 (リモート) 重複回避バックアップ
borgmatic V:2, I:3 509 borgbackup のヘルパー
rdiff-backup V:4, I:10 1203 (リモート) 増分バックアップ
restic V:2, I:6 21385 (リモート) 増分バックアップ
backupninja V:2, I:3 360 軽量で拡張可のメタバックアップシステム
flexbackup V:0, I:0 243 (リモート) 増分バックアップ
slbackup V:0, I:0 151 (リモート) 増分バックアップ
backup-manager V:0, I:1 566 コマンドラインのバックアップツール
backup2l V:0, I:0 115 マウントできるメディアのための低メンテナンスのバックアップ/復旧ツール (ディスクベース)

バックアップツールにはそれぞれの特別な狙いがあります。

  • Mondo Rescue を使うと、普通のインストールプロセスを経ずにバックアップ CD/DVD 等から完全なシステムを迅速に復旧できます。

  • BaculaAmandaBackupPC は、ネットワーク越しの定期的バックアップに焦点のあるフル機能のバックアップスイートです。

  • DuplicityBorg は典型的ワークステーション向けの比較的簡単なバックアップユーティリティーです。

個人用ワークステーションでは、サーバー環境用に設計されたフル装備バックアップユーティリティー一式はうまく機能しないかもしれません。同時に、既存のワークステーション用のバックアップユーティリティーでは足りない面があるかもしれません。

ここに最小限のユーザー努力でより簡単にバックアップできるようするティップスを示します。これらの技法はどのバックアップユーティリティーにでも使えます。

例示のために、主ユーザーとグループ名を penguin とし、バックアップとスナップショット用スクリプト例 "/usr/local/bin/bkss.sh" を以下として作成します:

#!/bin/sh -e
SRC="$1" # source data path
DSTFS="$2" # backup destination filesystem path
DSTSV="$3" # backup destination subvolume name
DSTSS="${DSTFS}/${DSTSV}-snapshot" # snapshot destination path
if [ "$(stat -f -c %T "$DSTFS")" != "btrfs" ]; then
  echo "E: $DESTFS needs to be formatted to btrfs" >&2 ; exit 1
fi
MSGID=$(notify-send -p "bkup.sh $DSTSV" "in progress ...")
if [ ! -d "$DSTFS/$DSTSV" ]; then
  btrfs subvolume create "$DSTFS/$DSTSV"
  mkdir -p "$DSTSS"
fi
rsync -aHxS --delete --mkpath "${SRC}/" "${DSTFS}/${DSTSV}"
btrfs subvolume snapshot -r "${DSTFS}/${DSTSV}" ${DSTSS}/$(date -u --iso=min)
notify-send -r "$MSGID" "bkup.sh $DSTSV" "finished!"

ここでは、基本ツールの rsync(1) のみを使いシステムのバックアップが実現され、Btrfs を使うことでストレージスペースが有効利用されています。

[ヒント] ヒント

参考: 当著者は、自作の類似シェルスクリプト "bss: Btrfs Subvolume Snapshot Utility" を自身のワークステーションで使用しています。

単一 GUI クリックによるバックアップの設定例をここに示します。

各 GUI クリック毎に、あなたのデーターが "~/Documents" から USB ストレージデバイスにバックアップされ、リードオンリーのスナップショットが作成されます。

マウントイベントによりトリガーされる自動バックアップの設定例をここに記します。

  • 「GUI バックアップ」 と同様にし、USB ストレージデバイスをバックアップ用に準備します。

  • systemd サービスユニットファイル "~/.config/systemd/user/back-BKUP.service" を以下のように作成します:

    [Unit]
    Description=USB Disk backup
    Requires=media-%u-BKUP.mount
    After=media-%u-BKUP.mount
    
    [Service]
    ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents
    StandardOutput=append:%h/.cache/systemd-snap.log
    StandardError=append:%h/.cache/systemd-snap.log
    
    [Install]
    WantedBy=media-%u-BKUP.mount
    
  • 以下のようにして systemd のユニット設定を有効化します。

     $ systemctl --user enable bkup-BKUP.service
    

各マウントイベント毎に、あなたのデーターが "~/Documents" から USB ストレージデバイスにバックアップされ、リードオンリーのスナップショットが作成されます。

ここで、systemd が現在メモリー上に保持する systemd のマウント unit 名を、呼び出ているユーザーのサービスマネージャーに問い合わすには、"systemctl --user list-units --type=mount" を使います。

タイマーイベントによりトリガーされる自動バックアップの設定例をここに記します。

  • 「GUI バックアップ」 と同様にし、USB ストレージデバイスをバックアップ用に準備します。

  • systemd タイマーユニットファイル "~/.config/systemd/user/snap-Documents.timer" を以下のように作成します:

    [Unit]
    Description=Run btrfs subvolume snapshot on timer
    Documentation=man:btrfs(1)
    
    [Timer]
    OnStartupSec=30
    OnUnitInactiveSec=900
    
    [Install]
    WantedBy=timers.target
    
  • systemd サービスユニットファイル "~/.config/systemd/user/snap-Documents.service" を以下のように作成します:

    [Unit]
    Description=Run btrfs subvolume snapshot
    Documentation=man:btrfs(1)
    
    [Service]
    Type=oneshot
    Nice=15
    ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents
    IOSchedulingClass=idle
    CPUSchedulingPolicy=idle
    StandardOutput=append:%h/.cache/systemd-snap.log
    StandardError=append:%h/.cache/systemd-snap.log
    
  • 以下のようにして systemd のユニット設定を有効化します。

     $ systemctl --user enable snap-Documents.timer
    

各タイマーイベント毎に、あなたのデーターが "~/Documents" から USB ストレージデバイスにバックアップされ、リードオンリーのスナップショットが作成されます。

ここで、systemd が現在メモリー上に保持する systemd のタイマー unit 名を、呼び出ているユーザーのサービスマネージャーに問い合わすには、"systemctl --user list-units --type=mount" を使います。

現代的なデスクトップシステムでは、この systemd を使うアプローチのほうが at(1) や cron(8) や anacron(8) を使う伝統的 Unix アプローチよりより精緻な制御を提供できます。

データーのセキュリティーのインフラはデーターの暗号化のツールとメッセージダイジェストのツールと署名ツールの組み合わせで提供されます。


Linux カーネルモジュール経由で自動的データー暗号化のインフラを実現する dm-cryptfscrypt に関しては 「データー暗号化ティップ」を参照下さい。

基本的なキー管理に関する GNU プライバシガードコマンドを次に記します。


トラストコードの意味を次に記します。


以下のようにすると私のキー "1DD8D791" をポピュラーなキーサーバー "hkp://keys.gnupg.net" にアップロード出来ます。

$ gpg --keyserver hkp://keys.gnupg.net --send-keys 1DD8D791

"~/.gnupg/gpg.conf" (もしくは古い場所 "~/.gnupg/options") 中の良いデフォールトのキーサーバーの設定は次を含みます。

keyserver hkp://keys.gnupg.net

次によってキーサーバーから知らないキーが獲得できます。

$ gpg --list-sigs --with-colons | grep '^sig.*\[User ID not found\]' |\
          cut -d ':' -f 5| sort | uniq | xargs gpg --recv-keys

OpenPGP 公開キーサーバー (バージョン0.9.6以前) に2つ以上サブキーのあるキーを壊すバグがありました。新しい gnupg (>1.2.1-2) パッケージはこのような壊れたサブキーを取り扱えます。gpg(1) の"--repair-pks-subkey-bug" オプションの説明を参照下さい。

基本的なキー管理に関する GNU プライバシガードコマンドを次に記します。


md5sum(1) はrfc1321 の方法を使ってダイジェストファイルを作成し各ファイルをそれで確認するユーティリティーを提供します。

$ md5sum foo bar >baz.md5
$ cat baz.md5
d3b07384d113edec49eaa6238ad5ff00  foo
c157a79031e1c40f85931829bc5fc552  bar
$ md5sum -c baz.md5
foo: OK
bar: OK
[注記] 注記

MD5 和の計算は GNU プライバシーガード (GnuPG) による暗号学的署名の計算より CPU への負荷がかかりません。通常、一番上のレベルのダイジェストファイルだけがデーターの整合性のために暗号学的に署名されます。

ソースコードをマージする多くのツールがあります。以下のコマンドが著者の目に止まりました。

表10.10 ソースコードマージツールのリスト

パッケージ ポプコン サイズ コマンド 説明
patch V:97, I:700 248 patch(1) 差分ファイルをオリジナルに適用
vim V:95, I:369 3743 vimdiff(1) vim で2つのファイルを並べて比較
imediff V:0, I:0 200 imediff(1) 対話型フルスクリーンの2方/3方マージツール
meld V:7, I:30 3536 meld(1) ファイルを比較やマージ (GTK)
wiggle V:0, I:0 175 wiggle(1) リジェクトされたパッチを適用
diffutils V:862, I:996 1735 diff(1) 1行ごとにファイルを比較
diffutils V:862, I:996 1735 diff3(1) 1行ごとにファイルを比較やマージ
quilt V:2, I:22 871 quilt(1) パッチのシリーズを管理
wdiff V:7, I:51 648 wdiff(1) テキストファイル間のワードの相違表示
diffstat V:13, I:121 74 diffstat(1) 差分ファイルによる変化のヒストグラム作成
patchutils V:16, I:119 232 combinediff(1) 2つの積み重ねパッチから1つの合計パッチを生成
patchutils V:16, I:119 232 dehtmldiff(1) HTML ページから差分ファイルを抽出
patchutils V:16, I:119 232 filterdiff(1) 差分ファイルから差分ファイルを抽出や削除
patchutils V:16, I:119 232 fixcvsdiff(1) CVS により作成された patch(1) が誤解する差分ファイルを修正
patchutils V:16, I:119 232 flipdiff(1) 古い2つのパッチを交換
patchutils V:16, I:119 232 grepdiff(1) 正規表現にマッチするパッチによって変更されるファイルを表示
patchutils V:16, I:119 232 interdiff(1) 2つのユニファイド差分ファイル間の違いを表示
patchutils V:16, I:119 232 lsdiff(1) どのファイルがパッチによって変更されるかを表示
patchutils V:16, I:119 232 recountdiff(1) ユニファイドコンテキスト差分ファイルのカウントやオフセットを再計算
patchutils V:16, I:119 232 rediff(1) 手編集された差分ファイルのカウントやオフセットを再計算
patchutils V:16, I:119 232 splitdiff(1) 増分パッチの分離
patchutils V:16, I:119 232 unwrapdiff(1) ワードラップされたパッチを復元
dirdiff V:0, I:1 167 dirdiff(1) ディレクトリーツリー間で相違点の表示と変更のマージ
docdiff V:0, I:0 553 docdiff(1) 2つのファイルをワード毎/文字毎に比較
makepatch V:0, I:0 100 makepatch(1) 拡張パッチファイルの生成
makepatch V:0, I:0 100 applypatch(1) 拡張パッチファイルの適用

最近は、ローカルとリモートの両方のコード管理一切が可能なGitがバージョンコントロールシステム (VCS) として最優先の選択肢です。

Debian は Debian Salsa サービス経由でフリーの Git サービスを提供します。その説明文書は https://wiki.debian.org/Salsa にあります。

Git関連パッケージは以下です。


Git は使うあなたの名前や email アドレス等を "~/.gitconfig" 中のいくつかのグローバル設定に設定したいなら以下のようにします。

$ git config --global user.name "Name Surname"
$ git config --global user.email [email protected]

以下によって Git のデフォルトの動作をカスタマイズしてもいいです。

$ git config --global init.defaultBranch main
$ git config --global pull.rebase true
$ git config --global push.default current

もしあなたが CVS や Subversion コマンドに慣れ過ぎている場合には、いくつかのコマンドエイリアスを以下のように設定するのも一計です。

$ git config --global alias.ci "commit -a"
$ git config --global alias.co checkout

あなたのグローバル設定は以下のようにするとチェックできます。

$ git config --global --list

Git 操作にはいくつかのデーターが関与します。

  • ユーサーから見えるファイルを保持しかつ変更の対象とする、ワーキングツリー

    • 記録すべき変更は、インデックスに明示的に選択して候補として挙げなければいけません。これは、git addgit rm コマンドです。

  • 候補として挙げたファイルを保持するインデックス

    • 候補として挙げたファイルはそれに続くリクエストでローカルのレポジトリーにコミットされるでしょう。これは、git commit コマンドです。

  • コミットされたファイルを保持するローカルのレポジトリー

    • Git はコミットされたデーターのリンクされた履歴をレポジトリー中にブランチとして整理して保存します。

    • git push コマンドによって、ローカルレポジトリーはリモートレポジトリーにデーターを送信できます。

    • git fetchgit pull コマンドによって、ローカルレポジトリーはリモートレポジトリーからデーターを受信できます。

      • git pull コマンドは git fetch コマンドの後で git mergegit rebase コマンドを実行します。

      • ここで、git merge は、2 つの別々の履歴のブランチの最後を 1 点にまとめます。(これは、カスタマイズされていないデフォルトの場合の git pull で、多くの人に向けてブランチを公開するアップストリームに好適です。)

      • ここで、git rebase は、リモートブランチの履歴の後ろにローカルブランチの履歴が繋がった連続履歴の単一ブランチを生成します。(これは、pull.rebase true カスタマイゼイションの場合で、残りの我々に好適です。)

  • コミットされたファイルを保持するリモートレポジトリー

    • リモートレポジトリーとの通信は SSH か HTTPS 等のセキュアー通信プロトコルを使います。

ワーキングツリーは .git/ ディレクトリーの外のファイルです。.git/ ディレクトリーの内部のファイルはインデックス、ローカル レポジトリー データー、いくつかの git 設定のテキストファイルを保持します。

主要 Git コマンドの概論です。

表10.12 主要 Git コマンド

Git コマンド 機能
git init (ローカル) レポジトリーを作成します
git clone URL リモートレポジトリーをワーキングツリー付きローカルレポジトリーとしてクローンします
git pull origin main ローカルの main ブランチをリモート レポジトリーの origin を使って更新します
git add . インデックス中にのみ既に存在するファイルに関してワーキングツリー中のファイルをインデックスに追加します
git add -A . ワーキングツリー内の全てのファイルを全てのファイルに関するインデックスに削除を含め加えます
git rm filename ワーキングツリーとインデックスからファイルを削除します
git commit ローカルレポジトリーにインデックス中の挙げられた変更をコミットします
git commit -a ワーキングツリー中の全ての変更をインデックスに追加し、それらをローカルレポジトリーにコミットします (add + commit)
git push-u origin branch_name リモート レポジトリー origin をローカルの branch_name ブランチで更新します (最初の呼び出し)
git push origin branch_name リモート レポジトリー origin をローカルの branch_name ブランチで更新します (その後の呼び出し)
git diff treeish1 treeish2 treeish1 コミットと treeish2 コミットの間の相違を表示します
gitk VCS レポジトリーのブランチ ヒストリー ツリーの GUI 表示をします

以下はGit ティップです。

表10.13 Git ティップ

Git コマンドライン 機能
gitk --all Git 全履歴を閲覧し HEAD を別のコミットにリセットし、パッチをチェリーピックし、タグやブランチを生成するような、Git 履歴への操作を加えます
git stash データーを消失無くクリーンなワーキングツリーを得ます
git remote -v リモートに関する設定をチェックします
git branch -vv ブランチに関する設定をチェックします
git status ワーキングツリーの状態を表示します
git config -l git 設定のリストをします
git reset --hard HEAD; git clean -x -d -f 全てのワーキングツリーの変更を元に戻し完全にクリーンアップします
git rm --cached filename git add filename で変更された候補のインデックスを元に戻します
git reflog レファレンスログを取得します(削除したブランチからコミットを復元するのに有用です)
git branch new_branch_name HEAD@{6} reflog 情報から新規ブランチを生成します
git remote add new_remote URL URL によって指される new_remote リモート レポジトリーを追加します
git remote rename origin upstream リモート レポジトリー名を origin から upstream に変更します
git branch -u upstream/branch_name リモート レポジトリー upstream とそのブランチ名 branch_name にリモート トラッキングを設定します。
git remote set-url origin https://foo/bar.git origin の URL を変更します
git remote set-url --push upstream DISABLED upstream へのプシュを無効化します (Edit .git/config to re-enable)
git remote update upstream upstream レポジトリー中の全リモートブランチの更新を取得しますrepository
git fetch upstream foo:upstream-foo ローカルの (孤立しているかもしれない) upstream-foo ブランチを、upstream レポジトリー中の foo ブランチのコピーとして作成します
git checkout -b topic_branch ; git push -u topic_branch origin 新規 topic_branch を作成しそれを origin にプシュします
git branch -m oldname newname ローカル ブランチ名を変更します
git push -d origin branch_to_be_removed リモート ブランチを削除します (新手法)
git push origin :branch_to_be_removed リモート ブランチを削除します (旧手法)
git checkout --orphan unconnected unconnected ブランチを生成します
git rebase -i origin/main きれいなブランチ履歴のために、origin/main からのコミットを順序変更/削除/押し潰します
git reset HEAD^; git commit --amend 最後の 2 コミットを 1 つに押し潰します
git checkout topic_branch ; git merge --squash topic_branch topic_branch を1 つのコミットに押し潰します
git fetch --unshallow --update-head-ok origin '+refs/heads/*:refs/heads/*' 浅いクローンをブランチのフルクローンに変換します
git ime 最後のコミットを分割して一連のファイル毎の小さなコミット等に分割します (imediff パッケージが必要)
git repack -a -d; git prune ローカル レポジトリーを単一の梱包に再梱包します(こうすると消去したブランチ等からのデーター復元の可能性を制限するかもしれません)

[警告] 警告

たとえ gitk(1) 等の一部ツールが受け付けるからといって、タグ文字列中にスペースを使ってはいけません。他の git コマンドで支障が起こるかもしれません。

[注意] 注意

もしリモートレポジトリーにプッシュしたローカルブランチがリベースしたりスクワッシュした場合には、このブランチをプッシュするのはリスクがあるし、--force オプションが必要です。これは main ブランチでは通常許容されませんが、main ブランチにマージする前のトピックブランチでは許容されます。

[注意] 注意

git サブコマンドを直接 "git-xyz" としてコマンドラインから起動するのは2006年初以来推奨されません。

[ヒント] ヒント

$PATH で指定されたパス中に実行可能ファイル git-foo が存在する場合、ハイフン無しの "git foo" をコマンドラインに入力するとこの git-foo が起動されます。これは git コマンドの機能です。

次を参照下さい。



[4] 重要データーは上書き事故を防ぐために CD/DVD-R のような1回書込みメディアに貯蔵するのが好ましいです。(シェルコマンドラインからストレージメディアにどうして書き込むかについては「バイナリーデーター」を参照下さい。GNOME デスクトップの GUI 環境ではメニュー: "Places→CD/DVD Creator" で簡単に書込みできます。)

[5] このようなデーターの一部は、システムに同一の入力文字列を入力しても再生成できません。

[6] もし、"~/.vim/vimrc" に代えて "~/.vimrc" を使う場合は、それに合わせて置換して下さい。