第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.1.10. リムーバブルストレージデバイス
10.1.11. ネットワーク経由でのデーター共有
10.1.12. アーカイブメディア
10.2. ディスクイメージ
10.2.1. ディスクイメージの作成
10.2.2. ディスクに直接書込み
10.2.3. ディスクイメージファイルをマウント
10.2.4. ディスクイメージのクリーニング
10.2.5. 空のディスクイメージ作成
10.2.6. ISO9660イメージファイル作成
10.2.7. CD/DVD-R/RWに直接書込み
10.2.8. ISO9660イメージファイルをマウント
10.3. バイナリーデーター
10.3.1. バイナリーデーターの閲覧と編集
10.3.2. ディスクをマウントせずに操作
10.3.3. データーの冗長性
10.3.4. データーファイルの復元と事故の証拠解析
10.3.5. 大きなファイルを小さなファイルに分割
10.3.6. ファイル内容の消去
10.3.7. ダミーファイル
10.3.8. ハードディスクの全消去
10.3.9. ハードディスク未使用部分の全消去
10.3.10. 削除されたがまだオープン中のファイルの復活法
10.3.11. 全てのハードリンクを検索
10.3.12. 見えないディスクスペースの消費
10.4. データーセキュリティーのインフラ
10.4.1. Gnupgのためのキー管理
10.4.2. GnuPGをファイルに使用
10.4.3. MuttでGnuPGを使用
10.4.4. VimでGnuPGを使用
10.4.5. MD5和
10.5. ソースコードマージツール
10.5.1. ソースファイル間の相違の抽出
10.5.2. ソースファイルに更新をマージ
10.5.3. 3方マージによる更新
10.6. バージョンコントロールシステム
10.6.1. VCSコマンドの比較
10.7. CVS
10.7.1. CVSレポジトリーの設定
10.7.2. CVSへのローカルアクセス
10.7.3. pserverを使ったCVSへのリモートアクセス
10.7.4. sshを使ったCVSへのリモートアクセス
10.7.5. 新規ソースをCVSにインポート
10.7.6. CVSレポジトリーのファイルパーミッション
10.7.7. CVSのワークフロー
10.7.8. CVSから最新ファイル
10.7.9. CVSの管理運営
10.7.10. CVSチェックアウトの実行ビット
10.8. Subversion
10.8.1. Subversionレポジトリーの設定
10.8.2. Apach2サーバーの経由のSubversionアクセス
10.8.3. グループによるSubversionへのローカルアクセス
10.8.4. グループによるSubversionへのSSH経由のリモートアクセス
10.8.5. Subversionディレクトリー構造
10.8.6. 新規ソースをSubversionにインポート
10.8.7. Subversionのワークフロー
10.9. Git
10.9.1. Gitクライアントの設定
10.9.2. Gitリファレンス
10.9.3. Gitコマンド
10.9.4. 設定履歴記録のためのGit

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

[警告] 警告

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

10.1. 共有とコピーとアーカイブ

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

  • データーアーカイブの作成
  • 遠隔ストレージアクセス
  • 複製
  • 変更履歴の追跡
  • データー共有のアシスト
  • 不正なファイルへのアクセスの防止
  • 不正なファイルの改変の検出

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

  • アーカイブと圧縮ツール
  • コピーと同期ツール
  • ネットワークファイルシステム
  • リムーバブルストレージメディア
  • セキュアーシェル
  • 認証システム
  • バージョンコントロールシステムツール
  • ハッシュや暗号学的暗号化ツール

10.1.1. アーカイブと圧縮ツール

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

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

パッケージ ポプコン サイズ コマンド 拡張子 コメント
tar * V:62, I:99 2044 tar(1) .tar 標準アーカイバー(デファクト標準)
cpio * V:34, I:99 664 cpio(1) .cpio Unix System Vスタイルのアーカイバー、find(1)とともに使用
binutils * V:53, I:76 10160 ar(1) .ar 静的ライブラリー生成用のアーカイバー
fastjar * V:4, I:39 220 fastjar(1) .jar Java用のアーカイバー(zip類似)
pax * V:1.5, I:5 172 pax(1) .pax 新規POSIX標準アーカイバー、tarcpioの間の妥協点
afio * V:0.3, I:1.5 240 afio(1) .afio ファイル毎の圧縮などの拡張をされたcpio
gzip * V:91, I:99 292 gzip(1), zcat(1), … .gz GNU LZ77圧縮ユーティリティー(デファクト標準)
bzip2 * V:55, I:79 132 bzip2(1), bzcat(1), … .bz2 gzip(1)より高い圧縮比(gzipより遅い、類似シンタックス)のBurrows-Wheelerブロック並び替え圧縮ユーティリティー
lzma * V:10, I:76 172 lzma(1) .lzma gzip(1)より高い圧縮比(gzipより遅い、類似シンタックス)のLZMA圧縮ユーティリティー
p7zip * V:2, I:25 1052 7zr(1), p7zip(1) .7z 高い圧縮比をもつ7-Zip圧縮ユーティリティー(LZMA圧縮)
p7zip-full * V:11, I:22 3612 7z(1), 7za(1) .7z 高い圧縮比をもつ7-Zip圧縮ユーティリティー(LZMA圧縮、他)
lzop * V:0.8, I:7 144 lzop(1) .lzo gzip(1)より高い圧縮と解凍の速度(gzipより低い圧縮比、類似シンタックス)のLZO圧縮ユーティリティー
zip * V:9, I:57 628 zip(1) .zip InfoZIP: DOSアーカイブと圧縮ツール
unzip * V:20, I:70 384 unzip(1) .zip InfoZIP: DOSアーカイブ解凍と圧縮解凍ツール

[警告] 警告

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

[注記] 注記

gzip圧縮されたtar(1)アーカイブは".tgz"とか".tar.gz"といったファイル拡張子を使います。

[注記] 注記

cp(1)とscp(1)とtar(1)は特殊ファイルに関して一部制約があるかもしれません。cpio(1)とafio(1)は最も汎用性があります。

[注記] 注記

cpio(1)とafio(1)はfind(1)等のコマンドとともに使うようにできていて、ファイルの選定部分のスクリプトを独立にテストできるのでバックアップスクリプトを作るのに向いています。

[注記] 注記

afio(1)はアーカイブ中の各ファイルを圧縮できます。この事実ゆえafiotarとかcpioアーカイブ全体を圧縮するよりファイルの破損に対してずっと安全となり、バックアップスクリプトにとって最良のアーカイブエンジンとなっています。

[注記] 注記

OpenOfficeデーターファイルの内部データー構造は".jar"ファイルです。

10.1.2. コピーと同期ツール

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

表10.2 コピーと同期ツールのリスト

パッケージ ポプコン サイズ ツール 機能
coreutils * V:91, I:99 11792 GNU cp ファイルやディレクトリーのローカルコピー("-a"で再帰的実行)
openssh-client * V:52, I:99 2076 scp ファイルやディレクトリーのリモートコピー(クライアント、"-r"で再帰実行)
openssh-server * V:67, I:80 808 sshd ファイルやディレクトリーのリモートコピー(リモートサーバー)
rsync * V:17, I:44 640 - 単方向リモート同期とバックアップ
unison * V:1.0, I:3 1644 - 双方向リモート同期とバックアップ
pdumpfs * V:0.05, I:0.15 148 - ハードリンクを使った毎日のローカルバックアップ(Plan9のdumpfs類似)

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

  • 転送元のファイルと転送先の既存ファイル間の相違のみを送信する差分転送アルゴリズム
  • サイズか最終変更時間に変更があったファイルのみを探す(デフォルトで採用される)急速確認アルゴリズム
  • tar(1)類似の"--exclude"や"--exclude-from"オプション
  • 転送先に追加ディレクトリレベルを作成しなくする「転送元ディレクトリ後スラシュ(/)付加」文法
[ティップ] ティップ

「データーバックアップ用コピースクリプト」に記されたbkupスクリプトを"-gl"オプションとともにcron(8)の下で実行すると静的なデーターアーカイブに関してpdumpfsと非常に似た機能を実現できます。

[ティップ] ティップ

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

10.1.3. アーカイブの慣用句

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

GNU tar(1):

$ tar cvzf archive.tar.gz ./source
$ tar xvzf archive.tar.gz

cpio(1):

$ find ./source -xdev -print0 | cpio -ov --null > archive.cpio; gzip archive.cpio
$ zcat archive.cpio.gz | cpio -i

afio(1):

$ find ./source -xdev -print0 | afio -ovZ0 archive.afio
$ afio -ivZ archive.afio

10.1.4. コピーの慣用句

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

  • ローカルコピー: "./source"ディレクトリー → "/dest" ディレクトリー
  • リモートコピー: ローカルホストの"./source"ディレクトリー → "user@host.dom"ホストの"/dest"ディレクトリー

rsync(8):

# cd ./source; rsync -av . /dest
# cd ./source; rsync -av . user@host.dom:/dest

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

# rsync -av ./source/ /dest
# rsync -av ./source/ user@host.dom:/dest

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

# cd ./source; cp -a . /dest
# cd ./source; scp -pr . user@host.dom:/dest

GNU tar(1):

# (cd ./source && tar cf - . ) | (cd /dest && tar xvfp - )
# (cd ./source && tar cf - . ) | ssh user@host.dom '(cd /dest && tar xvfp - )'

cpio(1):

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

afio(1):

# cd ./source; find . -print0 | afio -pv0a /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)、afio(1)
[ティップ] ティップ

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

10.1.5. ファイル選択の慣用句

アーカイブやコピーコマンド(「アーカイブの慣用句」「コピーの慣用句」参照)のためや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 ".*\.afio|.*~" -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. 正規表現".*\.afio"か".*~"にマッチするファイルを処理停止をすることで探索から除外
  4. 正規表現".*/\.git"にマッチするディレクトリーを処理停止をすることで探索から除外
  5. 9MiB(1048576バイトの単位)より大きいファイルを処理停止をすることで探索から除外
  6. 上記の探索条件に合致し"/path/to/timestamp"より新しいファイル名をプリントします

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

[注記] 注記

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

10.1.6. バックアップと復元

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

