tarfile --- خواندن و نوشتن پرونده‌های بایگانی tar

کد منبع: Lib/tarfile.py


ماژول tarfile امکان خواندن و نوشتن بایگانی‌های tar، از جمله آن‌هایی که از فشرده‌سازی gzip، bz2 و lzma استفاده می‌کنند، را فراهم می‌کند. برای خواندن یا نوشتن پرونده‌های .zip، از ماژول zipfile یا توابع سطح بالاتر در shutil استفاده کنید.

برخی حقایق و ارقام:

  • اگر ماژول‌های مربوطه در دسترس باشند، بایگانی‌های فشرده‌ی gzip، bz2، compression.zstd و lzma را می‌خواند و می‌نویسد.

    اگر هر یک از این ماژول‌های اختیاری در نسخه CPython شما وجود نداشته باشد، به دنبال مستندات توزیع‌کننده خود بگردید (یعنی هر کسی که پایتون را در اختیار شما قرار داده است). اگر توزیع‌کننده هستید، نیازمندی‌های ماژول‌های اختیاری را ببینید.

  • پشتیبانی از خواندن/نوشتن برای قالب POSIX.1-1988 (ustar).

  • پشتیبانی از خواندن/نوشتن برای قالب GNU tar شامل افزونه‌های longname و longlink، پشتیبانی فقط‌خواندنی از تمام انواع افزونه sparse از جمله بازیابی پرونده‌های پراکنده (sparse).

  • پشتیبانی از خواندن/نوشتن قالب POSIX.1-2001 (pax).

  • پوشه‌ها، پرونده‌های معمولی، پیوندهای سخت، پیوندهای نمادین، FIFOها، دستگاه‌های نویسه‌ای و دستگاه‌های بلوکی را مدیریت می‌کند و قادر است اطلاعات پرونده مانند برچسب زمانی، مجوزهای دسترسی و مالک را دریافت و بازیابی کند.

تغییر یافته در نسخه‌ی 3.3: پشتیبانی از فشرده‌سازی lzma افزوده شد.

تغییر یافته در نسخه‌ی 3.12: بایگانی‌ها با استفاده از یک فیلتر استخراج می‌شوند، که این امکان را به شما می‌دهد که یا ویژگی‌های غافلگیرکننده/خطرناک را محدود کنید، یا تأیید کنید که مورد انتظار هستند و بایگانی کاملاً مورد اعتماد است.

تغییر یافته در نسخه‌ی 3.14: فیلتر استخراج پیش‌فرض روی data تنظیم شد، که برخی قابلیت‌های خطرناک مانند پیوندها به مسیرهای مطلق یا مسیرهای خارج از مقصد را ممنوع می‌کند. پیش‌تر، راهبرد فیلتر معادل fully_trusted بود.

تغییر یافته در نسخه‌ی 3.14: پشتیبانی از فشرده‌سازی Zstandard با استفاده از compression.zstd افزوده شد.

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

یک شیء TarFile را برای مسیر name بازمی‌گرداند. برای اطلاعات دقیق درباره اشیای TarFile و آرگومان‌های کلیدواژه‌ای مجاز، اشیای TarFile را ببینید.

mode باید رشته‌ای به شکل 'filemode[:compression]' باشد؛ مقدار پیش‌فرض آن 'r' است. در اینجا فهرست کاملی از ترکیب‌های حالت آمده است:

حالت

اکشن

'r' یا 'r:*'

برای خواندن با فشرده‌سازی شفاف باز شود (توصیه‌شده).

'r:'

باز کردن برای خواندن به‌صورت انحصاری، بدون فشرده‌سازی.

'r:gz'

باز کردن برای خواندن با فشرده‌سازی gzip.

'r:bz2'

برای خواندن با فشرده‌سازی bzip2 باز می‌شود.

'r:xz'

باز کردن برای خواندن با فشرده‌سازی lzma.

'r:zst'

باز کردن برای خواندن با فشرده‌سازی Zstandard.

'x' یا 'x:'

یک پرونده tar را به‌صورت انحصاری و بدون فشرده‌سازی ایجاد می‌کند. اگر از قبل وجود داشته باشد، استثنای FileExistsError پرتاب می‌شود.

'x:gz'

یک tarfile با فشرده‌سازی gzip ایجاد کنید. اگر از پیش وجود داشته باشد، استثنای FileExistsError را پرتاب کنید.

'x:bz2'

یک پرونده tar با فشرده‌سازی bzip2 ایجاد می‌کند. اگر از قبل وجود داشته باشد، استثنای FileExistsError را پرتاب می‌کند.

'x:xz'

یک پرونده tar با فشرده‌سازی lzma ایجاد کنید. اگر از قبل وجود دارد، استثنای FileExistsError را پرتاب کنید.

'x:zst'

یک پرونده tar با فشرده‌سازی Zstandard ایجاد می‌کند. اگر از قبل وجود داشته باشد، استثنای FileExistsError را پرتاب می‌کند.

'a' یا 'a:'

برای الحاق بدون فشرده‌سازی باز می‌شود. اگر پرونده موجود نباشد، ایجاد می‌شود.

'w' یا 'w:'

برای نوشتن فشرده‌نشده باز شود.

'w:gz'

برای نوشتن با فشرده‌سازی gzip باز شود.

'w:bz2'

برای نوشتن با فشرده‌سازی bzip2 باز می‌شود.

'w:xz'

برای نوشتن با فشرده‌سازی lzma باز می‌شود.

'w:zst'

باز کردن برای نوشتن با فشردگی Zstandard.

توجه داشته باشید که 'a:gz'، 'a:bz2' یا 'a:xz' امکان‌پذیر نیست. اگر mode برای باز کردن یک پرونده مشخص (فشرده) جهت خواندن مناسب نباشد، ReadError پرتاب می‌شود. برای اجتناب از این حالت، از mode 'r' استفاده کنید. اگر یک روش فشرده‌سازی پشتیبانی نشود، CompressionError پرتاب می‌شود.

اگر fileobj مشخص شده باشد، از آن به‌عنوان جایگزینی برای یک file object بازشده در حالت دودویی برای name استفاده می‌شود. انتظار می‌رود در موقعیت ۰ قرار داشته باشد.

برای حالت‌های 'w:gz'، 'x:gz'، 'w|gz'، 'w:bz2'، 'x:bz2'، 'w|bz2'، tarfile.open() آرگومان کلیدواژه‌ای compresslevel (پیش‌فرض 9) را برای تعیین سطح فشرده‌سازی پرونده می‌پذیرد.

برای حالت‌های 'w:xz'، 'x:xz' و 'w|xz'، تابع tarfile.open() آرگومان کلیدواژه‌ای preset را برای مشخص کردن سطح فشرده‌سازی پرونده می‌پذیرد.

برای حالت‌های 'w:zst'، 'x:zst' و 'w|zst'، tarfile.open() آرگومان کلیدواژه‌ای level را برای تعیین سطح فشرده‌سازی پرونده می‌پذیرد. آرگومان کلیدواژه‌ای options نیز می‌تواند ارسال شود تا پارامترهای پیشرفته فشرده‌سازی Zstandard را که در CompressionParameter توصیف شده‌اند، فراهم کند. آرگومان کلیدواژه‌ای zstd_dict می‌تواند ارسال شود تا یک ZstdDict، یک دیکشنری Zstandard که برای بهبود فشرده‌سازی مقادیر کمتری از داده استفاده می‌شود، فراهم کند.

برای اهداف خاص، قالب دومی برای mode وجود دارد: 'filemode|[compression]'. tarfile.open() یک شیء TarFile برمی‌گرداند که داده‌های خود را به‌صورت جریانی از بلوک‌ها پردازش می‌کند. هیچ مکان‌یابی تصادفی‌ای روی پرونده انجام نخواهد شد. در صورت ارائه، fileobj می‌تواند هر شیءای باشد که یک متد read() یا write() (بسته به mode) داشته باشد که با بایت‌ها کار می‌کند. bufsize اندازه‌ی بلوک را مشخص می‌کند و مقدار پیش‌فرض آن 20 * 512 بایت است. از این حالت در ترکیب با مواردی مانند sys.stdin.buffer، یک file object برای سوکت یا یک دستگاه نوار استفاده کنید. با این حال، چنین شیء TarFile محدود است، زیرا دسترسی تصادفی را اجازه نمی‌دهد؛ مثال‌ها را ببینید. حالت‌های ممکن کنونی:

