Macで困っていたことの一つに、コマンドラインでファイルをコピーしたときのタイムスタンプの扱いがあった。作成日時(crtime: creation timeまたはbtime: birth time)が保持されないのだ。Finderでコピーしたときはすべて保たれるのに、コマンドラインからではcp
、CpMac
、ditto
、cpio
、pax
、tar
、rsync
等、いずれも維持されなかった。作成日時を持たないUnixだからしょうがないともいえるが、完全なバックアップを取りたいときなどに不満だった。余談だが、AppleScriptを使ってFinderにコピーさせようとか、SetFile
を使って一致させようとかする自作コマンドを作ってみたりしたくらいだ。
この長年の悩みを解消する方法を最近、知った。Homebrew版rsyncには、これを実現するオプション-N, --crtimesが追加されているのだ!*1
[追記 2019/06/14] コンピュータ間の転送には追加のオプションが必要になるかもしれません。
Homebrew版rsync
rsync -ahvANX src ... dest
とでもすれば、もろもろコピーしてくれる。
- -a, --archive
= -rlptgoD - -r, --recursive
ディレクトリ内を再帰的に処理(フォルダ以下を丸ごとコピー) - -l, --links
シンボリックリンクをシンボリックリンクとしてコピー - -p, --perms
パーミッションを保持 - -t, --times
変更日時を保持 - -g, --group
グループを保持 - -o, --owner
所有者を保持(スーパーユーザのみ) - -D
= --devices --specials - --devices
デバイスファイルを保持(スーパーユーザのみ) - --specials
特殊ファイルを保持 - -h, --human-readable
数値を人間が読みやすい形式で出力 - -v, --verbose
表示をより詳細に出力 - -N, --crtimes
作成日時を保持
-A、-Xはアクセス制御リストACLや拡張属性EA(リソースフォークやHFSメタデータを含む)を保持させる。(FinderによるコピーではACLグループとオーナーはキープされないようだ。)
- -A, --acls
ACL (Access Control List)を保持(-pを含む) - -X, --xattrs
EA (Extended Attribute)を保持
Mac (BSD)のcp
と同様にsrcとsrc/で挙動が違うことに注意(src/はsrcの中身)。
この辺が気に入らないことを考慮し、ecp
というコマンドを書いてみた。
ecp(.sh)
#!/bin/bash src=("${@:1:$#-1}") src=("${src[@]%/}") dest="${@:$#}" rsync -aANX "${src[@]}" "${dest}"
コマンドライン引数は最後以外、末尾の/を除去するようにした(srcは常にディレクトリ自体を指す)。
いずれのrsync
の呼び出し方にしても、-n, --dry-runをつけてお試し実行するようにしてほしい。
*1:crtimes.diffというパッチが当てられている