كيف أقوم بتعيين الأذونات (السمات) على ملف في ملف ZIP باستخدام وحدة zipfile الخاصة بـ Python؟

StackOverflow https://stackoverflow.com/questions/434641

سؤال

عندما أقوم باستخراج الملفات من ملف ZIP تم إنشاؤه باستخدام Python zipfile الوحدة، جميع الملفات غير قابلة للكتابة، للقراءة فقط وما إلى ذلك.

يتم إنشاء الملف واستخراجه ضمن Linux وPython 2.5.2.

بأفضل ما أستطيع قوله، أحتاج إلى ضبط ZipInfo.external_attr خاصية لكل ملف، ولكن يبدو أن هذا لا يتم توثيقه في أي مكان يمكنني العثور عليه، هل يمكن لأي شخص أن ينيرني؟

هل كانت مفيدة؟

المحلول

ويبدو أن هذا العمل (بفضل ايفان، وضعه هنا حتى الخط في السياق):

buffer = "path/filename.zip"  # zip filename to write (or file-like object)
name = "folder/data.txt"      # name of file inside zip 
bytes = "blah blah blah"      # contents of file inside zip

zip = zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo(name)
info.external_attr = 0777 << 16L # give full access to included file
zip.writestr(info, bytes)
zip.close()

وأنا لا تزال ترغب في رؤية شيء يوثق كان هذا ... مورد إضافي وجدت مذكرة على شكل ملف مضغوط: <لأ href = "http://www.pkware.com/documents/casestudies/ APPNOTE.TXT "يختلط =" noreferrer "> http://www.pkware.com/documents/casestudies/APPNOTE.TXT

نصائح أخرى

هذا الرابط ديه معلومات أكثر من أي شيء آخر لقد كنت قادرة على العثور على النت. حتى مصدر البريدي لايوجد أي شيء. نسخ القسم المختص للأجيال القادمة. هذا التصحيح ليس حقا حول توثيق هذا الشكل، والذي يذهب فقط لاظهار كيف مثير للشفقة (قراءة غير موجودة) وثائق الحالية.

# external_attr is 4 bytes in size. The high order two
# bytes represent UNIX permission and file type bits,
# while the low order two contain MS-DOS FAT file
# attributes, most notably bit 4 marking directories.
if node.isfile:
    zipinfo.compress_type = ZIP_DEFLATED
    zipinfo.external_attr = 0644 << 16L # permissions -r-wr--r--
    data = node.get_content().read()
    properties = node.get_properties()
    if 'svn:special' in properties and \
           data.startswith('link '):
        data = data[5:]
        zipinfo.external_attr |= 0120000 << 16L # symlink file type
        zipinfo.compress_type = ZIP_STORED
    if 'svn:executable' in properties:
        zipinfo.external_attr |= 0755 << 16L # -rwxr-xr-x
    zipfile.writestr(zipinfo, data)
elif node.isdir and path:
    if not zipinfo.filename.endswith('/'):
        zipinfo.filename += '/'
    zipinfo.compress_type = ZIP_STORED
    zipinfo.external_attr = 040755 << 16L # permissions drwxr-xr-x
    zipinfo.external_attr |= 0x10 # MS-DOS directory flag
    zipfile.writestr(zipinfo, '')

وأيضا، هذا الرابط لديه يلي. هنا المنخفض ترتيب بايت يعني يفترض أن أقصى اليمين (الأدنى) بايت بايت الأربعة. لذلك هذا هو واحد لMS-DOS، ويمكن أن يفترض أن تترك صفر خلاف ذلك.

<اقتباس فقرة>   

وملف خارجي سمات: (4 بايت)

      The mapping of the external attributes is
      host-system dependent (see 'version made by').  For
      MS-DOS, the low order byte is the MS-DOS directory
      attribute byte.  If input came from standard input, this
      field is set to zero.

وأيضا، ملف المصدر يونيكس / unix.c في المصادر لبرنامج البريدي InfoZIP، وتحميلها من أرشيف دبيان تمت يلي في التعليقات.

  /* lower-middle external-attribute byte (unused until now):
   *   high bit        => (have GMT mod/acc times) >>> NO LONGER USED! <<<
   *   second-high bit => have Unix UID/GID info
   * NOTE: The high bit was NEVER used in any official Info-ZIP release,
   *       but its future use should be avoided (if possible), since it
   *       was used as "GMT mod/acc times local extra field" flags in Zip beta
   *       versions 2.0j up to 2.0v, for about 1.5 years.
   */

