dittoは、ファイルの拡張属性・ACL・リソースフォーク・quarantine(検疫)情報といったmacOS固有のメタデータをデフォルトで保持してコピーする。オプションを指定すると、メタデータの種類ごとに保持するかどうかを切り替えられる。
デフォルトでメタデータを保持する
検証用に、拡張属性とquarantine情報を付けたファイルを用意する。
$ mkdir src
$ echo hi > src/a.txt
$ xattr -w com.example.note "hello" src/a.txt
$ xattr -w com.apple.quarantine "0081;66f5a000;Safari;" src/a.txt
$ xattr -l src/a.txt
com.apple.provenance:
com.apple.quarantine: 0081;66f5a000;Safari;
com.example.note: hello
com.apple.provenanceは、xattr -wで付けた属性とは別に、macOSがファイルへ付与する属性である。以降の結果でもdittoのオプションに関係なく表示される。
オプションなしでdittoを実行すると、拡張属性とquarantine情報がコピー先にも付く。
$ ditto src dst
$ xattr -l dst/a.txt
com.apple.provenance:
com.apple.quarantine: 0281;6ab861d3;;
com.example.note: hello
com.apple.quarantineの値はコピー元と異なる。dittoはquarantine情報を拡張属性としてそのまま複製するのではなく、quarantine情報として付け直す。macOS 26.6の環境で試した結果では、フラグと時刻が書き換わり、ダウンロード元アプリ名(Safari)は空になった。
ACLも同様に保持される。
$ chmod +a "everyone allow read" src/a.txt
$ ls -le src/a.txt
-rw-r--r--@ 1 user wheel 3 9月 27 09:22 src/a.txt
0: group:everyone allow read
$ ditto src dst
$ ls -le dst/a.txt
-rw-r--r--@ 1 user wheel 3 9月 27 09:22 dst/a.txt
0: group:everyone allow read
cp -RはACLを保持しない。
$ cp -R src dst2
$ ls -le dst2/a.txt
-rw-r--r--@ 1 user wheel 3 9月 27 09:23 dst2/a.txt
保持するメタデータを切り替えるオプション
メタデータの種類ごとに、保持する・しないを指定するオプションがある。
| 保持する(デフォルト) | 保持しない | 対象 |
|---|---|---|
--rsrc | --norsrc | リソースフォークとHFSメタデータ |
--extattr | --noextattr | 拡張属性 |
--acl | --noacl | ACL |
--qtn | --noqtn | quarantine情報 |
同じ種類の保持する・しないオプションを両方指定した場合は、後に指定したほうが優先される。
--norsrcでメタデータをまとめて除外する
--norsrcを指定すると、リソースフォークに加えて、拡張属性・ACL・quarantine情報もまとめて除外する。
$ ditto --norsrc src dst
$ xattr -l dst/a.txt
com.apple.provenance:
$ ls -le dst/a.txt
-rw-r--r--@ 1 user wheel 3 9月 27 09:22 dst/a.txt
リソースフォークは、拡張属性com.apple.ResourceForkとして確認できる。--norsrcを指定すると、ファイル本体だけがコピーされる。
$ xattr -w com.apple.ResourceFork "resourcedata" src/r.txt
$ ditto src dst1
$ ls -l@ dst1/r.txt
-rw-r--r--@ 1 user wheel 4 9月 27 09:23 dst1/r.txt
com.apple.ResourceFork 12
com.apple.provenance 11
$ ditto --norsrc src dst2
$ ls -l@ dst2/r.txt
-rw-r--r--@ 1 user wheel 4 9月 27 09:23 dst2/r.txt
com.apple.provenance 11
--norsrcと保持する側のオプションを組み合わせると、特定のメタデータだけ残せる。たとえば--norsrc --extattrでは拡張属性だけを残す。
$ ditto --norsrc --extattr src dst
$ xattr -l dst/a.txt
com.apple.provenance:
com.apple.quarantine: 0081;66f5a000;Safari;
com.example.note: hello
個別のメタデータを除外する
--noextattrは拡張属性を除外する。ただしquarantine情報は--noextattrの対象外であり、コピー先に付く。
$ ditto --noextattr src dst
$ xattr -l dst/a.txt
com.apple.provenance:
com.apple.quarantine: 0281;6ab861fe;;
--noaclはACLだけを除外する。
$ ditto --noacl src dst
$ ls -le dst/a.txt
-rw-r--r--@ 1 user wheel 3 9月 27 09:22 dst/a.txt
--noqtnだけではquarantine情報が残る
--noqtnは「quarantine情報を保持しない」オプションである。しかし--noqtnだけを指定しても、コピー先にはcom.apple.quarantineが残る。
$ ditto --noqtn src dst
$ xattr -l dst/a.txt
com.apple.provenance:
com.apple.quarantine: 0081;66f5a000;Safari;
com.example.note: hello
--noqtnで止まるのは、dittoによるquarantine情報の付け直しだけである。拡張属性のコピーは有効なままなので、com.apple.quarantineは通常の拡張属性として元の値のまま複製される。
DITTO_TEST_OPTIONS=1を付けて実行すると、実際にはコピーせずにditto内部のコピー設定を表示する。--noqtnを付けるとcopyQuarantineだけが消え、copyExtendedAttributesは残る。
$ DITTO_TEST_OPTIONS=1 ditto src dst
src
dst
copyACLs: true
copyExtendedAttributes: true
copyQuarantine: true
copyResources: true
crossDevices: true
persistRestrictedFlags: true
persistRootlessEAs: true
preserveHFSPlusCompression: true
$ DITTO_TEST_OPTIONS=1 ditto --noqtn src dst
src
dst
copyACLs: true
copyExtendedAttributes: true
copyResources: true
crossDevices: true
persistRestrictedFlags: true
persistRootlessEAs: true
preserveHFSPlusCompression: true
quarantine情報を確実に外すには、--noqtnと--noextattrを組み合わせる。
$ ditto --noqtn --noextattr src dst
$ xattr -l dst/a.txt
com.apple.provenance:
他の拡張属性を残したい場合は、コピー後にxattr -d com.apple.quarantineで削除する。
環境変数DITTONORSRCで一括指定する
環境変数DITTONORSRCを設定すると、--norsrc --noextattr --noacl --noqtnを指定した場合と同じ動作になる。
$ DITTONORSRC=1 ditto src dst
$ xattr -l dst/a.txt
com.apple.provenance:
DITTONORSRCを設定した状態で特定のメタデータだけ残したい場合は、--rsrcと組み合わせて指定する。--extattrや--aclは--rsrcを前提とするオプションである。単独で指定してもDITTONORSRCの設定が優先された。
$ DITTONORSRC=1 ditto --rsrc --extattr src dst
$ xattr -l dst/a.txt
com.apple.provenance:
com.apple.quarantine: 0081;66f5a000;Safari;
com.example.note: hello