حالت

اکشن

'r|*'

باز کردن یک جریان از بلوک‌های tar برای خواندن با فشرده‌سازی شفاف.

'r|'

باز کردن یک جریان از بلوک‌های tar فشرده‌نشده برای خواندن.

'r|gz'

باز کردن یک جریان فشرده‌شده با gzip برای خواندن.

'r|bz2'

یک جریان فشرده‌شده با bzip2 را برای خواندن باز کنید.

'r|xz'

باز کردن یک جریان فشرده‌شده با lzma برای خواندن.

'r|zst'

یک جریان فشرده‌شده با Zstandard را برای خواندن باز کنید.

'w|'

باز کردن یک جریان فشرده‌نشده برای نوشتن.

'w|gz'

باز کردن یک جریان فشرده‌شده با gzip برای نوشتن.

'w|bz2'

یک جریان فشرده‌شده با bzip2 را برای نوشتن باز کنید.

'w|xz'

یک جریان فشرده‌شده با lzma را برای نوشتن باز کنید.

'w|zst'

یک جریان فشرده با Zstandard را برای نوشتن باز کنید.

تغییر یافته در نسخه‌ی 3.5: حالت 'x' (ایجاد انحصاری) افزوده شد.

تغییر یافته در نسخه‌ی 3.6: پارامتر name یک path-like object را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.12: آرگومان کلیدواژه‌ای compresslevel برای جریان‌ها نیز کار می‌کند.

تغییر یافته در نسخه‌ی 3.14: آرگومان کلیدواژه‌ای preset برای جریان‌ها نیز کار می‌کند.

class tarfile.TarFile

کلاسی برای خواندن و نوشتن بایگانی‌های tar. از این کلاس به‌طور مستقیم استفاده نکنید: در عوض از tarfile.open() استفاده کنید. اشیای TarFile را ببینید.

tarfile.is_tarfile(name)

اگر name یک پرونده آرشیو tar باشد که ماژول tarfile بتواند آن را بخواند، True را برمی‌گرداند. name می‌تواند یک str، پرونده یا شیء شبه‌پرونده باشد.

تغییر یافته در نسخه‌ی 3.9: پشتیبانی از پرونده‌ها و اشیاء شبه‌پرونده.

ماژول tarfile استثناهای زیر را تعریف می‌کند:

exception tarfile.TarError

کلاس پایه برای همه‌ی استثناهای tarfile.

exception tarfile.ReadError

هنگام باز شدن یک بایگانی tar که یا توسط ماژول tarfile قابل مدیریت نیست یا به‌نحوی نامعتبر است، پرتاب می‌شود.

exception tarfile.CompressionError

هنگامی پرتاب می‌شود که از یک روش فشرده‌سازی پشتیبانی نشود یا نتوان داده‌ها را به‌درستی کدگشایی کرد.

exception tarfile.StreamError

برای محدودیت‌های رایج در اشیاء TarFile شبیه به جریان، پرتاب می‌شود.

exception tarfile.ExtractError

برای خطاهای غیرمرگبار هنگام استفاده از TarFile.extract() پرتاب می‌شود، اما تنها در صورتی که TarFile.errorlevel== 2 باشد.

exception tarfile.HeaderError

توسط TarInfo.frombuf() در صورتی پرتاب می‌شود که بافر دریافتی آن نامعتبر باشد.

exception tarfile.FilterError

کلاس پایه برای اعضای ردشده توسط فیلترها.

tarinfo

اطلاعات مربوط به عضوی که فیلتر از استخراج آن خودداری کرد، به‌صورت TarInfo.

exception tarfile.AbsolutePathError

برای امتناع از استخراج یک عضو با مسیر مطلق پرتاب می‌شود.

exception tarfile.OutsideDestinationError

برای امتناع از استخراج یک عضو خارج از پوشه مقصد پرتاب می‌شود.

exception tarfile.SpecialFileError

برای خودداری از استخراج یک پرونده خاص (مثلاً یک دستگاه یا پایپ ) پرتاب می‌شود.

exception tarfile.AbsoluteLinkError

برای امتناع از استخراج یک پیوند نمادین با مسیر مطلق، پرتاب می‌شود.

exception tarfile.LinkOutsideDestinationError

پرتاب می‌شود تا از استخراج یک پیوند نمادین که به خارج از پوشه‌ی مقصد اشاره دارد، خودداری شود.

exception tarfile.LinkFallbackError

پرتاب می‌شود تا شبیه‌سازی یک پیوند (سخت یا نمادین) از طریق استخراج عضوی دیگر از بایگانی را رد کند، در صورتی که آن عضو توسط موقعیت فیلتر رد شود. استثنایی که برای رد عضو جایگزین پرتاب شده است، به‌صورت BaseException.__context__ در دسترس است.

اضافه شده در نسخه‌ی 3.14.

ثابت‌های زیر در سطح ماژول در دسترس هستند:

tarfile.ENCODING

کدگذاری پیش‌فرض نویسه‌ها: در ویندوز 'utf-8' و در غیر این صورت، مقداری که sys.getfilesystemencoding() برمی‌گرداند.

tarfile.REGTYPE
tarfile.AREGTYPE

یک پرونده معمولی type.

tarfile.LNKTYPE

یک پیوند (داخل tarfile) type.

tarfile.SYMTYPE

یک پیوند نمادین type.

tarfile.CHRTYPE

یک دستگاه خاص نویسه‌ای type.

tarfile.BLKTYPE

یک دستگاه ویژه‌ی بلوکی (block special device) type.

tarfile.DIRTYPE

یک type پوشه.

tarfile.FIFOTYPE

یک دستگاه خاص FIFO type.

tarfile.CONTTYPE

یک پرونده پیوسته type.

tarfile.GNUTYPE_LONGNAME

یک type برای نام بلند GNU tar.

یک type برای پیوند بلند (longlink) در GNU tar.

tarfile.GNUTYPE_SPARSE

یک پرونده پراکنده (sparse file) در GNU tar type.

هر یک از ثابت‌های زیر، یک قالب آرشیو tar را تعریف می‌کند که ماژول tarfile می‌تواند آن را ایجاد کند. برای جزئیات، بخش قالب‌های tar پشتیبانی‌شده را ببینید.

tarfile.USTAR_FORMAT

قالب POSIX.1-1988 (ustar).

tarfile.GNU_FORMAT

قالب GNU tar.

tarfile.PAX_FORMAT

قالب POSIX.1-2001 (pax).

tarfile.DEFAULT_FORMAT

قالب پیش‌فرض برای ایجاد بایگانی‌ها. این در حال حاضر PAX_FORMAT است.

تغییر یافته در نسخه‌ی 3.8: قالب پیش‌فرض برای بایگانی‌های جدید از GNU_FORMAT به PAX_FORMAT تغییر کرد.

همچنین ملاحظه نمائید

ماژول zipfile

مستندات ماژول استاندارد zipfile.

عملیات بایگانی

مستندات امکانات بایگانی سطح بالاتر ارائه‌شده توسط ماژول استاندارد shutil.

راهنمای GNU tar، قالب پایه Tar

مستندات پرونده‌های آرشیوی tar، شامل افزونه‌های GNU tar.

اشیای TarFile

شیء TarFile رابطی به یک بایگانی tar فراهم می‌کند. یک بایگانی tar دنباله‌ای از بلوک‌ها است. یک عضو بایگانی (یک پرونده ذخیره‌شده) از یک بلوک سرآیند و به‌دنبال آن بلوک‌های داده تشکیل شده است. می‌توان یک پرونده را چندین بار در یک بایگانی tar ذخیره کرد. هر عضو بایگانی توسط یک شیء TarInfo نمایش داده می‌شود، برای جزئیات اشیاء TarInfo را ببینید.

