15

I'm building a linux installer for a Java application, and I end up with an install.jar and a setup.sh that I put in a zip file using ant.

The idea is the user unzips the zip file and then runs setup.sh but the trouble is that they always need to chmod setup.sh first to give themselves execute permissions.

I want to remove this step and Im not sure if the problem part is:

  1. That Im building on Windows
  2. That Im building with ant zip task
  3. Or that zips cannot presreve permissions and will always unzip without x permissions.
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
  • Permissions are external to the file, and particular to the filesystem. So, even if I cannot give an argumented answer, I vote for 3). Also, which permissions do you want to pass from your Windows FS to Unix? Even if zip supports that, building the file from windows makes no sense. – SJuan76 Nov 29 '12 at 19:50
  • Windows doesn't have the same perms as Unix; IIRC it'll default to `0666` for files. Or `0644`?. Which is less-funny than 666. I don't know if you can override it or not. – Dave Newton Nov 29 '12 at 19:52
  • I just want execute permission for the user, I could create the zip on linux if I really have to but would that fix it ? – Paul Taylor Nov 29 '12 at 21:42

7 Answers7

27

You don't have to switch to tar files. I don't know why people who don't know Ant are offering advice on this topic.

Use zipfileset's filemode parameter. Documented at http://ant.apache.org/manual/Types/zipfileset.html

Blaine
  • 1,577
  • 2
  • 17
  • 15
17

You cannot store Linux/Unix file permissions in a ZIP file.

Edit (after comments) by using the "external attributes" field inside the ZIP header these attributes can be store inside a ZIP file. GNU's unzip is apparently able to read that additional field and restore file permissions. I'm not sure when this was added to the ZIP format as the early versions - coming from a MS-DOS world - did not have support for this.

The TAR format - being a "native" Unix/Linux format - has been designed to include file attributes and Ant can create TAR files that will preserve attributes across all Linux/Unix operating systems.

<tar compression="gzip" destfile="my-archive.tgz">
  <tarfileset mode="544" dir="dir_with_shell_scripts">
     <include name="*.sh"/>
  </tarfileset>
</tar>
  • Thankyou that worked :) , my only concern is that when a user downloads this file they need to do 'tar xvf file' which is rather less intuitive than 'unzip file' – Paul Taylor Nov 30 '12 at 10:35
  • 4
    @PaulTaylor: for Unix/Linux users the tar format is (usually) much more natural than the ZIP format. –  Nov 30 '12 at 10:36
  • 1
    It is in fact possible to smuggle Unix permissions into a ZIP file, in the "Extra" field. See https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/434689#434689 – offby1 Jan 27 '14 at 22:34
  • 1
    @offby1: interesting. Do the usual unzip programs honour this? –  Jan 27 '14 at 22:37
  • 1
    @a_horse_with_no_name the "unzip" on RHEL 5.3 does, I know that much :) – offby1 Jan 28 '14 at 03:31
  • See @Blaine's answer for a real solution – Liosan Feb 06 '14 at 15:29
  • @Liosan: it might be the better answer, but I don't see a reason to downvote my (working) answer because of that. –  Feb 06 '14 at 15:58
  • @a_horse_with_no_name The reason for the downvote is because you state "You cannot store Linux/Unix file permissions in a ZIP file.", which is not true :) – Liosan Feb 07 '14 at 12:57
  • @Liosan: I edited my answer. But it's still unclear to me if those external attributes work for all Unix/Linux flavors? (Solaris, AIX, MacOS, BSD, ...). The `tar` format *does*. –  Feb 07 '14 at 13:06
  • @a_horse_with_no_name Ok, downvote reverted :) Indeed those attributes in .zipfiles are a bit fishy. – Liosan Feb 07 '14 at 13:07
  • Unix `unzip` restores permissions by default, and `[sudo] unzip -X [-K]` also restores UID and GID. – caw May 21 '21 at 20:36
3

To expand on Blaine’s answer, you can use <zipfileset> child elements to specify permissions:

<zip destfile="build/MyApplication.zip" encoding="UTF-8">

    <zipfileset dir="${content-dir}" encoding="UTF-8"
        includes="**/setup.sh" filemode="755"/>

    <zipfileset dir="${content-dir}" encoding="UTF-8"
        excludes="**/setup.sh"/>

</zip>
VGR
  • 40,506
  • 4
  • 48
  • 63
2

I think you can do this with Apache Commons Compress.

First paragraph:

Access to internal and external attributes (which are used to store Unix permission by some zip implementations).

Take a look at the API and look for setUnixMode()

mprivat
  • 21,582
  • 4
  • 54
  • 64
1

zip/unzip in modern linux distros will preserve file permissions. But you need to make sure that the zip in windows honours this.

Humpity
  • 152
  • 1
  • 9
-1

If you use a tar file instead of a zip file, it should preserve the permissions for you. The files' owners and groups might not match up, but the permission bits will.

dj_segfault
  • 11,957
  • 4
  • 29
  • 37
-1
<shellscript shell="sh" dir="abc" failonerror="true">
            zip -ry abc.zip *
</shellscript>

The ant script above invokes a shell script to create the zip archive in which the permissions are very well preserved. It works with Ant 1.7 and above. However I have not tried verified running this ant script on windows. This works very well on mac.

Varun Bhatia
  • 4,326
  • 32
  • 46