0

I am looking for a method of creating zip archives of files and folders on macOS that meets the following requirements:

  1. Creates zips from command line (not GUI such as Finder or Archive Utility)
  2. 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)
  3. 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 fail unzip -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 with ditto vs. Archive Utility. (For example, ditto zips report a Created Zip Spec of 15 '2.1', while Archive Utility zips report 14 '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.

Niel
  • 9
  • 3
  • Wow. Just tried it and `ditto` is seriously messed up on archives > 4 GB. One thing you might try is to write an AppleScript that does what you want using Archive Utility, and then calling that from the command line using `osascript`. – Mark Adler Apr 29 '23 at 18:47
  • Or `osascript` an AppleScript that does the Finder action. Either way. – Mark Adler Apr 29 '23 at 18:56

0 Answers0