0

I'm trying to create a python script which places a number of files in a "staging" directory tree, and then uses ZipFile to a create a .zip archive of them. This will later be copied to a linux machine, which will extract the files and use them. The staging directory contains a mix of text and binary data files. The section doing the writing is in this "try" block:

try:
    import zipfile
    zipf = zipfile.ZipFile(out_file, 'w', zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(staging_dir):
        for d in dirs:
            # Write directories so even empty directories are copied:
            arcname = os.path.relpath(os.path.join(root, d), staging_dir)
            zipf.write(os.path.join(root, d), arcname)
        for f in files:
            arcname = os.path.relpath(os.path.join(root, f), staging_dir)
            zipf.write(os.path.join(root, f), arcname)

This works on a linux machine running python 2.7 (my main goal) or 3.x (secondary goal). It can also run on a Windows machine (sort of an afterthought, it might be useful), but there's a problem with permissions in that case. Normally the script sets permissions in the files in the staging_dir with "os.chmod", and then zip creates the archive with the right permissions. But running this on windows, the "os.chmod" command doesn't really set all linux file modes (not possible), so the zipfile contents aren't at the right permissions. I'm trying to figure out if there's a way to fix the permissions when making the zipfile in the code above. In particular, files in staging_dir/bin need to have "0o750" permissions.

I've seen the answer to How do I set permissions (attributes) on a file in a ZIP file using Python's zipfile module, so I see how you could set permissions with "external_attr", and then write a file with "ZipFile.writestr". But the "external_attr" doesn't seem to apply to "ZipFile.write", only "ZipFile.writestr". And I'd like to do this on a zip archive that contains some binary files. Is there any other option than "writestr"? Is it be possible to use "writestr" on large binary files?

Dharman
  • 30,962
  • 25
  • 85
  • 135
PeterS6g
  • 122
  • 11
  • Which version of ZipFile? I found this which seems to be glancingly related, but I'm not sure if it's relevant to the version you're using. https://stackoverflow.com/questions/42326428/zipfile-in-python-file-permission/46837272 (look at the accepted answer to see what i'm talking about) – ingernet Nov 29 '19 at 21:12
  • Does ZipFile have a separate version than Python? I'm trying to get this to run in a variety of environments. It has to work on Python as old as 2.7, so I think the ZipFile could to be that old (or newer). – PeterS6g Nov 29 '19 at 21:20
  • My misunderstanding! For some reason, in my head, zipfile was an external library. Too much turkey on the brain. – ingernet Nov 29 '19 at 21:40
  • ok, one more thing. doesn't answer your question about how to do this within the zipping process, but might help you pivot a bit and solve this problem at the os.chmod level, which was the cause of this whole thing: https://stackoverflow.com/questions/27500067/chmod-issue-to-change-file-permission-using-python ...good luck! please let us know if you end up finding a solution. – ingernet Nov 29 '19 at 21:45
  • I did see that question about chmod, and noticed this: "Although Windows supports chmod(), you can only set the file's read-only flag with it (via the stat.S_IWRITE and stat.S_IREAD constants or a corresponding integer value). All other bits are ignored". That's why I realized that I couldn't rely on setting the execute bit in a windows environment. I think my pivot on this would be to instead change the permissions when the linux system unzips the file, which would work, but isn't ideal. I don't like that the zip file contents are subtly different depending on where it was created. – PeterS6g Dec 01 '19 at 17:29

0 Answers0