می‌توان از یک شیء TarFile به‌عنوان مدیر زمینه در یک دستور with استفاده کرد. این شیء هنگامی که بلوک کامل شود به‌طور خودکار بسته می‌شود. لطفاً توجه داشته باشید که در صورت بروز استثنا، بایگانی بازشده برای نوشتن نهایی نخواهد شد؛ تنها شیء پرونده‌ای که به‌صورت داخلی استفاده‌شده است بسته خواهد شد. برای دیدن یک نمونه‌ی استفاده، بخش مثال‌ها را ببینید.

اضافه شده در نسخه‌ی 3.2: پشتیبانی از پروتکل مدیریت زمینه اضافه شد.

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=1, stream=False)

تمام آرگومان‌های بعدی اختیاری هستند و می‌توان به‌عنوان ویژگی‌های نمونه نیز به آن‌ها دسترسی داشت.

name نام مسیر بایگانی است. name ممکن است یک path-like object باشد. اگر fileobj داده شود، می‌توان آن را حذف کرد. در این حالت، اگر ویژگی name شیء پرونده وجود داشته باشد، از آن استفاده می‌شود.

mode می‌تواند 'r' برای خواندن از یک بایگانی موجود، 'a' برای افزودن داده‌ها به یک پرونده موجود، 'w' برای ایجاد یک پرونده جدید و بازنویسی پرونده موجود، یا 'x' برای ایجاد یک پرونده جدید فقط در صورتی باشد که از قبل وجود نداشته باشد.

اگر fileobj داده شده باشد، از آن برای خواندن یا نوشتن داده استفاده می‌شود. اگر قابل تعیین باشد، mode با حالت fileobj جایگزین می‌شود. fileobj از موقعیت ۰ مورد استفاده قرار خواهد گرفت.

توجه

هنگامی که TarFile بسته می‌شود، fileobj بسته نمی‌شود.

format قالب بایگانی را برای نوشتن کنترل می‌کند. مقدار آن باید یکی از ثابت‌های USTAR_FORMAT، GNU_FORMAT یا PAX_FORMAT باشد که در سطح ماژول تعریف شده‌اند. هنگام خواندن، قالب به‌طور خودکار شناسایی می‌شود، حتی اگر قالب‌های متفاوتی در یک بایگانی واحد وجود داشته باشند.

می‌توانید از آرگومان tarinfo برای جایگزینی کلاس پیش‌فرض TarInfo با کلاس دیگری استفاده کنید.

اگر dereference برابر False باشد، پیوندهای نمادین و سخت به بایگانی افزوده می‌شوند. اگر این مقدار True باشد، محتوای پرونده‌های هدف به بایگانی افزوده می‌شود. این موضوع در سیستم‌هایی که از پیوندهای نمادین پشتیبانی نمی‌کنند، تأثیری ندارد.

اگر ignore_zeros برابر False باشد، یک بلوک خالی به‌عنوان پایان بایگانی در نظر گرفته می‌شود. اگر این مقدار True باشد، از بلوک‌های خالی (و نامعتبر) چشم‌پوشی می‌شود و تلاش می‌شود تا حد ممکن اعضا دریافت شوند. این فقط برای خواندن بایگانی‌های به‌هم‌پیوسته یا آسیب‌دیده مفید است.

debug می‌تواند از 0 (بدون پیام‌های اشکال‌زدایی) تا 3 (همه پیام‌های اشکال‌زدایی) تنظیم شود. پیام‌ها در sys.stderr نوشته می‌شوند.

errorlevel نحوه‌ی مدیریت خطاهای استخراج را کنترل می‌کند، ویژگی متناظر را ببینید.

آرگومان‌های encoding و errors کدگذاری نویسه‌ای را که برای خواندن یا نوشتن بایگانی استفاده می‌شود و نحوه‌ی مدیریت خطاهای تبدیل را تعریف می‌کنند. تنظیمات پیش‌فرض برای بیشتر کاربران کار خواهد کرد. برای اطلاعات جامع‌تر، بخش مسائل یونیکد را ببینید.

آرگومان pax_headers یک دیکشنری اختیاری از رشته‌ها است که اگر format برابر PAX_FORMAT باشد، به‌عنوان یک سرآیند سراسری pax اضافه خواهد شد.

اگر stream روی True تنظیم شده باشد، آنگاه هنگام خواندن بایگانی، اطلاعات مربوط به پرونده‌های درون بایگانی در نهانگاه ذخیره نمی‌شود و در حافظه صرفه‌جویی می‌شود.

تغییر یافته در نسخه‌ی 3.2: از 'surrogateescape' به‌عنوان مقدار پیش‌فرض آرگومان errors استفاده کنید.

تغییر یافته در نسخه‌ی 3.5: حالت 'x' (ایجاد انحصاری) افزوده شد.

تغییر یافته در نسخه‌ی 3.6: پارامتر name یک path-like object را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.13: پارامتر stream را اضافه کنید.

classmethod TarFile.open(...)

سازنده جایگزین. تابع tarfile.open() در واقع میان‌بری به این classmethod است.

TarFile.getmember(name)

یک شیء TarInfo برای عضو name برمی‌گرداند. اگر name در بایگانی یافت نشود، KeyError پرتاب می‌شود.

توجه

اگر عضوی بیش از یک بار در بایگانی وجود داشته باشد، آخرین مورد آن به‌عنوان به‌روزترین نسخه فرض می‌شود.

TarFile.getmembers()

اعضای آرشیو را به‌عنوان فهرستی از اشیای TarInfo برمی‌گرداند. فهرست همان ترتیب اعضای آرشیو را دارد.

TarFile.getnames()

اعضا را به‌صورت فهرستی از نام‌هایشان برمی‌گرداند. ترتیب این فهرست همان ترتیب فهرست برگردانده‌شده توسط getmembers() است.

TarFile.list(verbose=True, *, members=None)

فهرست محتوا را در sys.stdout چاپ می‌کند. اگر verbose برابر False باشد، تنها نام اعضا چاپ می‌شود. اگر این مقدار True باشد، خروجی مشابه خروجی ls -l تولید می‌شود. اگر members اختیاری داده شود، باید زیرمجموعه‌ای از فهرستی باشد که getmembers() برمی‌گرداند.

تغییر یافته در نسخه‌ی 3.5: پارامتر members افزوده شد.

TarFile.next()

هنگامی که TarFile برای خواندن باز شده باشد، عضو بعدی بایگانی را به‌صورت یک شیء TarInfo برمی‌گرداند. اگر عضو دیگری در دسترس نباشد، None برمی‌گرداند.

TarFile.extractall(path='.', members=None, *, numeric_owner=False, filter=None)

تمام اعضا را از بایگانی به پوشه کاری جاری یا پوشه path استخراج کنید. اگر members اختیاری داده شود، باید زیرمجموعه‌ای از فهرست برگردانده‌شده توسط getmembers() باشد. اطلاعات پوشه مانند مالک، زمان تغییر و مجوزها پس از استخراج همه اعضا تنظیم می‌شوند. این کار برای دور زدن دو مشکل انجام می‌شود: زمان تغییر یک پوشه هر بار که پرونده‌ای در آن ایجاد می‌شود، بازنشانی می‌شود. و اگر مجوزهای یک پوشه اجازه نوشتن ندهند، استخراج پرونده‌ها به آن ناموفق خواهد بود.

اگر numeric_owner برابر True باشد، از شماره‌های uid و gid موجود در tarfile برای تنظیم مالک/گروه پرونده‌های استخراج‌شده استفاده می‌شود. در غیر این صورت، از مقادیر نام‌دار موجود در tarfile استفاده می‌شود.

آرگومان filter مشخص می‌کند که members پیش از استخراج چگونه تغییر داده شوند یا رد شوند. برای جزئیات، فیلترهای استخراج را ببینید. توصیه می‌شود این را فقط در صورت نیاز به ویژگی‌های خاص tar به‌صراحت تنظیم کنید، یا برای پشتیبانی از نسخه‌های پایتون با پیش‌فرض کم‌امنیت‌تر (3.13 و پایین‌تر)، آن را به‌صورت filter='data' تنظیم کنید.

هشدار

هرگز آرشیوها را از منابع نامطمئن بدون بررسی پیشین استخراج نکنید.

از پایتون 3.14، پیش‌فرض (data) از خطرناک‌ترین مسائل امنیتی جلوگیری می‌کند. با این حال، از همه رفتارهای ناخواسته یا ناامن جلوگیری نمی‌کند. برای جزئیات، بخش فیلترهای استخراج را بخوانید.

