I am looking for a method of creating zip archives of files and folders on macOS that meets the following requirements:
- Creates zips from command line (not GUI such as Finder or Archive Utility)
- Properly preserves macOS metadata (resource forks, xattrs, acls, etc.), to the same degree as Apple's built-in Archive Utility, and ideally in the same way (sequestered to
__MACOSX
subdirectory) - Results in a valid compressed .zip file that will pass an
unzip -t
test without errors, even when larger than 4GB.
Bonus points if it can be done with built-in tools, but I'm open to third-party solutions as well.
Many previous answers suggest that the solution should be a ditto
command like the following, which is supposedly what Archive Utility itself uses under the hood:
ditto -c -k --sequesterRsrc --keepParent src_directory archive.zip
This may have been true at some point, but I suspect that it is no longer what Archive Utility is using (as of macOS 13 Ventura), because, for example:
- Large (> 4GB) zips created with
ditto
failunzip -t
tests (extra bytes at beginning or within zipfile
/bad zipfile offset (local header sig)
), while zips created with Archive Utility or Finder (right-click > Compress) do not have this problem. zipdetails
reveals many other internal differences between zips created withditto
vs. Archive Utility. (For example,ditto
zips report aCreated Zip Spec
of15 '2.1'
, while Archive Utility zips report14 '2.0'
.)
After some experimentation, it seems that Archive Utility zips share much more internal similarity with zips created by tar
, such as:
tar --mac-metadata --format zip -cvf archive.zip -C src_parent_directory src_file_or_folder_name
Perhaps not coincidentally, tar
is also Apple's official recommendation for creating compressed file archives from terminal (but only for tar archives, not zip).
Problem is: the zips created by tar
do not seem to properly preserve mac metadata, unlike zips created by ditto
and even unlike tars created by tar
. For example, the following command DOES preserve xattrs, unlike the above command:
tar --mac-metadata -cvzf archive.tar -C src_parent_directory src_file_or_folder_name
But for some reason it does not behave the same way when creating a zip, even though there's nothing in the man page that would suggest this is not supported. (I've also tried various combinations of --mac-metadata
, --xattrs
, and --acls
, none of which seem to make any difference.)
It seems like it must be possible somehow, since Archive Utility is able to do it. Anyone have suggestions? This longtime-lurker-firsttime-poster would be very grateful. Thanks!
[EDIT: it's been over a month and no one has answered yet... in case this makes it easier: I would also accept a solution that preserves resource forks and xattrs but NOT acls.]
To summarize:
ditto -c -k --sequesterRsrc --keepParent src_directory archive.zip
Meets requirements 1 and 2, but not 3.
tar --mac-metadata --format zip -cvf archive.zip -C src_parent_directory src_file_or_folder_name
Meets requirements 1 and 3, but not 2.
zip -r archive.zip src_directory
Meets requirements 1 and 3, but not 2.
tar --mac-metadata -cvzf archive.tar -C src_parent_directory src_file_or_folder_name
Meets requirement 2, but not 1 or 3 (because result is not a zip)
Archive Utility
and Finder right-click > Compress...
Meets requirements 2 and 3, but not 1.