[ティップ] ティップ

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

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

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

    • あなた自身が作成したデーターファイル: "~/"中のデーター
    • あなた自身が使用したアプリケーションが作成したデーターファイル: "/var/"("/var/cache/"と"/var/run/"と"/var/tmp/"は除外)中のデーター
    • システム設定ファイル: "/etc/"中のデーター
    • ローカルデーター: "/usr/local/"とか"/opt/"中のデーター
    • システムインストール情報: 要点(パーティション、…)をプレーンテキストで書いたメモ
    • 実証済みのデーターセット: 事前に実験的復元操作をして確認済み
  2. バックアップと復元の方法を知っていること

    • セキュアーなデーターのストレージ: 上書きやシステム障害の防止
    • 頻繁なバックアップ: スケジュールされたバックアップ
    • 冗長なバックアップ: データーのミラーリング
    • フルプルーフなプロセス: 簡単な単一コマンドバックアップ
  3. 関わっているリスクと費用の評価

    • データーがなくなった際の価値
    • バックアップに必要なリソース: 人的、ハードウエアー、ソフトウエアー、…
    • 故障モードとその確率

データーのセキュアーなストレージとして、好ましくはファイルシステム破壊に耐えるように異なるディスクや機器上に、少なくとも異なるディスクパーティション上に、データーはあるべきです。重要データーは上書き事故を防ぐためにCD/DVD-Rのような1回書込みメディアに貯蔵するのが好ましいです。(シェルコマンドラインからストレージメディアにどうして書き込むかについては「バイナリーデーター」を参照下さい。GNOMEデスクトップのGUI環境ではメニュー: "Places→CD/DVD Creator"で簡単に書込みできます。)

[注記] 注記

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

[注記] 注記

"/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"等のアイデンティティ関連のデーターファイルのバックアップと修復には特に注意が必要です。これらのデーターの一部はシステムに同様な入力をしても再生成できません。

[注記] 注記

ユーザープロセスでcronジョブを実行している際には、"/var/spool/cron/crontabs"ディレクトリー中のファイルを回復しcron(8)を再スタートしなければいけません。cron(8)とcrontab(1)に関しては「タスク定期実行のスケジュール」を参照下さい。

10.1.7. バックアプユーティリティーのスイート

Debianシステム上の目に止まったバックアップユーティリティーのスイートから選んだリストを記します。

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

パッケージ ポプコン サイズ 説明
rdiff-backup * V:1.3, I:3 768 (リモート)増分バックアップ
dump * V:0.4, I:1.6 712 ext2/ext3ファイルシステム用の4.4 BSD由来のdump(8)とrestore(8)
xfsdump * V:0.3, I:2 684 GNU/LinuxとIRIX上のXFSファイルシステム用のxfsdump(8)とxfsrestore(8)を使うdumpとrestore
backupninja * V:0.4, I:0.5 408 軽量で拡張可のメタバックアップシステム
mondo * V:0.11, I:0.7 1168 Mondo Rescue: 災害復元バックアップスイート
sbackup * V:0.08, I:0.2 488 GNOMEデスクトップ用の簡単なバックアップのスイート
keep * V:0.19, I:0.4 1196 KDE用のバックアップシステム
bacula-common * V:1.2, I:2 1360 Bacula: ネットワークバックアップ、復元および検証 - 共通のサポートファイル
bacula-client * I:0.9 52 Bacula: ネットワークバックアップ、復元および検証 - クライアントメタパッケージ
bacula-console * V:0.3, I:1.2 168 Bacula: ネットワークバックアップ、復元および検証 - テキストコンソール
bacula-server * I:0.5 52 Bacula: ネットワークバックアップ、復元および検証 - サーバーメタパッケージ
amanda-common * V:0.4, I:0.9 5308 Amanda: Advanced Maryland Automatic Network Disk Archiver (ライブラリー)
amanda-client * V:0.4, I:0.8 628 Amanda: Advanced Maryland Automatic Network Disk Archiver (クライアント)
amanda-server * V:0.13, I:0.3 1348 Amanda: Advanced Maryland Automatic Network Disk Archiver (サーバー)
backuppc * V:0.7, I:0.9 2170 BackupPCは高性能でエンタープライズ級の、PCをバックアップするためのシステム(ディスクベース)
backup-manager * V:0.4, I:0.5 660 コマンドラインのバックアップツール
backup2l * V:0.2, I:0.3 140 マウントできるメディアのための低メンテナンスのバックアップ/復旧ツール(ディスクベース)
faubackup * V:0.19, I:0.2 156 ストレージにファイルシステムを使うバックアップシステム(ディスクベース)

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

  • Mondo Rescueを使うと、通常のインストールプロセスを経ずにバックアップCD/DVD等から完全なシステムを迅速に復旧できます。
  • sbackupkeepパッケージは、デスクトップユーザーがユーザーデーターの定期的バックアップをする簡単なGUIのフロントエンドを提供します。同様の機能は簡単なスクリプト(「システムバックアップ用スクリプトの例」)とcron(8)で実現できます。
  • BaculaAmandaBackupPCは、ネットワーク越しの定期的バックアップに焦点のあるフル機能のバックアップスイートです。

「アーカイブと圧縮ツール」「コピーと同期ツール」に記された基本的なツールを使うとカスタムスクリプト経由のシステムバックアップができます。そのようなスクリプトは次を使うと強化できます。

  • rdiff-backupパッケージは(リモートの)増分バックアップを可能にします。
  • dumpパッケージは全ファイルシステムの効率的かつ増分のバックアップと復旧を補助します。
[ティップ] ティップ

dumpパッケージに関して学ぶには、"/usr/share/doc/dump/"の中のファイルと"Is dump really deprecated?"を参照下さい。

10.1.8. システムバックアップ用スクリプトの例

個人のDebianのunstable(非安定)スイートを実行するデスクトップシステムでは、個人的だったりクリティカルなデーターのみを保護する必要しかありません。いずれにせよ1年に1回はシステムを再インストールします。だから全システムをバックアップする理由もありませんし、フル機能のバックアップユーティリティーをインストールする理由もありません。

簡単なスクリプトでバックアップ用アーカイブを作成し、GUIを使ってCD/DVDにそれを焼きます。次のこのスクリプトの例を示します。

#!/bin/sh -e
# Copyright (C) 2007-2008 Osamu Aoki <osamu@debian.org>, Public Domain
BUUID=1000; USER=osamu # UID and name of a user who accesses backup files
BUDIR="/var/backups"
XDIR0=".+/Mail|.+/Desktop"
XDIR1=".+/\.thumbnails|.+/\.?Trash|.+/\.?[cC]ache|.+/\.gvfs|.+/sessions"
XDIR2=".+/CVS|.+/\.git|.+/\.svn|.+/Downloads|.+/Archive|.+/Checkout|.+/tmp"
XSFX=".+\.iso|.+\.tgz|.+\.tar\.gz|.+\.tar\.bz2|.+\.afio|.+\.tmp|.+\.swp|.+~"
SIZE="+99M"
DATE=$(date --utc +"%Y%m%d-%H%M")
[ -d "$BUDIR" ] || mkdir -p "BUDIR"
umask 077
dpkg --get-selections \* > /var/lib/dpkg/dpkg-selections.list
debconf-get-selections > /var/cache/debconf/debconf-selections

{
find /etc /usr/local /opt /var/lib/dpkg/dpkg-selections.list \
     /var/cache/debconf/debconf-selections -xdev -print0
find /home/$USER /root -xdev -regextype posix-extended \
  -type d -regex "$XDIR0|$XDIR1" -prune -o -type f -regex "$XSFX" -prune -o \
  -type f -size  "$SIZE" -prune -o -print0
find /home/$USER/Mail/Inbox /home/$USER/Mail/Outbox -print0
find /home/$USER/Desktop  -xdev -regextype posix-extended \
  -type d -regex "$XDIR2" -prune -o -type f -regex "$XSFX" -prune -o \
  -type f -size  "$SIZE" -prune -o -print0
} | cpio -ov --null -O $BUDIR/BU$DATE.cpio
chown $BUUID $BUDIR/BU$DATE.cpio
touch $BUDIR/backup.stamp

rootから実行されるスクリプト断片の例と言う位置づけです。

著者はこれをあなたが次のように変更し実行する事を期待します。

  • このスクリプトを編集して全てのあなたの重要なデーターをカバーしましょう(「ファイル選択の慣用句」「バックアップと復元」参照)。
  • 増分バックアップをするには、"find … -print0"を、"find … -newer $BUDIR/backup.stamp -print0"で置き換えます。
  • scp(1)かrsync(1)を使ってリモートホストにバックアップファイルを転送したり、それらを更なるデーターセキュリティーのためにCD/DVDに焼きます。(私はCD/DVDに焼くのにGNOMEデスクトップのGUIを使っています。更なる冗長性に関しては「zenityを使うシェルスクリプト例」を参照下さい。)

簡潔にしましょう!

[ティップ] ティップ

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

10.1.9. データーバックアップ用コピースクリプト

ディレクトリーツリーの下のデーターセットは、"cp -a"としてコピーすると通常のバックアップができます。

"/var/cache/apt/packages/"ディレクトリーの下のデーターのようなディレクトリーの下の大きな上書きされない静的なデーターセットは、"cp -al"を利用するハードリンクを使うと通常のバックアップに代わるディスク空間を効率的に利用するバックアップができます。

私がbkupと名付けたデーターバックアップのためのコピースクリプトを次に示します。このスクリプトは現ディレクトリーの下の全ての(非VCS)ファイルを親ディレクトリーかリモートホストの日付入りディレクトリーにコピーします。