تغییر یافته در نسخه‌ی 3.5: پارامتر numeric_owner اضافه شد.

تغییر یافته در نسخه‌ی 3.6: پارامتر path یک path-like object را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.12: پارامتر filter اضافه شد.

تغییر یافته در نسخه‌ی 3.14: پارامتر filter اکنون به‌طور پیش‌فرض مقدار 'data' دارد.

TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False, filter=None)

یک عضو را از بایگانی با استفاده از نام کامل آن به پوشه کاری فعلی استخراج کنید. اطلاعات پرونده آن تا حد امکان به‌دقت استخراج می‌شود. member می‌تواند یک نام پرونده یا یک شیء TarInfo باشد. می‌توانید با استفاده از path یک پوشه متفاوت را مشخص کنید. path می‌تواند یک path-like object باشد. ویژگی‌های پرونده (مالک، mtime، حالت) تنظیم می‌شوند، مگر اینکه set_attrs نادرست باشد.

آرگومان‌های numeric_owner و filter همانند آرگومان‌های extractall() هستند.

توجه

متد extract() به چندین مسئله‌ی استخراج رسیدگی نمی‌کند. در بیشتر موارد باید استفاده از متد extractall() را در نظر بگیرید.

هشدار

هرگز بایگانی‌ها را از منابع نامعتبر بدون بازرسی پیشین استخراج نکنید. برای جزئیات، هشدار مربوط به extractall() را ببینید.

تغییر یافته در نسخه‌ی 3.2: پارامتر set_attrs اضافه شد.

تغییر یافته در نسخه‌ی 3.5: پارامتر numeric_owner اضافه شد.

تغییر یافته در نسخه‌ی 3.6: پارامتر path یک path-like object را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.12: پارامتر filter اضافه شد.

TarFile.extractfile(member)

یک عضو را از آرشیو به‌عنوان یک شیء پرونده استخراج می‌کند. member ممکن است یک نام پرونده یا یک شیء TarInfo باشد. اگر member یک پرونده معمولی یا یک پیوند باشد، یک شیء io.BufferedReader بازگردانده می‌شود. برای تمام اعضای موجود دیگر، None بازگردانده می‌شود. اگر member در آرشیو یافت نشود، KeyError پرتاب می‌شود.

تغییر یافته در نسخه‌ی 3.3: یک شیء io.BufferedReader برمی‌گرداند.

تغییر یافته در نسخه‌ی 3.13: شیء برگردانده‌شده‌ی io.BufferedReader دارای ویژگی mode است که همیشه برابر با 'rb' است.

TarFile.errorlevel: int

اگر errorlevel برابر 0 باشد، هنگام استفاده از TarFile.extract() و TarFile.extractall()، خطاها نادیده گرفته می‌شوند. با این حال، هنگامی که debug بزرگ‌تر از ۰ باشد، آن‌ها به‌صورت پیام‌های خطا در خروجی اشکال‌زدایی ظاهر می‌شوند. اگر 1 (پیش‌فرض) باشد، تمام خطاهای مهلک به‌عنوان استثناهای OSError یا FilterError پرتاب می‌شوند. اگر 2 باشد، تمام خطاهای غیرمهلک نیز به‌عنوان استثناهای TarError پرتاب می‌شوند.

برخی استثناها، مثلاً آن‌هایی که به‌دلیل نوع اشتباه آرگومان‌ها یا خرابی داده ایجاد می‌شوند، همیشه پرتاب می‌شوند.

فیلترهای استخراج سفارشی باید برای خطاهای مهلک، FilterError و برای خطاهای غیرمهلک، ExtractError را پرتاب کنند.

توجه داشته باشید که هنگامی که یک استثنا پرتاب می‌شود، ممکن است بایگانی به‌طور ناقص استخراج شود. پاک‌سازی آن بر عهده‌ی کاربر است.

TarFile.extraction_filter

اضافه شده در نسخه‌ی 3.12.

فیلتر استخراج که به‌عنوان پیش‌فرض برای آرگومان filter در extract() و extractall() استفاده می‌شود.

این ویژگی ممکن است None یا یک شیء فراخوانی‌پذیر باشد. نام‌های رشته‌ای برای این ویژگی مجاز نیستند، برخلاف آرگومان filter در extract().

اگر extraction_filter برابر None باشد (حالت پیش‌فرض)، متدهای استخراج به‌طور پیش‌فرض از فیلتر data استفاده خواهند کرد.

این ویژگی را می‌توان روی نمونه‌ها تنظیم کرد یا در زیرکلاس‌ها بازنویسی کرد. همچنین می‌توان آن را روی خود کلاس TarFile تنظیم کرد تا یک پیش‌فرض سراسری تعیین شود، اگرچه، از آنجا که این کار بر تمام استفاده‌ها از tarfile تأثیر می‌گذارد، بهترین روش این است که این کار فقط در برنامه‌های سطح‌بالا یا پیکربندی سایت انجام شود. برای تنظیم یک پیش‌فرض سراسری به این روش، یک تابع فیلتر باید با @staticmethod پوشانده شود تا از تزریق آرگومان self جلوگیری شود.

تغییر یافته در نسخه‌ی 3.14: فیلتر پیش‌فرض روی data تنظیم شده است، که برخی قابلیت‌های خطرناک مانند پیوند به مسیرهای مطلق یا مسیرهای خارج از مقصد را غیرمجاز می‌کند. پیش‌تر، مقدار پیش‌فرض معادل fully_trusted بود.

TarFile.add(name, arcname=None, recursive=True, *, filter=None)

پرونده name را به بایگانی اضافه کنید. name می‌تواند هر نوع پرونده‌ای (پوشه، fifo، پیوند نمادین و غیره) باشد. در صورت ارائه، arcname یک نام جایگزین برای پرونده در بایگانی مشخص می‌کند. به‌طور پیش‌فرض، پوشه‌ها به‌صورت بازگشتی اضافه می‌شوند. می‌توانید با تنظیم recursive به False از این کار جلوگیری کنید. پیمایش بازگشتی ورودی‌ها را به ترتیب مرتب‌شده اضافه می‌کند. اگر filter ارائه شود، باید تابعی باشد که یک آرگومان شیء TarInfo می‌گیرد و شیء TarInfo تغییرکرده را برمی‌گرداند. اگر در عوض None برگرداند، شیء TarInfo از بایگانی حذف خواهد شد. برای یک مثال، مثال‌ها را ببینید.

تغییر یافته در نسخه‌ی 3.2: پارامتر filter اضافه شد.

تغییر یافته در نسخه‌ی 3.7: بازگشت، ورودی‌ها را به ترتیب مرتب‌شده اضافه می‌کند.

TarFile.addfile(tarinfo, fileobj=None)

شیء TarInfo با نام tarinfo را به بایگانی اضافه کنید. اگر tarinfo نشان‌دهنده یک پرونده معمولی با اندازه غیرصفر باشد، آرگومان fileobj باید یک binary file باشد و tarinfo.size بایت از آن خوانده می‌شود و به بایگانی افزوده می‌شود. می‌توانید اشیای TarInfo را مستقیماً یا با استفاده از gettarinfo() ایجاد کنید.

تغییر یافته در نسخه‌ی 3.13: برای پرونده‌های عادی با اندازه غیرصفر، باید fileobj داده شود.

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

یک شیء TarInfo از نتیجه‌ی os.stat() یا معادل آن روی یک پرونده موجود ایجاد کنید. پرونده یا با name نام‌گذاری می‌شود، یا به‌عنوان یک file object یعنی fileobj با توصیف‌گر پرونده مشخص می‌شود. name ممکن است یک path-like object باشد. در صورت ارائه، arcname نامی جایگزین برای پرونده در بایگانی را مشخص می‌کند؛ در غیر این صورت، نام از ویژگی name متعلق به fileobj یا از آرگومان name گرفته می‌شود. نام باید یک رشته متنی باشد.

