Home > DBCLS > Mac OS Xのコマンドラインでファイルを完璧にコピーする方法

Mac OS Xのコマンドラインでファイルを完璧にコピーする方法

  • 2011-04-21 (木) 19:51
  • DBCLS

Mac OS XのファイルはリソースフォークとかExtended Attribute、ACLといった情報を含んでおり、単なるcpとかscpではこのような情報が完璧に保持されるわけではない。

以前にMac OS X 10.5(Leopard)のコマンドラインで「完璧な」ファイルのコピーをおこなう方法を検討したのでその方法を書き留めておく。なお、Mac OS X 10.6(Snow Leopard)に移行してもそのまま利用可能だ。

基本的にはrsyncを使っている。rsyncのメリットは何と言っても差分コピーができること。たとえばホームディレクトリの定期的なバックアップに利用すれば、変更したファイルだけをコピーしてくれるので無駄がない。ファイルに変更がなくても、たとえばパーミッション等を変えるとちゃんとその情報がコピーされるのも隙がない。

もうひとつのメリットは、sshを利用して別のマシンに「完璧な」コピーを送れること。複数のMacをまったく同じ環境にセットアップしたり、リモートからバックアップを取るのに役立つ。ちなみにmesoは職場と自宅のMacを毎日この方法で同期していた。差分だけを転送するので数分程度で完了する(ただし巨大なファイルを転送するときは別)。

ここで注意が必要なのは、Leopardに標準で入っているrsyncは、どういうわけか毎回全てのファイルのリソースフォークをコピーして効率が悪いうえ、ハードリンクなどが保持されない。そこでrsyncにいくつかのパッチをあてソースからコンパイルすることにした。

参考

rsyncのコンパイル

curl -sO http://rsync.samba.org/ftp/rsync/src/rsync-3.0.4.tar.gz
curl -sO http://rsync.samba.org/ftp/rsync/src/rsync-patches-3.0.4.tar.gz

tar xzf rsync-3.0.4.tar.gz
tar xzf rsync-patches-3.0.4.tar.gz

cd rsync-3.0.4

# Apply patches relevant to preserving Mac OS X metadata

patch -p1 < patches/fileflags.diff
patch -p1 < patches/crtimes.diff

./configure
make

成功すればrsyncというバイナリができているはずだ。なお、ACLは10.4(Tiger)以降なので、Mac OS 10.3(Panther)上ではACL関係でエラーが出てコンパイルできない。

mesoは職場でIntel Mac、自宅でPowerPC Macを使っているので、両方の環境で実行できるようにユニバーサルバイナリ化した。

# Intel Macでmakeしたもの → rsync-3.0.4-i386/rsync
# PowerPC Macでmakeしたもの → rsync-3.0.4-PPC/rsync
# として、lipoでユニバーサルバイナリ化する。

lipo -create rsync-3.0.4-i386/rsync rsync-3.0.4-ppc/rsync -output rsync

# OS標準のrsyncと容易に区別できるよう、名前を変えておく。

cp -pi rsync ~/bin/rsync-304

Backup Bouncerによる評価

上記でmakeしたrsyncで「完璧な」コピーができるのかを、Backup Bouncerで検証。Backup Bouncerは、Mac OS Xのファイルが保持している各種情報が、コピー後にもちゃんと継承されているかどうかをテストするためのツール。ここで評価したのは、

  • Mac OS X 10.5 (Leopard)標準のrsync
  • rsyncx
  • rsync_hfs
  • 今回makeしたrsync-304

結果のみ示す。すべてのテスト項目をパスしたら、とりあえず完璧と呼ぶことにする。

テスト項目Leopard
rsync
rsyncxrsync_hfsrsync-304←304で使用
するオプション
basic-permissions (Critical)okokokok-a
timestamps (Critical)okokokok-a
symlinks (Critical)okokokok-a
symlink-ownershipokFAILFAILok-a
hardlinks (Important)FAILFAILFAILok-aH
resource-forks, on files (Critical)okokokok-aX
resource-forks,
on hardlinked files (Important)
FAILFAILFAILok-aHX
finder-flags (Critical)okFAILFAILok-aX
finder-locksFAILokFAILok–fileflags
creation-dateFAILokFAILok-aN
bsd-flagsokokokok-a
extended-attrs, on files (Important)okFAILFAILok-aX
extended-attrs, on directories (Important)okFAILFAILok-aX
extended-attrs, on symlinksFAILFAILFAILok-aX
access-control-lists, on files (Important)okFAILFAILok-aA
access-control-lists, on dirs (Important)okFAILFAILok-aA
fifookokokok-a
devicesokFAILokok-a
combo-tests, xattrs + rsrc forksokFAILFAILok-aX
combo-tests, lots of metadataokFAILFAILok-aAX

rsync-304のつかいかた

今回makeしたrsync-304ですべてのテストをパスすることがわかったので、これを使っていくことにした。与えるオプションは次の通り。

rsync-304 -avNHAX --fileflags --force-change --delete --stats

別のマシンにコピーするときは、そのマシンにも今回makeしたrsync-304を入れておく必要がある。そして、相手側のrsyncの位置をオプションで与える。たとえば、

--rsync-path=/Users/meso/bin/rsync-304

以上をまとめて、mesoは下記のようにscpxというエイリアスを設定し、コピーはすべてこれに任せている。

alias scpx='/Users/meso/bin/rsync-304 \
--rsync-path=/Users/meso/bin/rsync-304 \
-avNHAX --fileflags --force-change --delete --stats'

つかいかた:

# デスクトップにコピー

scpx hogehoge ~/Desktop/

# 別のマシンのデスクトップにコピー

scpx hogehoge meso@133.11.XX.XX:Desktop/

#  別のマシンにあるディレクトリをlocalにコピー

scpx meso@133.11.x.x:Desktop/hogehoge ./

# sshのポートを変更

scpx -e "ssh -p 12345" hogehoge meso@133.11.x.x:Desktop/

# ふつうにscpすると古いファイルは上書きされたり消されたり
# するが、obsolete以下に移動して取っておくにはこうする。
# 差分バックアップで過去のファイルを残したいときに便利。

scpx --backup --backup-dir=obsolete  meso  backup/

Trackbacks:0

Trackback URL for this entry
/archives/3/trackback
Listed below are links to weblogs that reference
Mac OS Xのコマンドラインでファイルを完璧にコピーする方法 from mesoの実験ノート

Home > DBCLS > Mac OS Xのコマンドラインでファイルを完璧にコピーする方法

Search
Feeds
Meta

Return to page top