وهكذا أخذ كل هذا معا، يبدو فقط يستخدم ثاني أعلى بايت في الواقع، على الأقل ليونكس.

وتحرير: سألت عن الجانب يونكس ذلك على Unix.SX، في مسألة "<لأ href =" https://unix.stackexchange.com/questions/14705/the-zip-formats-external-file -attribute "> ملف خارجي والشكل والرمز البريدي ويعزو ". يبدو أنني حصلت على زوجين من الأشياء الخاطئة. على وجه التحديد وتستخدم كل من اثنين من كبار بايت ليونكس.

أنظر إلى هذا: تعيين الأذونات على ملف مضغوط في بيثون

لست متأكدًا تمامًا مما إذا كان هذا هو ما تريده، ولكن يبدو أنه كذلك.

يبدو أن الخط الرئيسي هو:

zi.external_attr = 0777 << 16L

يبدو أنه يقوم بتعيين الأذونات على 0777 هناك.

وقال إن الأجوبة السابقة لا تعمل بالنسبة لي (على OS X 10.12). لقد وجدت أنه كذلك الأعلام القابلة للتنفيذ (ثماني 755)، وأنا أيضا بحاجة إلى تعيين "ملف العادية" العلم (ثماني 100000). لقد وجدت هذا المذكورة هنا: https://unix.stackexchange.com/questions/ 14705 / ل-الرمز البريدي الأشكال الخارجية ملف السمة

وهناك مثال الكامل:

zipname = "test.zip"
filename = "test-executable"

zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)

f = open(filename, 'r')
bytes = f.read()
f.close()

info = zipfile.ZipInfo(filename)
info.date_time = time.localtime()
info.external_attr = 0100755 << 16L

zip.writestr(info, bytes, zipfile.ZIP_DEFLATED)

zip.close()

وهناك مثال كاملة من بلدي نموذج التطبيقي معين، وخلق الرمز البريدي من .app ذلك أن كل شيء في Contents/MacOS/ المجلد هو قابل للتنفيذ: <لأ href = "https://gist.github.com/Draknek/3ce889860cea4f59838386a79cc11a85" يختلط = " noreferrer "> https://gist.github.com/Draknek/3ce889860cea4f59838386a79cc11a85

يمكنك تمديد ZipFile فئة لتغيير إذن الملف الافتراضي:

from zipfile import ZipFile, ZipInfo
import time

class PermissiveZipFile(ZipFile):
    def writestr(self, zinfo_or_arcname, data, compress_type=None):
        if not isinstance(zinfo_or_arcname, ZipInfo):
            zinfo = ZipInfo(filename=zinfo_or_arcname,
                            date_time=time.localtime(time.time())[:6])

            zinfo.compress_type = self.compression
            if zinfo.filename[-1] == '/':
                zinfo.external_attr = 0o40775 << 16   # drwxrwxr-x
                zinfo.external_attr |= 0x10           # MS-DOS directory flag
            else:
                zinfo.external_attr = 0o664 << 16     # ?rw-rw-r--
        else:
            zinfo = zinfo_or_arcname

        super(PermissiveZipFile, self).writestr(zinfo, data, compress_type)

يغير هذا المثال إذن الملف الافتراضي إلى 664 ويحافظ 775 للدلائل.

الكود ذو الصلة:

وعند القيام بذلك من هذا القبيل، وأنها لا تعمل على ما يرام؟

zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
    f = open(name, 'wb')
    f.write(self.read(name))
    f.close()

إذا لم يكن كذلك، فما استقاموا لكم فاستقيموا أقترح رمي في os.chmod في لحلقة مع 0777 أذونات مثل هذا:

zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
    f = open(name, 'wb')
    f.write(self.read(name))
    f.close()
    os.chmod(name, 0777)

وننظر أيضا في ما حدة بيثون zipfile لا:

def write(self, filename, arcname=None, compress_type=None):
    ...
    st = os.stat(filename)
    ...
    zinfo = ZipInfo(arcname, date_time)
    zinfo.external_attr = (st[0] & 0xFFFF) << 16L      # Unix attributes
    ...

و`` `

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top