#!/bin/sh -e
# Copyright (C) 2007-2008 Osamu Aoki <osamu@debian.org>, Public Domain
function fdot(){ find . -type d \( -iname ".?*" -o -iname "CVS" \) -prune -o -print0;}
function fall(){ find . -print0;}
function mkdircd(){ mkdir -p "$1";chmod 700 "$1";cd "$1">/dev/null;}
FIND="fdot";OPT="-a";MODE="CPIOP";HOST="localhost";EXTP="$(hostname -f)"
BKUP="$(basename $(pwd)).bkup";TIME="$(date  +%Y%m%d-%H%M%S)";BU="$BKUP/$TIME"
while getopts gcCsStrlLaAxe:h:T f; do case $f in
g)  MODE="GNUCP";; # cp (GNU)
c)  MODE="CPIOP";; # cpio -p
C)  MODE="CPIOI";; # cpio -i
s)  MODE="CPIOSSH";; # cpio/ssh
S)  MODE="AFIOSSH";; # afio/ssh
t)  MODE="TARSSH";; # tar/ssh
r)  MODE="RSYNCSSH";; # rsync/ssh
l)  OPT="-alv";; # hardlink (GNU cp)
L)  OPT="-av";;  # copy (GNU cp)
a)  FIND="fall";; # find all
A)  FIND="fdot";; # find non CVS/ .???/
x)  set -x;; # trace
e)  EXTP="${OPTARG}";; # hostname -f
h)  HOST="${OPTARG}";; # user@remotehost.example.com
T)  MODE="TEST";; # test find mode
\?) echo "use -x for trace."
esac; done
shift $(expr $OPTIND - 1)
if [ $# -gt 0 ]; then
  for x in $@; do cp $OPT $x $x.$TIME; done
elif [ $MODE = GNUCP ]; then
  mkdir -p "../$BU";chmod 700 "../$BU";cp $OPT . "../$BU/"
elif [ $MODE = CPIOP ]; then
  mkdir -p "../$BU";chmod 700 "../$BU"
  $FIND|cpio --null --sparse -pvd ../$BU
elif [ $MODE = CPIOI ]; then
  $FIND|cpio -ov --null | ( mkdircd "../$BU"&&cpio -i )
elif [ $MODE = CPIOSSH ]; then
  $FIND|cpio -ov --null|ssh -C $HOST "( mkdircd \"$EXTP/$BU\"&&cpio -i )"
elif [ $MODE = AFIOSSH ]; then
  $FIND|afio -ov -0 -|ssh -C $HOST "( mkdircd \"$EXTP/$BU\"&&afio -i - )"
elif [ $MODE = TARSSH ]; then
  (tar cvf - . )|ssh -C $HOST "( mkdircd \"$EXTP/$BU\"&& tar xvfp - )"
elif [ $MODE = RSYNCSSH ]; then
  rsync -rlpt ./ "${HOST}:${EXTP}-${BKUP}-${TIME}"
else
  echo "Any other idea to backup?"
  $FIND |xargs -0 -n 1 echo
fi

これはコマンド例の位置付けです。スクリプトを読んで自分自身で編集してからご使用下さい。

[ティップ] ティップ

私はこのbkupを私の"/usr/local/bin/"ディレクトリーに置いています。わたしは一時的スナップショットのバックアップが必要な時に、作業ディレクトリー中で引数無しにこのbkupコマンドを実行します。

[ティップ] ティップ

ソースファイルツリーや設定ファイルツリーのスナップショットの履歴を作成するには、git(7)を使うのが簡単でスペースの効率も良ろしいです(「設定履歴記録のためのGit」参照)。

10.1.10. リムーバブルストレージデバイス

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

  • ハードディスク
  • フラッシュメモリーのすべてのフォーマット
  • USBIEEE 1394 / FirewirePC Card等経由でつながれたデジタルカメラ

このようなリムーバブルストレージは、gnome-mount(1)を使いGNOME等の現代的なデスクトップ環境では自動的にユーザーとしてマウントできます。

  • GNOMEの下のマウント点は次のようにしてカスタマイズ可能な"/media/<disk_label>"と選ばれます。

    • FATファイルシステムでは、mlabel(1)を使います。
    • ISO9660ファイルシステムでは、genisoimage(1)を"-V"オプションとともに使います。
    • ext2/ext3ファイルシステムでは、tune2fs(1)を"-L"オプションとともに使います。
  • 符号化方式(エンコーディング)の選択をマウントオプションとして与える必要があるかもしれません(「ファイル名の符号化方式」参照)。
  • マウントされたファイルシステムのオーナーシップはノーマルユーザーが使えるように調整する必要があるかもしれません。
[注記] 注記

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

[ティップ] ティップ

間違ったマウントオプションにより問題が発生した時には、gconf-editor(1)を使って"/system/storage/"の下の対応する設定を消去します。

表10.4 "/etc/fstab"エントリーにマッチが無いリムーバブルデバイスをノーマルユーザーにマウントする事を許すパッケージのリスト

パッケージ ポプコン サイズ 説明
gnome-mount * V:23, I:42 968 ストレージデバイスを(アン)マウントやイジェクトするためのラッパー(GNOMEが使用)
pmount * V:9, I:32 868 ノーマルユーザーとしてリムーバブルデバイスをマウントする(KDEが使用)
cryptmount * V:0.15, I:0.5 308 暗号化されたファイルシステムの管理とユーザーモードでのマウント
usbmount * I:1.7 112 USBストレージデバイスを自動的にマウントやアンマウント

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

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

ファイルシステム 典型的使用シナリオの説明
FAT12 フロッピーディスク上のクロスプラットフォームのデーター共有(<32MiB)
FAT16 小さなハードディスク類似のデバイス上のクロスプラットフォームのデーター共有(<2GiB)
FAT32 大きなハードディスク類似のデバイス上のクロスプラットフォームのデーター共有(<8TiB, MS Windows95 OSR2以降でサポート有り)
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システムとハードディスク類似デバイス上のデーターを共有(ジャーナリングファイルシステム)

[ティップ] ティップ

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

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

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

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

    • 2GBより小さなメディアにはFAT16となるように"6"とタイプします
    • type "c" for FAT32 (LBA) for larger media.大きなメディアにはFAT32 (LBA)となるように"c"とタイプします
  • 第1パーティションをmkfs.vfat(8)を使って次のようにフォーマットします。

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

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

  • tar(1)やcpio(1)やafio(1)を使ってアーカイブファイルに最初にファイルをアーカイブすることで長いファイル名やシンボリックリンクやオリジナルのUnixファイルパーミッションとオーナー情報を保持します。
  • split(1)コマンドを使ってアーカイブファイルを2GiB次の塊に分割してファイルサイズの制約から保護します。
  • アーカイブファイルを暗号化してその内容を不正アクセスから保護します。
[注記] 注記

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

[注記] 注記

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

[ティップ] ティップ

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

10.1.11. ネットワーク経由でのデーター共有

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

表10.6 典型的使用シナリオの場合のネットワークサービスの選択のリスト

ネットワークサービス 典型的使用シナリオの説明
Sambaを使うSMB/CIFSネットワーク経由マウントファイルシステム "Microsoft Windows Network"経由でのファイル共有、smb.conf(5)とThe Official Samba 3.2.x HOWTO and Reference Guidesamba-docパッケージ参照
Linuxカーネルを使うNFSネットワークマウントファイルシステム "Unix/Linux Network"経由のファイル共有、exports(5)とLinux NFS-HOWTO参照。
HTTPサービス ウェッブサーバー/クライアント間のファイル共有
HTTPSサービス 暗号化されたセキュアーソケットレイヤー(SSL)もしくはTransport Layer Security (TLS)を使ったウェッブサーバー/クライアント間のファイル共有
FTPサービス FTPサーバー/クライアント間のファイル共有

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

  • SSL/TLSを使い暗号化
  • SSH経由でそれをトンネル
  • VPN経由でそれをトンネル
  • セキュアーファイアウォールの背後に限定

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

10.1.12. アーカイブメディア

重要なデーターアーカイブのためのコンピューターデーターストレージメディアを選ぶ時にはそれらの限界について注意を払うべきです。小さな個人的なバックアップのためには、著者としては名前が知られている会社の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回しか書けないので、本質的に重ね書きで間違ってデーターを消すことを防げます。これは、利点です!

[ティップ] ティップ

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

10.2. ディスクイメージ

次に、ディスクイメージの操作を論じます。「データー保存のティップ」も参照下さい。

10.2.1. ディスクイメージの作成

例えば2番目のSCSIドライブ"/dev/sdb"というアンマウントされたドライブのディスクイメージファイル"disk.img"はcp(1)かdd(1)を用いれば次のようにして作れます。

# cp /dev/sdb disk.img
# dd if=/dev/sdb of=disk.img

プライマリIDEディスクの最初のセクターにある伝統的PCのマスターブートレコード(MBR)(「ディスクパーティション設定」参照)のディスクイメージは、dd(1)を用いれば次のようにして作れます。

# dd if=/dev/hda of=mbr.img bs=512 count=1
# dd if=/dev/hda of=mbr-nopart.img bs=446 count=1
# dd if=/dev/hda of=mbr-part.img skip=446 bs=1 count=66
  • "mbr.img": パーティションテーブル付きのMBR
  • 。"mbr-nopart.img": パーティションテーブル抜きのMBR。
  • "part.img": MBRのパーティションテーブルのみ。

ブートディスクとしてSCSIドライブ(最近のシリアルATAドライブを含む)が使われている場合、"/dev/hda"を"/dev/sda"に置き換えて下さい。

オリジナルディスクのパーティションのイメージを作る場合には、"/dev/hda"を"/dev/hda1"等で置き換えます。

10.2.2. ディスクに直接書込み

ディスクイメージファイル"disk.img"はdd(1)を使ってサイズがマッチする例えば"/dev/sdb"という2番目のSCSIドライブに次のようにして書き込むことができます。

# dd if=disk.img of=/dev/sdb

同様にディスクパーティションイメージファイル"partition.img"はサイズがマッチする例えば"/dev/sdb1"という2番目のSCSIドライブの1番目のパーティションに次のようにして書き込むことができます。

# dd if=partition.img of=/dev/sdb1

10.2.3. ディスクイメージファイルをマウント

単一パーティションイメージを含むディスクイメージ"partition.img"は次のようにloopデバイスを使いマウントしアンマウントできます。

# losetup -v -f partition.img
Loop device is /dev/loop0
# mkdir -p /mnt/loop0
# mount -t auto /dev/loop0 /mnt/loop0
...hack...hack...hack
# umount /dev/loop0
# losetup -d /dev/loop0

これは以下のように簡略化出来ます。

# mkdir -p /mnt/loop0
# mount -t auto -o loop partition.img /mnt/loop0
...hack...hack...hack
# umount partition.img

複数のパーティションを含むディスクイメージ"disk.img"の各パーティションはloopデバイスを使ってマウント出来ます。loopデバイスはパーティションをデフォルトでは管理しないので、次のようにそれをリセットする必要があります。

# modinfo -p loop # verify kernel capability
max_part:Maximum number of partitions per loop device
max_loop:Maximum number of loop devices
# losetup -a # verify nothing using the loop device
# rmmod loop
# modprobe loop max_part=16

これで、loopデバイスは16パーティションまで管理出来ます。

# losetup -v -f disk.img
Loop device is /dev/loop0
# fdisk -l /dev/loop0

Disk /dev/loop0: 5368 MB, 5368709120 bytes
255 heads, 63 sectors/track, 652 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x452b6464

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1               1         600     4819468+  83  Linux
/dev/loop0p2             601         652      417690   83  Linux
# mkdir -p /mnt/loop0p1
# mount -t ext3 /dev/loop0p1 /mnt/loop0p1
# mkdir -p /mnt/loop0p2
# mount -t ext3 /dev/loop0p2 /mnt/loop0p2
...hack...hack...hack
# umount /dev/loop0p1
# umount /dev/loop0p2
# losetup -d /dev/loop0

この他、同様の効果はkpartxパッケージのkpartx(8)により作られるデバイスマッパーデバイスを用いて次のようにして実現も出来ます。

# kpartx -a -v disk.img
...
# mkdir -p /mnt/loop0p2
# mount -t ext3 /dev/mapper/loop0p2 /mnt/loop0p2
...
...hack...hack...hack
# umount /dev/mapper/loop0p2
...
# kpartx -d /mnt/loop0
[注記] 注記

MBR等をスキップするオフセットを使ったloopデバイスによっても、このようなディスクイメージの単一パーティションをマウント出来ます。しかしこれは失敗しがちです。

10.2.4. ディスクイメージのクリーニング

ディスクイメージファイル"disk.img"は消去済みのファイルを綺麗に無くした綺麗なスパースイメージ"new.img"に次のようにしてできます。

# mkdir old; mkdir new
# mount -t auto -o loop disk.img old
# dd bs=1 count=0 if=/dev/zero of=new.img seek=5G
# mount -t auto -o loop new.img new
# cd old
# cp -a --sparse=always ./ ../new/
# cd ..
# umount new.img
# umount disk.img

もし"disk.img"がext2かext3の場合には、zerofreeパッケージのzerofree(8)を使うことも出来ます。

# losetup -f -v disk.img
Loop device is /dev/loop3
# zerofree /dev/loop3
# cp --sparse=always disk.img new.img

10.2.5. 空のディスクイメージ作成

5MiBまで成長可能な空のディスクイメージファイル"disk.img"はdd(1)とmke2fs(8)を使って次のようにして作成できます。

$ dd bs=1 count=0 if=/dev/zero of=disk.img seek=5G

loopデバイスを使ってこのディスクイメージ"disk.img"上にext3ファイルシステムを作成できます。

# losetup -f -v disk.img
Loop device is /dev/loop1
# mkfs.ext3 /dev/loop1
...hack...hack...hack
# losetup -d /dev/loop1
$ du  --apparent-size -h disk.img
5.0G  disk.img
$ du -h disk.img
83M disk.img

"sparse"に関して、そのファイルサイズは5.0GiBでその実ディスク使用はたったの83MiBです。この相違はext2fsスパースファイルを保持できるから可能となっています。

[ティップ] ティップ

スパースファイルによる実際のディスク使用はそこに書かれるデーターとともに成長します。

「ディスクイメージファイルをマウント」にあるようにloopデバイスまたはデバイスマッパーデバイスによりデバイスに同様の操作をすることで、このディスクイメージ"disk.img"をparted(8)またはfdisk(8)を使ってパーティションしmkfs.ext3(8)やmkswap(8)等を使ってファイルシステムを作れます。

10.2.6. ISO9660イメージファイル作成

"source_directory"のソースディレクトリーツリーから作られるISO9660イメージファイル"cd.iso"はcdrkitが提供するgenisoimage(1)を使って次のようにして作成できます。

#  genisoimage -r -J -T -V volume_id -o cd.iso source_directory

同様に、ブート可能なISO9660イメージファイル"cdboot.iso"は、debian-installerのような"source_directory"にあるディレクトリーツリーから次のようにして作成できます。

#  genisoimage -r -o cdboot.iso -V volume_id \
   -b isolinux/isolinux.bin -c isolinux/boot.cat \
   -no-emul-boot -boot-load-size 4 -boot-info-table source_directory

上記では、Isolinuxブートローダー(「2段目: ブートローダー」参照)がブートに使われています。

次のようにするとCD-ROMデバイスから直接md5sum値を計算しISO9660イメージを作成できます。

$ isoinfo -d -i /dev/cdrom
CD-ROM is in ISO 9660 format
...
Logical block size is: 2048
Volume size is: 23150592
...
# dd if=/dev/cdrom bs=2048 count=23150592 conv=notrunc,noerror | md5sum
# dd if=/dev/cdrom bs=2048 count=23150592 conv=notrunc,noerror > cd.iso
[警告] 警告

正しい結果を得るために上記のようにLinuxのISO9660ファイルシステム先読みバグを注意深く避けなければいけません。

10.2.7. CD/DVD-R/RWに直接書込み

[ティップ] ティップ

DVDは、cdrkitが提供するwodim(1)にとっては単に大きなCDです。

使えるデバイスは次のようにするとみつかります。

# wodim --devices

そしてブランクのCD-Rをドライブに挿入して、例えば"/dev/hda"というこのデバイスにISO9660イメージファイル"cd.iso"にwodim(1)を使って次のようにして書込みます。

# wodim -v -eject dev=/dev/hda cd.iso

もしCD-RではなくCD-RWが使われている場合には、次を代わりに実行して下さい。

# wodim -v -eject blank=fast dev=/dev/hda cd.iso
[ティップ] ティップ

もしあなたのデスクトップシステムがCDを自動的にマウントする場合、wodim(1)を使う前に"sudo unmount /dev/hda"としてCDをアンマウントします。

10.2.8. ISO9660イメージファイルをマウント

もし"cd.iso"の内容がISO9660イメージの場合、次のようにするとそれを"/cdrom"に手動でマウントできます。

# mount -t iso9660 -o ro,loop cd.iso /cdrom
[ティップ] ティップ

現代的なデスクトップシステムではリムーバブルメディアを自動的にマウントします(「リムーバブルストレージデバイス」参照)。

10.3. バイナリーデーター

次に、ストレージメディア上のバイナリーデーターを直接操作することを論じます。「データー保存のティップ」も参照下さい。

10.3.1. バイナリーデーターの閲覧と編集

もっとも基本的なバイナリーファイルを閲覧方法は"od -t x1"コマンドを使うことです。

表10.7 バイナリーデーターを閲覧や編集するパッケージのリスト

パッケージ ポプコン サイズ 説明
coreutils * V:91, I:99 11792 ファイルをダンプするod(1)がある基本パッケージ(HEX, ASCII, OCTAL, …)
bsdmainutils * V:73, I:99 756 ファイルをダンプするhd(1)があるユーティリティーパッケージ(HEX, ASCII, OCTAL, …)
hexedit * V:0.3, I:1.9 108 バイナリーエディターとビューワー(HEX, ASCII)
bless * V:0.05, I:0.3 1240 フル機能の16進エディター(GNOME)
okteta * V:0.3, I:3 1392 フル機能の16進エディター(KDE4)
ncurses-hexedit * V:0.09, I:0.5 192 バイナリーエディターとビューワー(HEX, ASCII, EBCDIC)
lde * V:0.04, I:0.4 992 Linuxディスクエディター
beav * V:0.03, I:0.3 164 バイナリーエディターとビューワー(HEX, ASCII, EBCDIC, OCTAL, …)
hex * V:0.01, I:0.09 84 16進ダンプツール(日本語2バイトコードをサポート)

[ティップ] ティップ

HEXはが16の16進フォーマットです。OCTALはが8の8進フォーマットです。ASCII(アスキー)は情報交換用アメリカ標準コードで、通常の英文テキストです。EBCDIC(エビシディック)はIBMメインフレームオペレーティングシステム上で使われる拡張二進化十進数互換コードです。

10.3.2. ディスクをマウントせずに操作

ディスクをマウントせずに読出しや書込みをするツールがあります。

表10.8 ディスクをマウントせずに操作するパッケージのリスト

パッケージ ポプコン サイズ 説明
mtools * V:4, I:48 412 MSDOSファイルをマウントせずに使うツール
hfsutils * V:0.2, I:1.7 236 HFSやHFS+ファイルをマウントせずに使うツール

10.3.3. データーの冗長性

Linuxカーネルが提供するソフトウエアーRAIDシステムは高いレベルのストレージ信頼性を達成するためにカーネルのファイルシステムのレベルでデーターの冗長性を提供します。

アプリケーションプログラムレベルでストレージの高い信頼性を達成するようにデーター冗長性を付加するツールもあります。

表10.9 ファイルにデーターの冗長性を追加するツールのリスト

パッケージ ポプコン サイズ 説明
par2 * V:0.5, I:1.7 272 ファイルのチェックと修理のためのパリティーアーカイブセット
dvdisaster * V:0.19, I:0.8 1420 CD/DVDメディアのデーターロス/傷つき/老化の防止
dvbackup * V:0.01, I:0.12 544 MiniDVカメラレコーダを使うバックアップツール(rsbep(1)を提供)
vdmfec * V:0.00, I:0.03 88 前方エラー修正を使って失われたブロックの復元

10.3.4. データーファイルの復元と事故の証拠解析

データーファイルの復元と事故の証拠解析のツールがあります。

表10.10 データーファイルの復元と事故の証拠解析のリスト

パッケージ ポプコン サイズ 説明
testdisk * V:0.3, I:3 4616 パーティションのスキャンとディスク復元のためのユーティリティー
magicrescue * V:0.10, I:0.6 344 マジックバイトを探してファイルを復元するユーティリティー
scalpel * V:0.05, I:0.2 124 質素で高性能なファイル彫刻刀
recover * V:0.08, I:0.8 104 ext2ファイルシステム上のファイルの削除復元ユーティリティー
e2undel * V:0.07, I:0.6 244 ext2ファイルシステム上のファイルの削除復元ユーティリティー
ext3grep * V:0.09, I:0.5 300 ext3ファイルシステム上のファイルの削除復元ヘルプツール
scrounge-ntfs * V:0.04, I:0.5 80 NTFSファイルシステム上のデーター復元プログラム
gzrt * V:0.03, I:0.16 68 gzip復元ツールキット
sleuthkit * V:0.15, I:0.7 5016 証拠解析のためのツール(Sleuthkit)
autopsy * V:0.08, I:0.4 1368 SleuthKitのためのGUI
foremost * V:0.11, I:0.7 140 データー復元のための証拠解析アプリケーション
tct * V:0.04, I:0.2 604 証拠解析関連ユーティリティー
dcfldd * V:0.03, I:0.19 124 証拠解析とセキュリティーのためのddの強化版
rdd * V:0.02, I:0.12 200 証拠解析のためのコピープログラム

10.3.5. 大きなファイルを小さなファイルに分割

単一ファイルでバックアップするにはデーターが大きすぎる場合、そのファイル内容を例えば2000MiBの断片にしてバックアップし、それらの断片を後日マージしてオリジナルのファイルに戻せます。

$ split -b 2000m large_file
$ cat x* >large_file
[注意] 注意

名前がかち合わないように"x"で始まるファイル名のファイルが無いようにします。

10.3.6. ファイル内容の消去

そのようなログファイルの内容を消去するために、rm(1)を使ってファイルを消去しその後新しい空ファイルを作成しないようにします。こうするとコマンド実行間にファイルがアクセスされているかもしれないのがお勧めできない理由です。次のようにするのがファイル内容を消去する安全な方法です。

$ :>file_to_be_cleared

10.3.7. ダミーファイル

次のコマンドはダミーや空のファイルを作成します。

$ dd if=/dev/zero    of=5kb.file bs=1k count=5
$ dd if=/dev/urandom of=7mb.file bs=1M count=7
$ touch zero.file
$ : > alwayszero.file

次のファイルを見つかります。

  • "5kb.file"は5KBのゼロの連続です。
  • "7mb.file"は7MBのランダムなデーターです。
  • "zero.file"は0バイト長のファイルかもしれません。もしファイルが存在する時は、そのmtimeを更新しその内容と長さを保持します。
  • "alwayszero.file"は常に0バイト長ファイルです。もしファイルが存在する時はmtimeを更新しファイル内容をリセットします。

10.3.8. ハードディスクの全消去

"/dev/sda"にあるUSBメモリースティック等のハードディスク類似デバイス全体のデーターを完全に消すいくつかの方法があります。

[注意] 注意

次のコマンドを実行する前にまずUSBメモリースティックの場所をmount(8)を使ってチェックします。"/dev/sda"によって指し示されるデバイスはSCSIハードディスクかも知れませんしあなたの全システムのあるシリアルATAハードディスクかも知れません。

次のようにしてデーターを0にリセットして全消去します。

# dd if=/dev/zero of=/dev/sda

次のようにしてランダムデーターを上書きして全消去します。

# dd if=/dev/urandom of=/dev/sda

次のようにしてランダムデーターを非常に効率的に上書きして全消去します。

# shred -v -n 1 /dev/sda

DebianインストーラCD等の多くのブート可能なLinuxのCDのシェルからdd(1)が利用可能ですから、"/dev/hda"や"/dev/sda"等のシステムハードディスクに対して同類のメディアから消去コマンドを実行することでインストールされたシステムを完全に消去することができます。

10.3.9. ハードディスク未使用部分の全消去

データーの消去はファイルシステムからアンリンクされているだけなので、例えば"/dev/sdb1"のようなハードディスク(USBメモリースティック)上の使用されていない領域には消去されたデーター自身が含まれているかもしれません。これらに上書きすることで綺麗に消去できます。

# mount -t auto /dev/sdb1 /mnt/foo
# cd /mnt/foo
# dd if=/dev/zero of=junk
dd: writing to `junk': No space left on device
...
# sync
# umount /dev/sdb1
[警告] 警告

あなたのUSBメモリースティックにとってはこれで通常十分です。でもこれは完璧ではありません。消去されたファイル名や属性はファイルシステム中に隠れて残っているかもしれません。

10.3.10. 削除されたがまだオープン中のファイルの復活法

ファイルをうっかり消去しても、そのファイルが何らかのアプリケーション(読出しか書込み)によって使われている限り、そのようなファイルを回復出来ます。

例えば、次を試してみて下さい:

$ echo foo > bar
$ less bar
$ ps aux | grep ' less[ ]'
bozo    4775  0.0  0.0  92200   884 pts/8    S+   00:18   0:00 less bar
$ rm bar
$ ls -l /proc/4775/fd | grep bar
lr-x------ 1 bozo bozo 64 2008-05-09 00:19 4 -> /home/bozo/bar (deleted)
$ cat /proc/4775/fd/4 >bar
$ ls -l
-rw-r--r-- 1 bozo bozo 4 2008-05-09 00:25 bar
$ cat bar
foo

この代わりに、(lsofパッケージがインストールされている時)もう一つのターミナルで次のように実行します。

$ ls -li bar
2228329 -rw-r--r-- 1 bozo bozo 4 2008-05-11 11:02 bar
$ lsof |grep bar|grep less
less 4775 bozo 4r REG 8,3 4 2228329 /home/bozo/bar
$ rm bar
$ lsof |grep bar|grep less
less 4775 bozo 4r REG 8,3 4 2228329 /home/bozo/bar (deleted)
$ cat /proc/4775/fd/4 >bar
$ ls -li bar
2228302 -rw-r--r-- 1 bozo bozo 4 2008-05-11 11:05 bar
$ cat bar
foo

10.3.11. 全てのハードリンクを検索

ハードリンクのあるファイルは"ls -li"を使って確認できます、

$ ls -li
total 0
2738405 -rw-r--r-- 1 root root 0 2008-09-15 20:21 bar
2738404 -rw-r--r-- 2 root root 0 2008-09-15 20:21 baz
2738404 -rw-r--r-- 2 root root 0 2008-09-15 20:21 foo

"baz"も"foo"もリンク数が"2" (>1)でハードリンクがある事を示しています。これらのinode番号は共通の"2738404"です。これはこれらがハードリンクされた同じファイルということを意味します。ハードリンクされた全てのファイルを偶然うまく見つけられない場合は、それを例えば"2738404"というinodeで次のようにして探せます。

# find /path/to/mount/point -xdev -inum 2738404

10.3.12. 見えないディスクスペースの消費

削除されたがオープンされたままのファイルは、通常のdu(1)では見えませんが、ディスクスペースを消費します。これらは次のようにすればそのサイズとともにリストできます。

# lsof -s -X / |grep deleted

10.4. データーセキュリティーのインフラ

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

表10.11 データーセキュリティーインフラツールのリスト

コマンド パッケージ ポプコン サイズ 説明
gpg(1) gnupg * V:40, I:99 5288 GNUプライバシーガード - OpenPGP 暗号化ト署名ツール
N/A gnupg-doc * I:1.3 4124 GNUプライバシガード文書
gpgv(1) gpgv * V:59, I:99 436 GNUプライバシガード - 署名確認ツール
paperkey(1) paperkey * V:0.01, I:0.13 88 OpenPGPの秘密キーから秘密の情報だけを抜粋
cryptsetup(8), … cryptsetup * V:3, I:5 952 暗号化されたブロックデバイス(dm-crypt / LUKS)のためのユーティリティー
ecryptfs(7), … ecryptfs-utils * V:0.16, I:0.2 464 ecryptfsスタックドファイルシステム暗号化のためのユーティリティー
md5sum(1) coreutils * V:91, I:99 11792 MD5メッセージダイジェストを計算やチェック
sha1sum(1) coreutils * V:91, I:99 11792 SHA1メッセージダイジェストを計算やチェック
openssl(1ssl) openssl * V:36, I:90 2352 "openssl dgst"を使ってメッセージダイジェストを計算やチェック(OpenSSL)

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

10.4.1. Gnupgのためのキー管理

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

表10.12 キー管理のためのGNUプライバシガードコマンドのリスト

コマンド 説明
gpg --gen-key 新規キーの生成
gpg --gen-revoke my_user_ID my_user_IDに関するリボークキーを生成
gpg --edit-key user_ID インタラクティブにキーを編集、ヘルプは"help"
gpg -o file --exports 全てのキーをファイルにエクスポート
gpg --imports file 全てのキーをファイルからインポート
gpg --send-keys user_ID user_IDのキーをキーサーバーに送信
gpg --recv-keys user_ID user_IDのキーをキーサーバーから受信
gpg --list-keys user_ID user_IDのキーをリスト
gpg --list-sigs user_ID user_IDの署名をリスト
gpg --check-sigs user_ID user_IDの署名をチェック
gpg --fingerprint user_ID user_IDのフィンガープリントをチェック
gpg --refresh-keys ローカルキーリングをアップデート

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

表10.13 トラストコードの意味のリスト

コード 信用の説明
- 所有者への信用未付与/未計算
e 信用計算に失敗
q 計算用の情報不十分
n このキーを信用不可
m スレスレの信用
f フルに信用
u 究極の信用

次のようにすると私のキー"A8061F32"をポピュラーなキーサーバー"hkp://subkeys.pgp.net"にアップロード出来ます。

$ gpg --keyserver hkp://subkeys.pgp.net --send-keys A8061F32

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

keyserver hkp://subkeys.pgp.net

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

$ gpg --list-sigs | \
  sed -n '/^sig.*\[User ID not found\]/s/^sig..........\(\w\w*\)\W.*/\1/p' |\
  sort | uniq | xargs gpg --recv-keys

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

10.4.2. GnuPGをファイルに使用

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

表10.14 ファイルに使用するGNUプライバシーガードコマンドのリスト

コマンド 説明
gpg -a -s file ファイルをASCII文字化したfile.ascと署名
gpg --armor --sign file , ,
gpg --clearsign file メッセージをクリアサイン
gpg --clearsign --not-dash-escaped patchfile パッチファイルをクリアサイン
gpg --verify file クリアサインされたファイルを確認
gpg -o file.sig -b file 署名を別ファイルで作成
gpg -o file.sig --detach-sig file , ,
gpg --verify file.sig file file.sigを使ってファイルを確認
gpg -o crypt_file.gpg -r name -e file fileからバイナリーcrypt_file.gpgへのname宛公開キー暗号化
gpg -o crypt_file.gpg --recipient name --encrypt file , ,
gpg -o crypt_file.asc -a -r name -e file fileからASCII文字化されたcrypt_file.ascへのname宛公開キー暗号化
gpg -o crypt_file.gpg -c file fileからバイナリーcrypt_file.gpgへの対称暗号化
gpg -o crypt_file.gpg --symmetric file , ,
gpg -o crypt_file.asc -a -c file fileからASCII文字化されたcrypt_file.ascへの対称暗号化
gpg -o file -d crypt_file.gpg -r name 暗号解読
gpg -o file --decrypt crypt_file.gpg , ,

10.4.3. MuttでGnuPGを使用

インデックスメニュー上で"S"とすればGnuPGが使えるようにしておきながら、遅いGnuPGが自動的に起動しないように"~/.muttrc"に次の内容を追加します。

macro index S ":toggle pgp_verify_sig\n"
set pgp_verify_sig=no

10.4.4. VimでGnuPGを使用

gnupgのプラグインを使うと".gpg"や".asc"や".ppg"というファイル拡張子のファイルに対して透過的にGnuPGを実行できます。

# aptitude install vim-scripts vim-addon-manager
$ vim-addons install gnupg

10.4.5. MD5和

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.5. ソースコードマージツール

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

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

コマンド パッケージ ポプコン サイズ 説明
diff(1) diff * V:77, I:95 32 1行ごとにファイルを比較
diff3(1) diff * V:77, I:95 32 1行ごとにファイルを比較やマージ
vimdiff(1) vim * V:14, I:31 1732 vimで2つのファイルを並べて比較
patch(1) patch * V:10, I:93 244 差分ファイルをオリジナルに適用
dpatch(1) dpatch * V:2, I:15 344 Debianパッケージのためにパッチのシリーズを管理
diffstat(1) diffstat * V:2, I:15 84 差分ファイルによる変化のヒストグラム作成
combinediff(1) patchutils * V:2, I:16 292 2つの積み重ねパッチから1つの合計パッチを生成
dehtmldiff(1) patchutils * V:2, I:16 292 HTMLページから差分ファイルを抽出
filterdiff(1) patchutils * V:2, I:16 292 差分ファイルから差分ファイルを抽出や削除
fixcvsdiff(1) patchutils * V:2, I:16 292 CVSにより作成されたpatch(1)が誤解する差分ファイルを修正
flipdiff(1) patchutils * V:2, I:16 292 古い2つのパッチを交換
grepdiff(1) patchutils * V:2, I:16 292 正規表現にマッチするパッチによって変更されるファイルを表示
interdiff(1) patchutils * V:2, I:16 292 2つのユニファイド差分ファイル間の違いを表示
lsdiff(1) patchutils * V:2, I:16 292 どのファイルがパッチによって変更されるかを表示
recountdiff(1) patchutils * V:2, I:16 292 ユニファイドコンテキスト差分ファイルのカウントやオフセットを再計算
rediff(1) patchutils * V:2, I:16 292 手編集された差分ファイルのカウントやオフセットを再計算
splitdiff(1) patchutils * V:2, I:16 292 増分パッチの分離
unwrapdiff(1) patchutils * V:2, I:16 292 ワードラップされたパッチを復元
wiggle(1) wiggle * V:0.02, I:0.11 204 リジェクトされたパッチを適用
quilt(1) quilt * V:1.0, I:7 856 パッチのシリーズを管理
meld(1) meld * V:0.6, I:2 2304 ファイルを比較やマージ(GTK)
xxdiff(1) xxdiff * V:0.2, I:1.2 1352 ファイルを比較やマージ(プレーンX)
dirdiff(1) dirdiff * V:0.08, I:0.5 224 ディレクトリーツリー間で相違点の表示と変更のマージ
docdiff(1) docdiff * V:0.01, I:0.16 688 2つのファイルをワード毎/文字毎に比較
imediff2(1) imediff2 * V:0.01, I:0.10 76 対話型フルスクリーンの2方マージツール
makepatch(1) makepatch * V:0.02, I:0.19 148 拡張パッチファイルの生成
applypatch(1) makepatch * V:0.02, I:0.19 148 拡張パッチファイルの適用
wdiff(1) wdiff * V:1.9, I:15 116 テキストファイル間のワードの相違表示

10.5.1. ソースファイル間の相違の抽出

ファイルの場所次第で次の手順のひとつに従うとふたつのソースファイル間の相違を抽出しユニファイド差分ファイル"file.patch0"か"file.patch1"を作成します。

$ diff -u file.old file.new > file.patch0
$ diff -u old/file new/file > file.patch1

10.5.2. ソースファイルに更新をマージ

差分ファイル(別名、パッチファイル)はプログラム更新を送るのに使われます。受け取った側はこの更新を別のファイルに次のようにして適用します。

$ patch -p0 file < file.patch0
$ patch -p1 file < file.patch1

10.5.3. 3方マージによる更新

3つのバージョンのソースコードがある場合、diff3(1)を使って効率的に3方マージを次のように実行できます。

$ diff3 -m file.mine file.old file.yours > file

10.6. バージョンコントロールシステム

Debianシステム上のバージョンコントロールシステム(VCS)のまとめを次に記します。

[注記] 注記

VCSシステムを今始めて学ぶ場合には、人気が出て来ているGitから学び出すことをお薦めします。

表10.16 バージョンコントロールシステムツールのリスト

パッケージ ポプコン サイズ ツール VCSタイプ コメント
cssc * V:0.00, I:0.05 2168 CSSC ローカル Unix SCCSのクローン(非推薦)
rcs * V:1.4, I:8 772 RCS ローカル "Unix SCCSの本来あるべき姿"
cvs * V:4, I:28 3660 CVS リモート リモートVCSの過去の標準
subversion * V:10, I:32 4284 Subversion リモート "良く出来たCVS"、新しいリモートVCSのデファクト標準
git-core * V:7, I:12 15056 Git 分散型 C で書かれた高速DVCS(Linuxカーネル他が利用)
mercurial * V:1.2, I:5 332 Mercurial 分散型 Pythonと一部Cで書かれたDVCS
bzr * V:0.5, I:2 15200 Bazaar 分散型 tlaに影響されPythonで書かれたDVCS(Ubuntuが使用)
darcs * V:0.2, I:1.5 8120 Darcs 分散型 パッチに関して賢い計算をするDVCS(遅い)
tla * V:0.16, I:1.3 1100 GNU arch 分散型 主にTom LordによるDVCS(歴史的)
monotone * V:0.06, I:0.3 4836 Monotone 分散型 C++で書かれたDVCS
tkcvs * V:0.06, I:0.4 2384 CVS, … リモート VCS (CVS, Subversion, RCS)レポジトリーツリーのGUI表示
gitk * V:0.7, I:3 796 Git 分散型 VCS (Git)レポジトリーツリーのGUI表示

VCSはリビジョンコントロールシステム(RCS)とかソフトウエアー設定管理(SCM)という別名もあります。

Gitのような分散VCSが最近一番人気のツールです。CVSやSubversionは既存のオープンソースプログラム活動に参加するのにまだ有用かもしれません。

DebianはDebian Aliothサービス経由でフリーのVCSサービスを提供します。それは実質的に全てのVCSをサポートします。その説明文書はhttp://wiki.debian.org/Aliothにあります。

[注意] 注意

gitパッケージはDVCSではない"GNUインタラクティブツール"です。

VCSアーカイブへの共有アクセスを作るための基本が数点あります。

10.6.1. VCSコマンドの比較

次に全体像を提供するべく元来のVCSコマンドを極端に簡略化した比較を示します。典型的なコマンド文字列はオプションや引数が必要となるかもしれません。

表10.17 本来のVCSコマンドの比較

CVS Subversion Git 機能
cvs init svn create git init (ローカル)レポジトリーを作成
cvs login - - リモートレポジトリーにログイン
cvs co svn co git clone リモートレポジトリーをワーキングツリーとしてチェックアウト
cvs up svn up git pull リモートレポジトリーをマージしてワーキングツリーを更新
cvs add svn add git add . VCSにワーキングツリー中のファイルを追加
cvs rm svn rm git rm VCSからワーキングツリー中のファイルを削除
cvs ci svn ci - リモートレポジトリーに変更をコミット
- - git commit -a ローカルレポジトリーに変更をコミット
- - git push ローカルレポジトリーでリモートレポジトリーを更新
cvs status svn status git status VCSに対するワーキングツリーの状態を表示
cvs diff svn diff git diff diff <参照レポジトリー> <ワーキングツリー>
- - git repack -a -d; git prune ローカルレポジトリーを単一パックにリパック
tkcvs tkcvs gitk VCSレポジトリーツリーのGUI表示

[注意] 注意

gitサブコマンドを直接"git-xyz"としてコマンドラインから起動するのは2006初以来避けるように推薦されています。

[ティップ] ティップ

tkcvs(1)やgitk(1)等のGUIツールはファイルの変更履歴を追跡するのに本当に役立ちます。多くの公開アーカイブが彼らのレポジトリーの中を閲覧するための提供しているウェッブインターフェースもまた非常に有用です。

[ティップ] ティップ

Gitはgit-cvsgit-svnパッケージを使ってCVSやSubversionによって提供されるレポジトリー等の他のVCSレポジトリーを直接処理したり、ローカル変更のためのローカルレポジトリーを提供します。git for CVS usersGit for GNOME developers「Git」を参照下さい。

[ティップ] ティップ

CVSやSubversionに等価コマンドが無いコマンドがGitにあります: "fetch"、"rebase"、"cherrypick"、…

10.7. CVS

次を参照下さい。

  • cvs(1)
  • "/usr/share/doc/cvs/html-cvsclient"
  • "/usr/share/doc/cvs/html-info"
  • "/usr/share/doc/cvsbook"
  • "info cvs"

10.7.1. CVSレポジトリーの設定

CVSレポジトリーへのコミットを"src"グループメンバに限定し許可し、CVSの管理を"staff"グループメンバに限定し許可するように次の設定をすることでうっかりミスを予防できます。

# cd /var/lib; umask 002; mkdir cvs
# export CVSROOT=/srv/cvs/project
# cd $CVSROOT
# chown root:src .
# chmod 2775 .
# cvs -d $CVSROOT init
# cd CVSROOT
# chown -R root:staff .
# chmod 2775 .
# touch val-tags
# chmod 664 history val-tags
# chown root:src history val-tags
[ティップ] ティップ

"$CVSROOT"ディレクトリーの所有者を"root:staff"とし、そのパーミッションを"3775"と変更すると新規プロジェクトの作成を制限できます。

10.7.2. CVSへのローカルアクセス

デフォールトのCVSレポジトリーは"$CVSROOT"で指示されます。次はローカルアクセスのための"$CVSROOT"を設定します。

$ export CVSROOT=/srv/cvs/project

10.7.3. pserverを使ったCVSへのリモートアクセス

多くの公開CVSサーバーはアカウント名"anonymous"でpserverサービス経由の読出しのみアクセスを提供します。例えば、Debianウェッブサイト内容はwebwmlプロジェクトはDebian aliothサービスでのCVSを使ってメンテされています。次はこのCVSレポジトリーへのリモートアクセスのための"$CVSROOT"を設定します。

$ export CVSROOT=:pserver:anonymous@cvs.alioth.debian.org:/cvsroot/webwml
$ cvs login
[注記] 注記

pserverは盗聴攻撃されやすくインセキュアーなので、書込みアクセスはサーバーの管理者によって通常無効にされています。

10.7.4. sshを使ったCVSへのリモートアクセス

次はSSHを使いwebwml プロジェクトのCVSレポジトリーをリモートアクセスするために"$CVS_RSH"と"$CVSROOT"を設定します。

$ export CVS_RSH=ssh
$ export CVSROOT=:ext:account@cvs.alioth.debian.org:/cvs/webwml

リモートパスワードプロンプトを無くすのにSSHを使ったパブリックキー認証を使えます。

10.7.5. 新規ソースをCVSにインポート

"~/path/to/module1"で新規のローカルソースツリーの場所を作成。

$ mkdir -p ~/path/to/module1; cd ~/path/to/module1

"~/path/to/module1"の下の新規のローカルソースツリーを埋める。

次のパラメーターを使ってCVSにインポートします。

  • モジュール名: "module1"
  • ベンダータグ: Main-branch (全ブランチへのタグ)
  • リリースタグ: Release-initial (特定リリースタグ)
$ cd ~/path/to/module1
$ cvs import -m "Start module1" module1 Main-branch Release-initial
$ rm -Rf . # optional

10.7.6. CVSレポジトリーのファイルパーミッション

CVSは現レポジトリーファイルを上書きせず他のファイルで置き換えます。だからレポジトリーディレクトリーへの書込みパーミッションはクリチカルです。"module1"という新規レポジトリーを"/srv/cvs/project"に作成の際毎に、必要ならこの条件を満たすために次を実行します。

# cd /srv/cvs/project
# chown -R root:src module1
# chmod -R ug+rwX   module1
# chmod    2775     module1

10.7.7. CVSのワークフロー

次にCVSを使う典型的なワークフローを記します。

"$CVSROOT"で指されるCVSプロジェクトから得られる全てのモジュールを次のようにしてチェックします。

$ cvs rls
CVSROOT
module1
module2
...

"module1"をそのデフォールトディレクトリーの"./module1"に次のようにしてチェックアウトします。

$ cd ~/path/to
$ cvs co module1
$ cd module1

必要に応じ内容に変更を加える。

次のようにして"diff -u [repository] [local]"と等価を作成し変更をチェックします。

$ cvs diff -u

あるファイル"file_to_undo"を酷く壊したが他のファイルは大丈夫な事に気づきます。

次のようにして"file_to_undo"ファイルをCVSからのクリーンコピーで上書きします。

$ cvs up -C file_to_undo

次のようにして更新されたローカルソースツリーをCVSに保存します。

$ cvs ci -m "Describe change"

次のようにして"file_to_add"ファイルを作成しCVSに追加します。

$ vi file_to_add
$ cvs add file_to_add
$ cvs ci -m "Added file_to_add"

次のようにしてCVSから最新バージョンをマージします。

$ cvs up -d

コンフリクトある変更を意味する"C filename"で始まる行に注意します。

".#filename.version"中の変更されていないコードを探します。

コンフリクトある変更はファイル中の"<<<<<<<"や">>>>>>>"を探索します。

必要に応じコンフリクト解消のためにファイルを編集します。

次のようにしてリリースタグ"Release-1"を追加します。

$ cvs ci -m "last commit for Release-1"
$ cvs tag Release-1

さらに編集します。

次のようにリリースタグ"Release-1"を削除します。

$ cvs tag -d Release-1

次のようにCVSへ変更をチェックインします。

$ cvs ci -m "real last commit for Release-1"

リリースタグ"Release-1"を更新したCVSのmainのHEADに次のようにして再付加します。

$ cvs tag Release-1

次のようにして"Release-initial"タグによってで指定されるオリジナルのバージョンから、スティッキーブランチタグが"Release-initial-bugfixes"のブランチを作成し、"~/path/to/old"ディレクトリーにチェックアウトします。

$ cvs rtag -b -r Release-initial Release-initial-bugfixes module1
$ cd ~/path/to
$ cvs co -r Release-initial-bugfixes -d old module1
$ cd old
[ティップ] ティップ

ブランチポイントとして特定の日付を指定するには"-r Release-initial"の代わりに"-D 2005-12-20" (ISO 8601日付フォーマット)を使います。

オリジナルバージョンに基づいたスティッキータグ"Release-initial-bugfixes"が付いているこのローカルのソースツリーで作業をします。

このブランチで一人で作業をします … 誰か他の人がこの"Release-initial-bugfixes"ブランチに合流するまで。

次のようにして必要に応じて新規ディレクトリーを作りながらこのブランチ上の他の人が変更したファイルと同期します。

$ cvs up -d

必要に応じコンフリクト解消のためにファイルを編集します。

次のようにCVSへ変更をチェックインします。

$ cvs ci -m "checked into this branch"

次のようにしてスティッキータグを削除し("-A")、キーワード展開せずに("-kk")、mainのHEAD(最新版)をつかってローカルのツリーを更新します。

$ cvs up -d -kk -A

次のようにしてキーワード展開せずに("-kk")、"Release-initial-bugfixes"ブランチをマージしてローカルのツリー(内容=mainのHEAD)を更新します。

$ cvs up -d -kk -j Release-initial-bugfixes

エディターを使ってコンフリクト解消します。

次のようにCVSへ変更をチェックインします。

$ cvs ci -m "merged Release-initial-bugfixes"

次のようにしてアーカイブを作成します。

$ cd ..
$ mv old old-module1-bugfixes
$ tar -cvzf old-module1-bugfixes.tar.gz old-module1-bugfixes
$ rm -rf old-module1-bugfixes
[ティップ] ティップ

"cvs up" コマンドには、新規ディレクトリー作成には"-d"オプションを、また空ディレクトリーの摘み取りには"-P"オプションを指定できます。

[ティップ] ティップ

"cvs co module1/subdir"とサブディレクトリーの名前を提供して、"module1"のサブディレクトリーだけをチェックアウトすることが出来ます。

表10.18 CVSコマンドの特記すべきオプション(cvs(1)の最初の引数として使用)

オプション 意味
-n 空実行、効果無し
-t 各段階のCVS活動が分かるようにメッセージを表示

10.7.8. CVSから最新ファイル

CVSから最新ファイルを取り込むには、次のように"tomorrow"(明日)を使います:

$ cvs ex -D tomorrow module_name

10.7.9. CVSの管理運営

モジュールのエリアス"mx"をCVSプロジェクト(ローカルサーバー)に追加します。

$ export CVSROOT=/srv/cvs/project
$ cvs co CVSROOT/modules
$ cd CVSROOT
$ echo "mx -a module1" >>modules
$ cvs ci -m "Now mx is an alias for module1"
$ cvs release -d .

さて、CVSから"new"ディレクトリーに"module1"(エリアス: "mx")を次のようにしてチェックアウトします。

$ cvs co -d new mx
$ cd new
[注記] 注記

上記プロシージャを行うには、適切なファイルパーミッションが設定されているべきです。

10.7.10. CVSチェックアウトの実行ビット

CVSからファイルをチェックアウトする時に、その実行パーミッションビットは保持されます。

チェックアウトされた例えば"filename"ファイルで実行ビットの問題にあった際には、次のコマンドを使いCVSレポジトリー中のそのパーミッションを変更します。

# chmod ugo-x filename

10.8. Subversion

Subversionは旧来のCVSを置き換える最近の世代のバージョンコントロールシステムです。Subversionにはタグとブランチを除くCVSのほとんどの機能をあります。

Subversionのサーバーをセットアップするには、subversionlibapache2-svnsubversion-toolsパッケージをインストールする必要があります。

10.8.1. Subversionレポジトリーの設定

現状のsubversionパッケージはレポジトリーの設定はしないので手動で設定を行う必要があります。レポジトリーを置く可能な場所の1つは"/srv/svn/project"中です。

ディレクトリーを次のように作成します。

# mkdir -p        /srv/svn/project

レポジトリーデーターベースを次のように作成します。

# svnadmin create /srv/svn/project

10.8.2. Apach2サーバーの経由のSubversionアクセス

Apache2サーバー経由でSubversionレポジトリーにアクセスするだけなら、レポジトリーを次に記すようにWWWサーバーのみによって書込み可とするだけが必要です。

# chown -R www-data:www-data /srv/svn/project

ユーザー認証経由でレポジトリーにアクセス許可するために"/etc/apache2/mods-available/dav_svn.conf"中の次の部分を追加(もしくはアンコメント)します。

<Location /project>
  DAV svn
  SVNPath /srv/svn/project
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /etc/subversion/passwd
<LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
</LimitExcept>
</Location>

次のコマンドでユーザー認証ファイルを作成します。

# htpasswd2 -c /etc/subversion/passwd some-username

Apach2を再スタート

あなたの新規のSubversionレポジトリーは"http://localhost/project"と(ウェッブサーバーのURLが"http://example.com/"と仮定すると)"http://example.com/project"のURLにてアクセスできます。

10.8.3. グループによるSubversionへのローカルアクセス

次はSubversionレポジトリーを例えばprojectというグループによってローカルアクセス出きるようにする設定です。

# chmod  2775     /srv/svn/project
# chown -R root:src /srv/svn/project
# chmod -R ug+rwX   /srv/svn/project

あなたの新しいSubversionレポジトリーは、projectグループに属するローカルユーザーにとってsvn(1)から"file:///localhost/srv/svn/project"か"file:///srv/svn/project"のURLからグループアクセスできます。グループアクセスを確実にするために、svnsvnservesvnlooksvnadmin等のコマンドを"umask 002"の下で実行しなければいけません。

10.8.4. グループによるSubversionへのSSH経由のリモートアクセス

SSHから"example.com:/srv/svn/project"のURLにあるグループアクセス可能なSubversionレポジトリーは、svn(1)を使って"svn+ssh://example.com:/srv/svn/project"にてアクセスできます。

10.8.5. Subversionディレクトリー構造

Subversionのブランチやタグの機能を欠くことを補うべく、多くのプロジェクトは次と似たようなディレクトリーツリーを使っています。

  ----- module1
    |   |-- branches
    |   |-- tags
    |   |   |-- release-1.0
    |   |   `-- release-2.0
    |   |
    |   `-- trunk
    |       |-- file1
    |       |-- file2
    |       `-- file3
    |
    `-- module2
[ティップ] ティップ

ブランチやタグをマークするためには"svn copy …"コマンドを使わなければいけません。こうすることでSubversionがファイルの変更履歴を適切な記録を確実にするとともに記録容量を節約できます。

10.8.6. 新規ソースをSubversionにインポート

"~/path/to/module1"で新規のローカルソースツリーの場所を作成。

$ mkdir -p ~/path/to/module1; cd ~/path/to/module1

"~/path/to/module1"の下の新規のローカルソースツリーを埋める。

ソースを次のパラメーターを使ってSubversionにインポートします。

  • モジュール名: "module1"
  • SubversionサイトのURL: "file:///srv/svn/project",
  • Subversionディレクトリー: "module1/trunk":
  • Subversionタグ: "module1/tags/Release-initial"
$ cd ~/path/to/module1
$ svn import file:///srv/svn/project/module1/trunk -m "Start module1"
$ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-initial

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

$ svn import ~/path/to/module1 file:///srv/svn/project/module1/trunk -m "Start module1"
$ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-initial
[ティップ] ティップ

"file:///…"といったURLは、"http://…"や"svn+ssh://…"といったいかなる他形式のURLででも置き換えられます。

10.8.7. Subversionのワークフロー

次にSubversionを使う典型的なワークフローを記します。

"file:///srv/svn/project"のURLで指定されるSubversionプロジェクトから得られる全てのモジュールを次のようにしてチェックします。

$ svn list file:///srv/svn/project
module1
module2
...

次のようにして"module1/trunk"を"module1"ディレクトリーにチェックアウトします。

$ cd ~/path/to
$ svn co file:///srv/svn/project/module1/trunk module1
$ cd module1

必要に応じ内容に変更を加える。

次のようにして"diff -u [repository] [local]"と等価を作成し変更をチェックします。

$ svn diff

あるファイル"file_to_undo"を酷く壊したが他のファイルは大丈夫な事に気づきます。

次のようにして"file_to_undo"ファイルをSubversionからのクリーンコピーで上書きします。

$ svn revert file_to_undo

更新されたローカルソースツリーを次のようにしてSubversionに保存します。

$ svn ci -m "Describe change"

次のようにして"file_to_add"ファイルを作成しSubversionに追加します。

$ vi file_to_add
$ svn add file_to_add
$ svn ci -m "Added file_to_add"

次のようにしてSubversionから最新バージョンをマージします。

$ svn up

コンフリクトある変更を意味する"C filename"で始まる行に注意します。

"filename.r6"と"filename.r9"と"filename.mine"等中の変更されていないコードを探します。

コンフリクトある変更はファイル中の"<<<<<<<"や">>>>>>>"を探索します。

必要に応じコンフリクト解消のためにファイルを編集します。

次のようにしてリリースタグ"Release-1"を追加します。

$ svn ci -m "last commit for Release-1"
$ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-1

さらに編集します。

次のようにリリースタグ"Release-1"を削除します。

$ svn rm file:///srv/svn/project/module1/tags/Release-1

次のようにして変更をSubversionにチェックインします。

$ svn ci -m "real last commit for Release-1"

リリースタグ"Release-1"を更新したSubversionのtrunkのHEADに再付加します。

$ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-1

次のようにして"module1/tags/Release-initial"というパスで指定されるオリジナルのバージョンから、パスが"module1/branches/Release-initial-bugfixes"のブランチを作成し、"~/path/to/old"ディレクトリーにチェックアウトします。

$ svn cp file:///srv/svn/project/module1/tags/Release-initial file:///srv/svn/project/module1/branches/Release-initial-bugfixes
$ cd ~/path/to
$ svn co file:///srv/svn/project/module1/branches/Release-initial-bugfixes old
$ cd old
[ティップ] ティップ

ブランチポイントとして特定の日付を指定するには"module1/tags/Release-initial"の代わりに"module1/trunk@{2005-12-20}" (ISO 8601日付フォーマット)を使います。

オリジナルバージョンに基づいたブランチ"Release-initial-bugfixes"を指定しているローカルのソースツリーで作業します。

このブランチで一人で作業をします … 誰か他の人がこの"Release-initial-bugfixes"ブランチに合流するまで。

次のようにしてこのブランチ上の他の人が変更したファイルと同期します。

$ svn up

必要に応じコンフリクト解消のためにファイルを編集します。

次のようにして変更をSubversionにチェックインします。

$ svn ci -m "checked into this branch"

trunkのHEADを使って次のようにローカルツリーを更新します。

$ svn switch file:///srv/svn/project/module1/trunk

次のようにして"Release-initial-bugfixes"ブランチをマージしてローカルのツリー(内容=trunkのHEAD)を更新します。

$ svn merge file:///srv/svn/project/module1/branches/Release-initial-bugfixes

エディターを使ってコンフリクト解消します。

次のようにして変更をSubversionにチェックインします。

$ svn ci -m "merged Release-initial-bugfixes"

次のようにしてアーカイブを作成します。

$ cd ..
$ mv old old-module1-bugfixes
$ tar -cvzf old-module1-bugfixes.tar.gz old-module1-bugfixes
$ rm -rf old-module1-bugfixes
[ティップ] ティップ

"file:///…"といったURLは、"http://…"や"svn+ssh://…"といったいかなる他形式のURLででも置き換えられます。

[ティップ] ティップ

"svn co file:///srv/svn/project/module1/trunk/subdir module1/subdir"とサブディレクトリーの名前を提供して、"module1"のサブディレクトリーだけをチェックアウトすることが出来ます。

表10.19 Subversionコマンドの特記すべきオプション(svn(1)の最初の引数として使用)

オプション 意味
--dry-run 空実行、効果無し
-v svn活動の詳細なメッセージを表示

10.9. Git

Gitはローカルとリモートのソースコード管理の全機能があります。これはリモートレポジトリーとのネットワーク接続なしにソースコードへの変更を記録できるといことです。

10.9.1. Gitクライアントの設定

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

$ git config --global user.name "Name Surname"
$ git config --global user.email yourname@example.com

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

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

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

$ git config --global --list

10.9.2. Gitリファレンス

次を参照下さい。

git-gui(1)とgitk(1)コマンドは簡単にGitが利用出来るようにします。

[警告] 警告

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

10.9.3. Gitコマンド

アップストリームが異なるVCSを使っていようと、アップストリームへのネットワーク接続無しにローカルコピーを管理できるので、ローカル活動にgit(1)を使うのは良い考えかもしれません。次はgit(1)とともに使われるパッケージとコマンドのリストです。

表10.20 git関連のパッケージとコマンドのリスト

コマンド パッケージ ポプコン サイズ 説明
N/A git-doc * I:2 6860 正式Git文書
N/A gitmagic * I:0.3 876 "Gitマジック"、Gitに関する分かり易いガイド
git(7) git-core * V:7, I:12 15056 git: 高速、スケーラブル、分散型リビジョンコントロールシステム
gitk(1) gitk * V:0.7, I:3 796 GUIによる履歴付きGitレポジトリーブラウザー
git-gui(1) git-gui * V:0.3, I:2 1456 Git用のGUI(履歴無し)
git-svnimport(1) git-svn * V:0.5, I:3 524 SubversionからGitへのデーターのインポート
git-svn(1) git-svn * V:0.5, I:3 524 SubversionとGit間での双方向操作を提供
git-cvsimport(1) git-cvs * V:0.15, I:1.4 656 CVSからiGitへのデーターのインポート
git-cvsexportcommit(1) git-cvs * V:0.15, I:1.4 656 GitからCVSチェックアウトに1コミットエキスポート
git-cvsserver(1) git-cvs * V:0.15, I:1.4 656 Git用CVSサーバーエミュレーター
git-send-email(1) git-email * V:0.09, I:1.4 392 Gitからパッチの集合のemailとして送信
stg(1) stgit * V:0.09, I:0.7 1864 Git上のquilt(Python)
git-buildpackage(1) git-buildpackage * V:0.12, I:1.0 508 Gitを使ってDebianパッケージ化を自動化
guilt(7) guilt * V:0.02, I:0.12 336 Git上のquilt(SH/AWK/SED/…)

10.9.4. 設定履歴記録のためのGit

Gitツールを使い設定の経時履歴をマニュアルで記録できます。次は"/etc/apt/"の内容を記録する単純な練習例です。

$ cd /etc/apt/
$ sudo git init
$ sudo chmod 700 .git
$ sudo git add .
$ sudo git commit -a

設定を説明とともにコミットします。

設定ファイルへの変更をします。

$ cd /etc/apt/
$ sudo git commit -a

設定を説明とともにコミットしそのままいろいろ作業をしていきます。

$ cd /etc/apt/
$ sudo gitk --all

フルの履歴を手中しています。

[注記] 注記

設定データーのどのファイルパーミッションでも機能するためにはsudo(8)が必要です。ユーザーの設定データーの場合sudoをスキップ出来るかもしれません。

[注記] 注記

上記例での"chmod 700 .git"コマンドはアーカイブデーターを不正読出しアクセスから守るために必要です。

[ティップ] ティップ

設定履歴の記録に関するより完全なセットアップは、etckeeperパッケージを見て下さい: 「設定ファイルの変更記録」