می‌توانید برخی از ویژگی‌های TarInfo را پیش از افزودن آن با استفاده از addfile() تغییر دهید. اگر شیء پرونده، یک شیء پرونده معمولی نباشد که در ابتدای پرونده قرار گرفته باشد، ممکن است ویژگی‌هایی مانند size نیاز به تغییر داشته باشند. این حالت برای اشیایی مانند GzipFile صدق می‌کند. همچنین ممکن است name تغییر کند، که در این صورت arcname می‌تواند یک رشته‌ی ساختگی باشد.

تغییر یافته در نسخه‌ی 3.6: پارامتر name یک path-like object را می‌پذیرد.

TarFile.close()

TarFile را ببندید. در حالت نوشتن، دو بلوک صفر پایانی به بایگانی افزوده می‌شوند.

TarFile.pax_headers: dict

یک دیکشنری حاوی جفت‌های کلید-مقدار از سرآیندهای سراسری pax.

اشیاء TarInfo

یک شیء TarInfo نمایانگر یک عضو در TarFile است. جدای از ذخیره کردن همه‌ی ویژگی‌های مورد نیاز یک پرونده (مانند نوع پرونده، اندازه، زمان، دسترسی‌ها، مالک و غیره)، این شیء چند متد مفید برای تعیین نوع آن ارائه می‌دهد. این شیء داده‌های خود پرونده را در بر نمی‌گیرد.

اشیای TarInfo توسط متدهای getmember()، getmembers() و gettarinfo() از کلاس TarFile برگردانده می‌شوند.

تغییر اشیای برگردانده‌شده توسط getmember() یا getmembers() بر تمام عملیات‌های بعدی روی بایگانی تأثیر خواهد گذاشت. در مواردی که این رفتار نامطلوب است، می‌توانید از copy.copy() استفاده کنید یا متد replace() را فراخوانی کنید تا یک رونوشت تغییریافته را در یک مرحله ایجاد کنید.

چندین ویژگی را می‌توان روی None تنظیم کرد تا نشان داده شود که یک مورد فراداده استفاده‌نشده یا ناشناخته است. متدهای مختلف TarInfo با None به‌صورت متفاوتی برخورد می‌کنند:

  • متدهای extract() یا extractall() فراداده‌ی مربوطه را نادیده می‌گیرند و آن را روی یک مقدار پیش‌فرض تنظیم‌شده باقی می‌گذارند.

  • addfile() شکست خواهد خورد.

  • list() یک رشته‌ی جای‌نگهدار را چاپ خواهد کرد.

class tarfile.TarInfo(name='')

یک شیء TarInfo ایجاد کنید.

classmethod TarInfo.frombuf(buf, encoding, errors)

یک شیء TarInfo را از بافر رشته‌ای buf ایجاد می‌کند و برمی‌گرداند.

اگر بافر نامعتبر باشد، HeaderError پرتاب می‌شود.

classmethod TarInfo.fromtarfile(tarfile)

عضو بعدی را از شیء TarFile به نام tarfile می‌خواند و آن را به‌عنوان یک شیء TarInfo برمی‌گرداند.

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')

یک بافر رشته‌ای از یک شیء TarInfo ایجاد کنید. برای اطلاعات درباره آرگومان‌ها، سازنده کلاس TarFile را ببینید.

تغییر یافته در نسخه‌ی 3.2: از 'surrogateescape' به‌عنوان مقدار پیش‌فرض آرگومان errors استفاده کنید.

یک شیء TarInfo دارای ویژگی‌های داده‌ای عمومی زیر است:

TarInfo.name: str

نام عضو آرشیو.

TarInfo.size: int

اندازه بر حسب بایت.

TarInfo.mtime: int | float

زمان آخرین تغییر بر حسب ثانیه از epoch، همان‌طور که در os.stat_result.st_mtime آمده است.

تغییر یافته در نسخه‌ی 3.12: می‌توان آن را برای extract() و extractall() روی None تنظیم کرد، که باعث می‌شود استخراج از اعمال این ویژگی صرف‌نظر کند.

TarInfo.mode: int

بیت‌های دسترسی، مانند os.chmod().

تغییر یافته در نسخه‌ی 3.12: می‌توان آن را برای extract() و extractall() روی None تنظیم کرد، که باعث می‌شود استخراج از اعمال این ویژگی صرف‌نظر کند.

TarInfo.type

نوع پرونده. type معمولاً یکی از این ثابت‌ها است: REGTYPE، AREGTYPE، LNKTYPE، SYMTYPE، DIRTYPE، FIFOTYPE، CONTTYPE، CHRTYPE، BLKTYPE، GNUTYPE_SPARSE. برای تعیین راحت‌تر نوع یک شیء TarInfo، از متدهای is*() زیر استفاده کنید.

TarInfo.linkname: str

نام پرونده هدف، که فقط در اشیای TarInfo از نوع LNKTYPE و SYMTYPE موجود است.

برای پیوندهای نمادین (SYMTYPElinkname نسبت به پوشه‌ی حاوی پیوند است. برای پیوندهای سخت (LNKTYPElinkname نسبت به ریشه‌ی بایگانی است.

TarInfo.uid: int

شناسه‌ی کاربری که در ابتدا این عضو را ذخیره کرده است.

تغییر یافته در نسخه‌ی 3.12: می‌توان آن را برای extract() و extractall() روی None تنظیم کرد، که باعث می‌شود استخراج از اعمال این ویژگی صرف‌نظر کند.

TarInfo.gid: int

شناسه‌ی گروه کاربری که این عضو را در ابتدا ذخیره کرده است.

تغییر یافته در نسخه‌ی 3.12: می‌توان آن را برای extract() و extractall() روی None تنظیم کرد، که باعث می‌شود استخراج از اعمال این ویژگی صرف‌نظر کند.

TarInfo.uname: str

نام کاربری.

تغییر یافته در نسخه‌ی 3.12: می‌توان آن را برای extract() و extractall() روی None تنظیم کرد، که باعث می‌شود استخراج از اعمال این ویژگی صرف‌نظر کند.

TarInfo.gname: str

نام گروه.

تغییر یافته در نسخه‌ی 3.12: می‌توان آن را برای extract() و extractall() روی None تنظیم کرد، که باعث می‌شود استخراج از اعمال این ویژگی صرف‌نظر کند.

TarInfo.chksum: int

جمع‌آزما سرآیند.

TarInfo.devmajor: int

شماره اصلی دستگاه.

TarInfo.devminor: int

شماره فرعی دستگاه.

TarInfo.offset: int

سرآیند tar از اینجا شروع می‌شود.

TarInfo.offset_data: int

داده‌ی پرونده از اینجا شروع می‌شود.

TarInfo.sparse

اطلاعات عضو تنک.

TarInfo.pax_headers: dict

یک دیکشنری حاوی جفت‌های کلید-مقدار از یک سرآیند توسعه‌یافته‌ی pax مرتبط.

TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., uid=..., gid=..., uname=..., gname=..., deep=True)

اضافه شده در نسخه‌ی 3.12.

یک نسخه‌ی جدید از شیء TarInfo را با تغییر ویژگی‌های داده‌شده برمی‌گرداند. برای مثال، برای برگرداندن یک TarInfo با نام گروه تنظیم‌شده روی 'staff'، به‌صورت زیر عمل کنید:

new_tarinfo = old_tarinfo.replace(gname='staff')

به‌طور پیش‌فرض، یک کپی عمیق ایجاد می‌شود. اگر deep نادرست باشد، کپی کم‌عمق است، یعنی pax_headers و هرگونه ویژگی سفارشی با شیء اصلی TarInfo به اشتراک گذاشته می‌شوند.

یک شیء TarInfo همچنین چند متد پرس‌وجوی مفید ارائه می‌دهد:

TarInfo.isfile()

اگر شیء TarInfo یک پرونده معمولی باشد، True را برمی‌گرداند.

TarInfo.isreg()

مشابه isfile().

TarInfo.isdir()

اگر پوشه باشد، True را برمی‌گرداند.

TarInfo.issym()

اگر پیوند نمادین باشد، True را برمی‌گرداند.

TarInfo.islnk()

اگر پیوند سخت باشد، True را برمی‌گرداند.

TarInfo.ischr()

اگر یک دستگاه نویسه‌ای باشد، True را برمی‌گرداند.

TarInfo.isblk()

اگر یک دستگاه بلوکی (block device) باشد، True را برمی‌گرداند.

TarInfo.isfifo()

اگر یک FIFO باشد، True را برمی‌گرداند.

TarInfo.isdev()

اگر یک دستگاه نویسه‌ای، دستگاه بلوکی یا FIFO باشد، True را برمی‌گرداند.

فیلترهای استخراج

اضافه شده در نسخه‌ی 3.12.

قالب tar برای ثبت تمام جزئیات یک سامانه فایل‌بندی شبه‌یونیکس طراحی شده است، که آن را بسیار قدرتمند می‌سازد. متأسفانه، این ویژگی‌ها ایجاد پرونده‌های tar با اثراتی ناخواسته — و احتمالاً مخرب — هنگام استخراج را آسان می‌کنند. برای مثال، استخراج یک پرونده tar می‌تواند پرونده‌های دلخواه را به روش‌های گوناگونی بازنویسی کند (مثلاً با استفاده از مسیرهای مطلق، اجزای مسیر ..، یا پیوندهای نمادینی که بر اعضای بعدی اثر می‌گذارند).

در بیشتر موارد، به تمام قابلیت‌ها نیازی نیست. بنابراین، tarfile از فیلترهای استخراج پشتیبانی می‌کند: سازوکاری برای محدود کردن قابلیت‌ها، و در نتیجه کاهش برخی از مشکلات امنیتی.

هشدار

هیچ‌یک از فیلترهای موجود، همه‌ی قابلیت‌های خطرناک آرشیو را مسدود نمی‌کند. هرگز آرشیوها را از منابع نامطمئن بدون بازرسی پیشین استخراج نکنید. همچنین نکاتی برای تأیید بیشتر را ببینید.

همچنین ملاحظه نمائید

PEP 706

شامل انگیزه و دلایل بیشتر پشت طراحی است.

آرگومان filter برای TarFile.extract() یا extractall() می‌تواند یکی از موارد زیر باشد:

  • رشته‌ی 'fully_trusted': تمام فراداده‌ها را همان‌گونه که در بایگانی مشخص شده است، رعایت کنید. باید زمانی استفاده شود که کاربر به‌طور کامل به بایگانی اعتماد داشته باشد، یا راستی‌آزمایی پیچیده‌ی خودش را پیاده‌سازی کند.

  • رشته‌ی 'tar': بیشتر ویژگی‌های مخصوص tar (یعنی ویژگی‌های سامانه فایل‌بندی‌های شبه‌یونیکس) را رعایت می‌کند، اما ویژگی‌هایی را که به احتمال زیاد غافلگیرکننده یا مخرب هستند مسدود می‌کند. برای جزئیات، tar_filter() را ببینید.

  • رشته‌ی 'data': بیشتر ویژگی‌های خاص سامانه فایل‌بندی‌های شبه‌یونیکس را نادیده می‌گیرد یا مسدود می‌کند. برای استخراج بایگانی‌های داده‌ی چندسکویی در نظر گرفته شده است. برای جزئیات، data_filter() را ببینید.

  • None (پیش‌فرض): از TarFile.extraction_filter استفاده می‌شود.

    اگر آن نیز None (پیش‌فرض) باشد، از فیلتر 'data' استفاده خواهد شد.

    تغییر یافته در نسخه‌ی 3.14: فیلتر پیش‌فرض روی data تنظیم شده است. پیش از این، فیلتر پیش‌فرض معادل fully_trusted بود.

  • یک شیء فراخوانی‌پذیر که برای هر عضو استخراج‌شده فراخوانی خواهد شد، همراه با یک TarInfo که آن عضو را توصیف می‌کند و مسیر مقصدی که بایگانی در آن استخراج می‌شود (یعنی برای همه اعضا از یک مسیر یکسان استفاده می‌شود):

    filter(member: TarInfo, path: str, /) -> TarInfo | None
    

    فراخوانی‌پذیر درست پیش از استخراج هر عضو فراخوانی می‌شود، بنابراین می‌تواند وضعیت فعلی دیسک را در نظر بگیرد. این فراخوانی‌پذیر می‌تواند:

    • یک شیء TarInfo برگرداند که به‌جای فراداده‌ی موجود در بایگانی استفاده خواهد شد، یا

    • None را برگرداند، که در این صورت عضو نادیده گرفته می‌شود، یا

    • پرتاب استثنا برای لغو عملیات یا رد کردن عضو، بسته به errorlevel. توجه داشته باشید که هنگامی که استخراج لغو شود، extractall() ممکن است بایگانی را به‌صورت نیمه‌استخراج‌شده باقی بگذارد. تلاشی برای پاک‌سازی نمی‌کند.

فیلترهای نام‌دار پیش‌فرض

فیلترهای نام‌دار و از پیش تعریف‌شده به‌صورت توابع در دسترس هستند، بنابراین می‌توان از آن‌ها در فیلترهای سفارشی دوباره استفاده کرد:

tarfile.fully_trusted_filter(member, path)

member را بدون تغییر بازگردانید.

این فیلتر 'fully_trusted' را پیاده‌سازی می‌کند.

tarfile.tar_filter(member, path)

فیلتر 'tar' را پیاده‌سازی می‌کند.

  • اسلش‌های ابتدایی (/ و os.sep) را از نام پرونده‌ها حذف کنید.

  • امتناع از استخراج پرونده‌هایی با مسیرهای مطلق (در صورتی که نام حتی پس از حذف اسلش‌ها مطلق باشد، مثلاً C:/foo در ویندوز). این کار باعث پرتاب AbsolutePathError می‌شود.

  • Normalize filenames (TarInfo.name) that contain .. components using os.path.normpath(). Note that this removes internal .. components, which may change the meaning of the name if it traverses symbolic links.

  • امتناع از استخراج پرونده‌هایی که مسیر مطلق آن‌ها (پس از دنبال کردن پیوندهای نمادین) در نهایت خارج از مقصد قرار بگیرد. این باعث پرتاب OutsideDestinationError می‌شود.

  • بیت‌های بالای حالت (setuid، setgid، sticky) و بیت‌های نوشتن گروه/دیگران (S_IWGRP | S_IWOTH) را پاک کنید.

عضو TarInfo تغییریافته را برمی‌گرداند.

تغییر یافته در نسخه‌ی 3.14.7 (unreleased): Filenames containing .. components are now normalized.

tarfile.data_filter(member, path)

فیلتر 'data' را پیاده‌سازی می‌کند. علاوه بر آنچه tar_filter انجام می‌دهد:

  • اهداف پیوند (TarInfo.linkname) را با استفاده از os.path.normpath() عادی‌سازی کنید. توجه داشته باشید که این کار کامپوننت‌های .. داخلی را حذف می‌کند، که ممکن است در صورتی معنای پیوند را تغییر دهد که مسیر موجود در TarInfo.linkname از پیوندهای نمادین عبور کند.

  • امتناع از استخراج پیوندهایی (سخت یا نرم) که به مسیرهای مطلق اشاره می‌کنند، یا پیوندهایی که به خارج از مقصد اشاره می‌کنند.

    این AbsoluteLinkError یا LinkOutsideDestinationError را پرتاب می‌کند.

    توجه داشته باشید که چنین پرونده‌هایی حتی در سکوهایی که از پیوندهای نمادین پشتیبانی نمی‌کنند نیز رد می‌شوند.

  • خودداری از استخراج پرونده‌های دستگاهی (از جمله پایپ‌ها). این کار SpecialFileError را پرتاب می‌کند.

  • برای پرونده‌های معمولی، از جمله پیوندهای سخت:

    • دسترسی‌های خواندن و نوشتن مالک را تنظیم کنید (S_IRUSR | S_IWUSR).

    • اگر مالک اجازه‌ی اجرا را نداشته باشد (S_IXUSR)، اجازه‌ی اجرای گروه و دیگران (S_IXGRP | S_IXOTH) را حذف کنید.

  • برای سایر پرونده‌ها (پوشه‌ها)، mode را روی None تنظیم کنید، تا متدهای استخراج از اعمال بیت‌های دسترسی صرف‌نظر کنند.

  • اطلاعات کاربر و گروه (uid، gid، uname، gname) را روی None تنظیم کنید، تا متدهای استخراج از تنظیم آن صرف‌نظر کنند.

عضو TarInfo تغییریافته را برمی‌گرداند.

توجه داشته باشید که این فیلتر همه قابلیت‌های خطرناک بایگانی را مسدود نمی‌کند. برای جزئیات نکاتی برای تأیید بیشتر را ببینید.

تغییر یافته در نسخه‌ی 3.14: مقاصد پیوند اکنون نرمال‌سازی شده‌اند.

خطاهای فیلتر

هنگامی که یک فیلتر از استخراج یک پرونده خودداری می‌کند، یک استثنای مناسب پرتاب می‌کند که زیرکلاسی از FilterError است. اگر TarFile.errorlevel برابر ۱ یا بیشتر باشد، استخراج متوقف می‌شود. با errorlevel=0، خطا ثبت می‌شود و عضو نادیده گرفته می‌شود، اما استخراج ادامه می‌یابد.

نکاتی برای تأیید بیشتر

حتی با filter='data'، tarfile برای استخراج پرونده‌های غیرقابل‌اعتماد بدون بازرسی قبلی مناسب نیست. از جمله مشکلات دیگر، فیلترهای از پیش تعریف‌شده از حملات منع سرویس جلوگیری نمی‌کنند. کاربران باید بررسی‌های بیشتری انجام دهند.

در اینجا فهرستی ناقص از مواردی که باید در نظر بگیرید آمده است:

  • در یک پوشه موقت جدید استخراج کنید تا برای مثال از سوءاستفاده از پیوندهای از پیش موجود جلوگیری شود و پاک‌سازی پس از یک استخراج شکست‌خورده آسان‌تر شود.

  • اگر به این قابلیت نیاز ندارید، پیوندهای نمادین را غیرمجاز کنید.

  • هنگام کار با داده‌های غیرقابل‌اعتماد، از محدودیت‌های خارجی (مثلاً در سطح سیستم‌عامل) بر مصرف دیسک، حافظه و CPU استفاده کنید.

  • نام‌های پرونده را با یک فهرست مجاز (allow-list) از نویسه‌ها بررسی کنید (تا نویسه‌های کنترلی، نویسه‌های مشابه (confusables)، جداکننده‌های مسیر بیگانه و غیره را حذف کنید).

  • بررسی کنید که نام‌پرونده‌ها دارای پسوندهای موردانتظار باشند (برای جلوگیری از پرونده‌هایی که هنگام «کلیک روی آن‌ها» اجرا می‌شوند، یا پرونده‌های بدون پسوند مانند نام‌های ویژه دستگاه در ویندوز).

  • تعداد پرونده‌های استخراج‌شده، اندازه کل داده‌های استخراج‌شده، طول نام پرونده (شامل طول پیوند نمادین) و اندازه هر پرونده را محدود کنید.

  • پرونده‌هایی را که در سامانه فایل‌بندی‌های غیرحساس به بزرگی و کوچکی حروف پوشانده می‌شوند، بررسی کنید.

همچنین توجه داشته باشید که:

  • پرونده‌های Tar ممکن است شامل چندین نسخه از یک پرونده یکسان باشند. انتظار می‌رود نسخه‌های بعدی هر یک از نسخه‌های قبلی را بازنویسی کنند. این قابلیت برای امکان‌پذیر کردن به‌روزرسانی بایگانی‌های نواری حیاتی است، اما می‌تواند به‌صورت مخربانه مورد سوءاستفاده قرار گیرد.

  • tarfile در برابر مشکلات مربوط به داده‌های «زنده» محافظت نمی‌کند، برای مثال زمانی که مهاجمی پوشه‌ی مقصد (یا مبدأ) را در حالی که استخراج (یا بایگانی) در حال انجام است دستکاری می‌کند.

پشتیبانی از نسخه‌های قدیمی‌تر پایتون

فیلترهای استخراج به پایتون 3.12 اضافه شدند، اما ممکن است به‌عنوان به‌روزرسانی‌های امنیتی به نسخه‌های قدیمی‌تر نیز بک‌پورت شوند. برای بررسی در دسترس بودن این قابلیت، برای مثال به‌جای بررسی نسخه پایتون، از hasattr(tarfile, 'data_filter') استفاده کنید.

مثال‌های زیر نشان می‌دهند که چگونه از نسخه‌های پایتون با و بدون این قابلیت پشتیبانی کنید. توجه داشته باشید که تنظیم extraction_filter بر هر عملیات بعدی تأثیر خواهد گذاشت.

  • بایگانی کاملاً مورد اعتماد:

    my_tarfile.extraction_filter = (lambda member, path: member)
    my_tarfile.extractall()
    
  • در صورت موجود بودن، از فیلتر 'data' استفاده کنید، اما اگر این قابلیت در دسترس نبود، به رفتار Python 3.11 ('fully_trusted') بازگردید:

    my_tarfile.extraction_filter = getattr(tarfile, 'data_filter',
                                           (lambda member, path: member))
    my_tarfile.extractall()
    
  • از فیلتر 'data' استفاده کنید؛ اگر در دسترس نباشد، شکست بخورد:

    my_tarfile.extractall(filter=tarfile.data_filter)
    

    یا:

    my_tarfile.extraction_filter = tarfile.data_filter
    my_tarfile.extractall()
    
  • از فیلتر 'data' استفاده کنید؛ در صورت در دسترس نبودن، هشدار دهید:

    if hasattr(tarfile, 'data_filter'):
        my_tarfile.extractall(filter='data')
    else:
        # remove this when no longer needed
        warn_the_user('Extracting may be unsafe; consider updating Python')
        my_tarfile.extractall()
    

مثال فیلتر استخراج حالت‌دار

در حالی که متدهای استخراج tarfile یک filter فراخوانی‌پذیر ساده می‌پذیرند، فیلترهای سفارشی ممکن است اشیاء پیچیده‌تری با وضعیت داخلی باشند. نوشتن این‌ها به‌صورت مدیران زمینه ممکن است مفید باشد، تا به این شکل استفاده شوند:

with StatefulFilter() as filter_func:
    tar.extractall(path, filter=filter_func)

برای مثال، می‌توان چنین فیلتری را به این صورت نوشت:

class StatefulFilter:
    def __init__(self):
        self.file_count = 0

    def __enter__(self):
        return self

    def __call__(self, member, path):
        self.file_count += 1
        return member

    def __exit__(self, *exc_info):
        print(f'{self.file_count} files extracted')

رابط خط فرمان

اضافه شده در نسخه‌ی 3.4.

ماژول tarfile یک رابط خط فرمان ساده برای تعامل با بایگانی‌های tar فراهم می‌کند.

اگر می‌خواهید یک بایگانی tar جدید ایجاد کنید، نام آن را پس از گزینه‌ی -c مشخص کنید و سپس نام پرونده(ها) را که باید گنجانده شوند فهرست کنید:

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

ارسال یک پوشه نیز قابل قبول است:

$ python -m tarfile -c monty.tar life-of-brian_1979/

اگر می‌خواهید یک آرشیو tar را در پوشه جاری استخراج کنید، از گزینه‌ی -e استفاده کنید:

$ python -m tarfile -e monty.tar

همچنین می‌توانید با ارسال نام پوشه، یک آرشیو tar را در پوشه‌ای دیگر استخراج کنید:

$ python -m tarfile -e monty.tar  other-dir/

برای فهرست پرونده‌های موجود در یک آرشیو tar، از گزینه -l استفاده کنید:

$ python -m tarfile -l monty.tar

گزینه‌های خط فرمان

-l <tarfile>
--list <tarfile>

فهرست کردن پرونده‌ها در یک پرونده tar.

-c <tarfile> <source1> ... <sourceN>
--create <tarfile> <source1> ... <sourceN>

ایجاد tarfile از پرونده‌های منبع.

-e <tarfile> [<output_dir>]
--extract <tarfile> [<output_dir>]

اگر output_dir مشخص نشده باشد، tarfile را در پوشه‌ی فعلی استخراج می‌کند.

-t <tarfile>
--test <tarfile>

بررسی می‌کند که آیا پرونده tar معتبر است یا خیر.

-v, --verbose

خروجی پرجزئیات.

--filter <filtername>

فیلتر برای --extract را مشخص می‌کند. برای جزئیات، فیلترهای استخراج را ببینید. فقط نام‌های رشته‌ای پذیرفته می‌شوند (یعنی fully_trusted، tar و data).

مثال‌ها

مثال‌های خواندن

چگونگی استخراج کامل یک آرشیو tar در پوشه کاری فعلی:

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall(filter='data')
tar.close()

نحوه استخراج زیرمجموعه‌ای از یک آرشیو tar با TarFile.extractall()، با استفاده از یک تابع تولیدگر به‌جای فهرست:

import os
import tarfile

def py_files(members):
    for tarinfo in members:
        if os.path.splitext(tarinfo.name)[1] == ".py":
            yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

چگونگی خواندن یک آرشیو tar فشرده‌شده با gzip و نمایش برخی اطلاعات اعضا:

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
for tarinfo in tar:
    print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
    if tarinfo.isreg():
        print("a regular file.")
    elif tarinfo.isdir():
        print("a directory.")
    else:
        print("something else.")
tar.close()

مثال‌های نوشتار

چگونگی ایجاد یک آرشیو tar فشرده‌نشده از فهرستی از نام پرونده‌ها:

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

همان مثال با استفاده از دستور with:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

چگونگی ایجاد یک بایگانی و نوشتن آن در stdout با استفاده از sys.stdout.buffer در پارامتر fileobj در TarFile.add():

import sys
import tarfile
with tarfile.open("sample.tar.gz", "w|gz", fileobj=sys.stdout.buffer) as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

چگونگی ایجاد یک بایگانی و بازنشانی اطلاعات کاربر با استفاده از پارامتر filter در TarFile.add():

import tarfile
def reset(tarinfo):
    tarinfo.uid = tarinfo.gid = 0
    tarinfo.uname = tarinfo.gname = "root"
    return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

قالب‌های tar پشتیبانی‌شده

سه قالب tar وجود دارد که می‌توان آن‌ها را با ماژول tarfile ایجاد کرد:

  • قالب ustar در POSIX.1-1988 (USTAR_FORMAT). این قالب از نام پرونده‌هایی با طول حداکثر ۲۵۶ نویسه و نام پیوندهایی تا ۱۰۰ نویسه پشتیبانی می‌کند. حداکثر اندازه پرونده ۸ GiB است. این قالب قدیمی و محدود است، اما به‌طور گسترده پشتیبانی می‌شود.

  • قالب GNU tar (GNU_FORMAT). این قالب از نام‌پرونده‌ها و نام‌پیوندهای طولانی، پرونده‌های بزرگ‌تر از ۸ GiB و پرونده‌های پراکنده پشتیبانی می‌کند. این قالب استاندارد دوفاکتو در سیستم‌های GNU/Linux است. tarfile به‌طور کامل از افزونه‌های GNU tar برای نام‌های طولانی پشتیبانی می‌کند؛ پشتیبانی از پرونده‌های پراکنده فقط‌خواندنی است.

  • قالب pax POSIX.1-2001 (PAX_FORMAT). این قالب انعطاف‌پذیرترین قالب است و عملاً هیچ محدودیتی ندارد. این قالب از نام‌پرونده‌های بلند، نام‌پیوندهای بلند و پرونده‌های بزرگ پشتیبانی می‌کند و مسیرنام‌ها را به‌شکلی قابل‌حمل ذخیره می‌کند. پیاده‌سازی‌های مدرن tar، از جمله GNU tar، bsdtar/libarchive و star، به‌طور کامل از ویژگی‌های گسترش‌یافته‌ی pax پشتیبانی می‌کنند؛ برخی کتابخانه‌های قدیمی یا نگهداری‌نشده ممکن است پشتیبانی نکنند، اما باید با بایگانی‌های pax به‌گونه‌ای رفتار کنند که گویی آن‌ها در قالب ustar با پشتیبانی جهانی قرار دارند. این قالب، قالب پیش‌فرض کنونی برای بایگانی‌های جدید است.

    این قالب، قالب ustar موجود را با سرآیندهای اضافی برای اطلاعاتی که نمی‌توان آن‌ها را به شکل دیگری ذخیره کرد، گسترش می‌دهد. دو گونه از سرآیندهای pax وجود دارد: سرآیندهای توسعه‌یافته فقط بر سرآیند پرونده بعدی تأثیر می‌گذارند؛ سرآیندهای سراسری برای کل بایگانی معتبر هستند و بر تمام پرونده‌های بعدی تأثیر می‌گذارند. تمام داده‌های یک سرآیند pax به دلایل قابلیت حمل، با UTF-8 کدگذاری شده‌اند.

گونه‌های دیگری نیز از قالب tar وجود دارند که می‌توان آن‌ها را خواند، اما نمی‌توان آن‌ها را ایجاد کرد:

  • قالب قدیمی V7. این اولین قالب tar از ویرایش هفتم یونیکس است و فقط پرونده‌های عادی و پوشه‌ها را ذخیره می‌کند. نام‌ها نباید بیش از ۱۰۰ نویسه طول داشته باشند و اطلاعات نام کاربر/گروه وجود ندارد. در برخی از بایگانی‌ها، در صورت وجود فیلدهایی با نویسه‌های غیر ASCII، جمع‌آزماهای سرآیند اشتباه محاسبه‌شده‌اند.

  • قالب توسعه‌یافته‌ی tar در SunOS. این قالب گونه‌ای از قالب pax در POSIX.1-2001 است، اما با آن سازگار نیست.

مسائل یونیکد

قالب tar در ابتدا برای پشتیبان‌گیری روی درایوهای نوار با تمرکز اصلی بر حفظ اطلاعات سامانه فایل‌بندی در نظر گرفته شد. امروزه بایگانی‌های tar معمولاً برای توزیع پرونده و تبادل بایگانی‌ها از طریق شبکه‌ها استفاده می‌شوند. یکی از مشکلات قالب اصلی (که پایه‌ی همه‌ی قالب‌های دیگر است) این است که هیچ مفهومی برای پشتیبانی از کدگذاری‌های مختلف نویسه وجود ندارد. برای مثال، یک بایگانی tar معمولی که روی یک سیستم UTF-8 ایجاد شده است، اگر شامل نویسه‌های غیر ASCII باشد، روی یک سیستم Latin-1 به‌درستی قابل خواندن نیست. فراداده‌ی متنی (مانند نام پرونده‌ها، نام پیوندها، نام‌های کاربر/گروه) آسیب‌دیده به نظر خواهد رسید. متأسفانه، هیچ راهی برای تشخیص خودکار کدگذاری یک بایگانی وجود ندارد. قالب pax برای حل این مشکل طراحی شد. این قالب فراداده‌ی غیر ASCII را با استفاده از کدگذاری نویسه‌ی جهانی UTF-8 ذخیره می‌کند.

جزئیات تبدیل نویسه‌ها در tarfile توسط آرگومان‌های کلیدواژه‌ای encoding و errors کلاس TarFile کنترل می‌شود.

encoding کدگذاری نویسه‌ای مورد استفاده برای فراداده در بایگانی را تعریف می‌کند. مقدار پیش‌فرض، sys.getfilesystemencoding() یا 'ascii' به‌عنوان جایگزین است. بسته به این‌که بایگانی خوانده شود یا نوشته شود، فراداده باید کدگشایی یا کدگذاری شود. اگر encoding به‌درستی تنظیم نشده باشد، این تبدیل ممکن است شکست بخورد.

آرگومان errors تعیین می‌کند که با نویسه‌هایی که قابل تبدیل نیستند چگونه رفتار شود. مقادیر ممکن در بخش هندلرهای خطا فهرست شده‌اند. روش پیش‌فرض 'surrogateescape' است که پایتون از آن برای فراخوانی‌های سامانه فایل‌بندی خود نیز استفاده می‌کند، نام پرونده‌ها، آرگومان‌های خط فرمان و متغیرهای محیطی را ببینید.

برای بایگانی‌های PAX_FORMAT (پیش‌فرض)، معمولاً نیازی به encoding نیست، زیرا تمام فراداده‌ها با استفاده از UTF-8 ذخیره می‌شوند. encoding تنها در موارد نادری استفاده می‌شود که سرآیند‌های pax دودویی کدگشایی می‌شوند یا رشته‌های دارای نویسه‌های جانشین (surrogate) ذخیره می‌شوند.