shutil --- عملیات پرونده سطحبالا¶
کد منبع: Lib/shutil.py
ماژول shutil تعدادی عملیات سطح بالا روی پروندهها و مجموعههایی از پروندهها ارائه میدهد. بهویژه، توابعی فراهم شدهاند که از کپی و حذف پرونده پشتیبانی میکنند. برای عملیات روی پروندههای منفرد، ماژول os را نیز ببینید.
هشدار
حتی توابع سطح بالاتر کپی پرونده (shutil.copy()، shutil.copy2()) نمیتوانند تمام فرادادههای پرونده را کپی کنند.
در پلتفرمهای POSIX، این بدان معناست که مالک و گروه پرونده و همچنین فهرستهای کنترل دسترسی (ACL) از دست میروند. در Mac OS، شاخهی منبع (resource fork) و سایر فرادادهها استفاده نمیشوند. این بدان معناست که منابع از دست خواهند رفت و کدهای نوع پرونده و ایجادکننده صحیح نخواهند بود. در Windows، مالکان پرونده، فهرستهای کنترل دسترسی (ACL) و جریانهای داده جایگزین (alternate data streams) کپی نمیشوند.
عملیات پوشهها و پروندهها¶
- shutil.copyfileobj(fsrc, fdst[, length])¶
محتویات شیء شبهپرونده fsrc را به شیء شبهپرونده fdst کپی کنید. عدد صحیح length، اگر داده شود، اندازهی بافر است. بهویژه، مقدار منفی length به معنای کپی کردن دادهها بدون حلقهزدن روی دادههای منبع بهصورت تکهتکه است؛ بهطور پیشفرض، دادهها بهصورت تکهتکه خوانده میشوند تا از مصرف حافظهی کنترلنشده جلوگیری شود. توجه داشته باشید که اگر موقعیت فعلی پرونده در شیء fsrc برابر ۰ نباشد، تنها محتویات از موقعیت فعلی پرونده تا پایان پرونده کپی خواهند شد.
copyfileobj()ضمانت نمیکند که جریان مقصد در پایان کپی تخلیه شده باشد. اگر میخواهید در پایان عملیات کپی از مقصد بخوانید (برای مثال، محتوای یک پرونده موقت را بخوانید که از یک جریان HTTP کپی شده است)، باید اطمینان حاصل کنید که پیش از تلاش برای خواندن پرونده مقصد،flush()یاclose()را روی شیء شبهپرونده فراخوانی کردهاید.
- shutil.copyfile(src, dst, *, follow_symlinks=True)¶
محتوای پروندهای به نام src (بدون فراداده) را در پروندهای به نام dst کپی میکند و dst را به کارآمدترین شکل ممکن برمیگرداند. src و dst یا اشیاء مسیرمانند (path-like objects) هستند یا نامهای مسیری که بهصورت رشته داده شدهاند.
dst باید نام کامل پرونده مقصد باشد؛ برای کپیای که مسیر پوشه مقصد را میپذیرد، به
copy()مراجعه کنید. اگر src و dst یک پرونده را مشخص کنند،SameFileErrorپرتاب میشود.محل مقصد باید قابل نوشتن باشد؛ در غیر این صورت، استثنای
OSErrorپرتاب خواهد شد. اگر dst از قبل وجود داشته باشد، جایگزین خواهد شد. پروندههای خاص مانند دستگاههای نویسهای یا بلوکی و پایپها را نمیتوان با این تابع کپی کرد.اگر follow_symlinks نادرست باشد و src یک پیوند نمادین باشد، بهجای کپی کردن پروندهای که src به آن اشاره دارد، یک پیوند نمادین جدید ایجاد خواهد شد.
یک رویداد حسابرسی
shutil.copyfileرا با آرگومانهایsrcوdstپرتاب میکند.تغییر یافته در نسخهی 3.3: پیشتر
IOErrorبه جایOSErrorپرتاب میشد. آرگومان follow_symlinks افزوده شد. اکنون dst را برمیگرداند.تغییر یافته در نسخهی 3.4:
SameFileErrorبهجایErrorپرتاب میشود. از آنجا که اولی زیرکلاسی از دومی است، این تغییر سازگار با عقب است.تغییر یافته در نسخهی 3.8: ممکن است از فراخوانیهای سیستمی کپی سریع مختص پلتفرم بهصورت داخلی استفاده شود تا پرونده با کارایی بیشتری کپی شود. بخش عملیات کپی کارآمد وابسته به سکو را ببینید.
- exception shutil.SpecialFileError¶
این استثنا هنگامی پرتاب میشود که
copyfile()یاcopytree()برای کپی کردن یک پایپ نامدار تلاش کند.اضافه شده در نسخهی 2.7.
- exception shutil.SameFileError¶
این استثنا زمانی پرتاب میشود که مبدأ و مقصد در
copyfile()یک پرونده باشند.اضافه شده در نسخهی 3.4.
- shutil.copymode(src, dst, *, follow_symlinks=True)¶
بیتهای دسترسی را از src به dst کپی میکند. محتوای پرونده، مالک و گروه بدون تغییر باقی میمانند. src و dst اشیای شبهمسیر یا نامهای مسیر هستند که بهصورت رشته داده شدهاند. اگر follow_symlinks نادرست باشد و هر دو src و dst پیوندهای نمادین باشند،
copymode()تلاش میکند حالت خود dst را تغییر دهد (نه پروندهای که به آن اشاره میکند). این قابلیت در همه سکوها در دسترس نیست؛ لطفاً برای اطلاعات بیشترcopystat()را ببینید. اگرcopymode()نتواند پیوندهای نمادین را در سکوی محلی تغییر دهد و از آن خواسته شود که این کار را انجام دهد، هیچ کاری انجام نمیدهد و بازمیگردد.یک رویداد حسابرسی
shutil.copymodeرا با آرگومانهایsrcوdstپرتاب میکند.تغییر یافته در نسخهی 3.3: آرگومان follow_symlinks افزوده شد.
- shutil.copystat(src, dst, *, follow_symlinks=True)¶
بیتهای اجازه، زمان آخرین دسترسی، زمان آخرین تغییر و پرچمها را از src به dst کپی میکند. در لینوکس،
copystat()همچنین «ویژگیهای توسعهیافته» را در صورت امکان کپی میکند. محتوای پرونده، مالک و گروه بدون تغییر میمانند. src و dst اشیاء مسیرمانند یا نامهای مسیر دادهشده بهصورت رشته هستند.اگر follow_symlinks نادرست باشد و src و dst هر دو به پیوندهای نمادین اشاره کنند،
copystat()بهجای پروندههایی که پیوندهای نمادین به آنها اشاره میکنند، روی خود پیوندهای نمادین عمل میکند؛ اطلاعات را از پیوند نمادین src میخواند و اطلاعات را در پیوند نمادین dst مینویسد.توجه
همهی سکوها امکان بررسی و تغییر پیوندهای نمادین را فراهم نمیکنند. خود پایتون میتواند به شما بگوید چه قابلیتهایی بهصورت محلی در دسترس است.
اگر
os.chmod in os.supports_follow_symlinksبرابرTrueباشد،copystat()میتواند بیتهای دسترسی یک پیوند نمادین را تغییر دهد.اگر
os.utime in os.supports_follow_symlinksبرابرTrueباشد،copystat()میتواند زمانهای آخرین دسترسی و تغییر یک پیوند نمادین را تغییر دهد.اگر
os.chflags in os.supports_follow_symlinksبرابرTrueباشد،copystat()میتواند پرچمهای یک پیوند نمادین را تغییر دهد. (os.chflagsدر همهی سکوها در دسترس نیست.)
در سکوهایی که برخی یا همهی این قابلیتها در دسترس نیستند، هنگامی که از آن خواسته شود یک پیوند نمادین را تغییر دهد،
copystat()هر آنچه را که بتواند کپی میکند.copystat()هرگز شکست برنمیگرداند.برای اطلاعات بیشتر،
os.supports_follow_symlinksرا ببینید.یک رویداد حسابرسی
shutil.copystatرا با آرگومانهایsrc،dstپرتاب میکند.تغییر یافته در نسخهی 3.3: آرگومان follow_symlinks و پشتیبانی از ویژگیهای گستردهی لینوکس افزوده شد.
- shutil.copy(src, dst, *, follow_symlinks=True)¶
پرونده src را به پرونده یا پوشهی dst کپی میکند. src و dst باید اشیای مسیرمانند (path-like object) یا رشتهها باشند. اگر dst یک پوشه را مشخص کند، پرونده با استفاده از نام پایهی پرونده src در dst کپی خواهد شد. اگر dst پروندهای را مشخص کند که از قبل وجود دارد، آن پرونده جایگزین خواهد شد. مسیر پرونده تازه ایجادشده را برمیگرداند.
اگر follow_symlinks نادرست باشد و src یک پیوند نمادین باشد، dst بهصورت یک پیوند نمادین ایجاد میشود. اگر follow_symlinks درست باشد و src یک پیوند نمادین باشد، dst یک کپی از پروندهای خواهد بود که src به آن ارجاع میدهد.
copy()دادههای پرونده و حالت دسترسی پرونده (نگاه کنید بهos.chmod()) را کپی میکند. سایر فرادادهها، مانند زمانهای ایجاد و تغییر پرونده، حفظ نمیشوند. برای حفظ تمام فرادادههای پرونده اصلی، بهجای آن ازcopy2()استفاده کنید.یک رویداد حسابرسی
shutil.copyfileرا با آرگومانهایsrcوdstپرتاب میکند.یک رویداد حسابرسی
shutil.copymodeرا با آرگومانهایsrcوdstپرتاب میکند.تغییر یافته در نسخهی 3.3: آرگومان follow_symlinks اضافه شد. اکنون مسیر پرونده تازه ایجادشده را برمیگرداند.
تغییر یافته در نسخهی 3.8: ممکن است از فراخوانیهای سیستمی کپی سریع مختص پلتفرم بهصورت داخلی استفاده شود تا پرونده با کارایی بیشتری کپی شود. بخش عملیات کپی کارآمد وابسته به سکو را ببینید.
- shutil.copy2(src, dst, *, follow_symlinks=True)¶
مشابه
copy()است، با این تفاوت کهcopy2()همچنین تلاش میکند فراداده پرونده را حفظ کند.هنگامی که follow_symlinks false باشد و src یک پیوند نمادین باشد،
copy2()تلاش میکند همهی فرادادهها را از پیوند نمادین src به پیوند نمادین تازهایجادشدهی dst کپی کند. با این حال، این قابلیت در همهی سکوها در دسترس نیست. در سکوهایی که بخشی یا همهی این قابلیت در دسترس نیست،copy2()همهی فرادادهای را که بتواند حفظ میکند؛copy2()هرگز به این دلیل که نمیتواند فرادادهی پرونده را حفظ کند، استثنایی پرتاب نمیکند.copy2()ازcopystat()برای کپی فراداده پرونده استفاده میکند. لطفاً برای اطلاعات بیشتر درباره پشتیبانی پلتفرم از تغییر فراداده پیوند نمادین،copystat()را ببینید.یک رویداد حسابرسی
shutil.copyfileرا با آرگومانهایsrcوdstپرتاب میکند.یک رویداد حسابرسی
shutil.copystatرا با آرگومانهایsrc،dstپرتاب میکند.تغییر یافته در نسخهی 3.3: آرگومان follow_symlinks افزوده شد، سعی میکند ویژگیهای گسترشیافتهی سامانه فایلبندی را نیز کپی کند (در حال حاضر فقط در لینوکس). اکنون مسیر پرونده تازهایجادشده را برمیگرداند.
تغییر یافته در نسخهی 3.8: ممکن است از فراخوانیهای سیستمی کپی سریع مختص پلتفرم بهصورت داخلی استفاده شود تا پرونده با کارایی بیشتری کپی شود. بخش عملیات کپی کارآمد وابسته به سکو را ببینید.
- shutil.ignore_patterns(*patterns)¶
این تابع کارخانهای، تابعی ایجاد میکند که میتوان از آن بهعنوان یک شیء فراخوانیپذیر برای آرگومان ignore تابع
copytree()استفاده کرد؛ این تابع، پروندهها و پوشههایی را که با یکی از الگوهای بهسبک glob ارائهشده در patterns مطابقت دارند، نادیده میگیرد. مثال زیر را ببینید.
- shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)¶
بهصورت بازگشتی کل درخت پوشهای را که ریشه در src دارد، به پوشهای به نام dst کپی کنید و پوشه مقصد را برگردانید. تمام پوشههای میانی لازم برای دربرگرفتن dst نیز بهطور پیشفرض ایجاد خواهند شد.
مجوزها و زمانهای پوشهها با
copystat()کپی میشوند، پروندههای جداگانه با استفاده ازcopy2()کپی میشوند.اگر symlinks درست باشد، پیوندهای نمادین در درخت منبع بهصورت پیوندهای نمادین در درخت جدید نمایش داده میشوند و فرادادهی پیوندهای اصلی تا جایی که سکو اجازه میدهد کپی خواهد شد؛ اگر نادرست باشد یا ذکر نشود، محتوا و فرادادهی پروندههای پیوندشده به درخت جدید کپی میشوند.
هنگامی که symlinks نادرست باشد، اگر پروندهای که پیوند نمادین به آن اشاره میکند وجود نداشته باشد، استثنایی به فهرست خطاهایی که در پایان فرآیند کپی در یک استثنای
Errorپرتاب میشود، افزوده خواهد شد. اگر میخواهید این استثنا را نادیده بگیرید، میتوانید پرچم اختیاری ignore_dangling_symlinks را روی درست تنظیم کنید. توجه داشته باشید که این گزینه روی پلتفرمهایی که ازos.symlink()پشتیبانی نمیکنند، تأثیری ندارد.اگر ignore داده شود، باید یک شیء فراخوانیپذیر باشد که بهعنوان آرگومانهای خود، پوشهای را که
copytree()از آن بازدید میکند و فهرستی از محتویات آن را، همانطور کهos.listdir()برمیگرداند، دریافت میکند. از آنجا کهcopytree()بهصورت بازگشتی فراخوانی میشود، شیء فراخوانیپذیر ignore بهازای هر پوشهای که کپی میشود، یک بار فراخوانی خواهد شد. این شیء فراخوانیپذیر باید دنبالهای از نام پوشهها و پروندهها را نسبت به پوشه جاری برگرداند (یعنی زیرمجموعهای از آیتمهای آرگومان دوم خود)؛ سپس این نامها در فرایند کپی نادیده گرفته خواهند شد. میتوان ازignore_patterns()برای ایجاد چنین شیء فراخوانیپذیری استفاده کرد که نامها را بر اساس الگوهای بهسبک glob نادیده میگیرد.اگر استثنا(هایی) رخ دهد، یک
Errorهمراه با فهرستی از دلایل پرتاب میشود.اگر copy_function ارائه شود، باید یک شیء فراخوانیپذیر باشد که برای کپی کردن هر پرونده از آن استفاده میشود. این شیء با مسیر مبدأ و مسیر مقصد بهعنوان آرگومانها فراخوانی میشود. بهطور پیشفرض،
copy2()استفاده میشود، اما هر تابعی که از همان امضا پشتیبانی کند (مانندcopy()) میتواند استفاده شود.اگر dirs_exist_ok نادرست (پیشفرض) باشد و dst از قبل وجود داشته باشد، استثنای
FileExistsErrorپرتاب میشود. اگر dirs_exist_ok درست باشد، عملیات کپی در صورت مواجهه با پوشههای موجود ادامه مییابد و پروندههای درون درخت dst توسط پروندههای متناظر از درخت src بازنویسی میشوند.یک رویداد حسابرسی
shutil.copytreeرا با آرگومانهایsrcوdstپرتاب میکند.تغییر یافته در نسخهی 3.2: آرگومان copy_function افزوده شد تا بتوانید یک تابع کپی سفارشی ارائه دهید. آرگومان ignore_dangling_symlinks افزوده شد تا خطاهای پیوندهای نمادین معلق را هنگامی که symlinks برابر با false است، ساکت کند.
تغییر یافته در نسخهی 3.3: هنگامی که symlinks نادرست باشد، فراداده کپی میشود. اکنون dst را برمیگرداند.
تغییر یافته در نسخهی 3.8: ممکن است از فراخوانیهای سیستمی کپی سریع مختص پلتفرم بهصورت داخلی استفاده شود تا پرونده با کارایی بیشتری کپی شود. بخش عملیات کپی کارآمد وابسته به سکو را ببینید.
تغییر یافته در نسخهی 3.8: پارامتر dirs_exist_ok افزوده شد.
- shutil.rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None)¶
حذف یک درخت پوشهی کامل؛ path باید به یک پوشه اشاره کند (اما نه به یک پیوند نمادین به پوشه). اگر ignore_errors درست باشد، خطاهای ناشی از حذفهای ناموفق نادیده گرفته میشوند؛ اگر نادرست یا مشخصنشده باشد، چنین خطاهایی با فراخوانی هندلری که توسط onexc یا onerror مشخصشده است رسیدگی میشوند یا اگر هر دو مشخصنشده باشند، استثناها به فراخواننده انتشار مییابند.
این تابع میتواند از مسیرهای نسبی نسبت به توصیفگرهای پوشه پشتیبانی کند.
توجه
در پلتفرمهایی که توابع مبتنی بر fd لازم را پشتیبانی میکنند، بهطور پیشفرض از نسخهای از
rmtree()استفاده میشود که در برابر حملهی پیوند نمادین مقاوم است. در سایر پلتفرمها، پیادهسازیrmtree()در برابر حملهی پیوند نمادین آسیبپذیر است: با زمانبندی و شرایط مناسب، مهاجمان میتوانند پیوندهای نمادین روی سامانه فایلبندی را دستکاری کنند تا پروندههایی را حذف کنند که در غیر این صورت قادر به دسترسی به آنها نخواهند بود. برنامهها میتوانند از ویژگی تابعrmtree.avoids_symlink_attacksبرای تعیین اینکه کدام حالت صدق میکند استفاده کنند.اگر onexc ارائهشده باشد، باید یک شیء فراخوانیپذیر باشد که سه پارامتر را میپذیرد: function، path و excinfo.
نخستین پارامتر، function، تابعی است که استثنا را پرتاب کرده است؛ این تابع به پلتفرم و پیادهسازی بستگی دارد. دومین پارامتر، path، نام مسیر دادهشده به function خواهد بود. سومین پارامتر، excinfo، استثنایی است که پرتاب شده است. استثناهای پرتابشده از سوی onexc گرفته نخواهند شد.
onerror منسوخشده مشابه onexc است، با این تفاوت که سومین پارامتری که دریافت میکند، تاپل برگرداندهشده از
sys.exc_info()است.همچنین ملاحظه نمائید
مثال rmtree برای نمونهای از مدیریت حذف درخت پوشهای که شامل پروندههای فقطخواندنی است.
یک رویداد حسابرسی
shutil.rmtreeرا با آرگومانهایpathوdir_fdپرتاب میکند.تغییر یافته در نسخهی 3.3: نسخهای مقاوم در برابر حملهی پیوند نمادین افزوده شد که در صورت پشتیبانی سکو از توابع مبتنی بر fd، بهطور خودکار استفاده میشود.
تغییر یافته در نسخهی 3.8: در ویندوز، دیگر محتویات یک اتصالِ پوشه (directory junction) را پیش از حذف اتصال حذف نخواهد کرد.
تغییر یافته در نسخهی 3.11: پارامتر dir_fd اضافه شد.
تغییر یافته در نسخهی 3.12: پارامتر onexc افزوده شد، onerror منسوخ شد.
تغییر یافته در نسخهی 3.13:
rmtree()اکنون استثناهایFileNotFoundErrorرا برای همه موارد بهجز مسیر سطح بالا نادیده میگیرد. استثناهایی غیر ازOSErrorو زیرکلاسهایOSErrorاکنون همیشه به فراخواننده منتقل میشوند.
- shutil.move(src, dst, copy_function=copy2)¶
بهصورت بازگشتی یک پرونده یا پوشه (src) را به مکان دیگری منتقل میکند و مقصد را برمیگرداند.
اگر dst یک پوشه موجود یا پیوند نمادین به یک پوشه باشد، آنگاه src به داخل آن پوشه منتقل میشود. مسیر مقصد در آن پوشه نباید از قبل وجود داشته باشد.
اگر dst از قبل وجود داشته باشد اما پوشه نباشد، ممکن است بسته به رفتار
os.rename()بازنویسی شود.os.rename()ترجیحاً بهصورت داخلی زمانی استفاده میشود که src و مقصد روی سامانه فایلبندی یکسانی باشند. در صورتی کهos.rename()بهدلیلOSErrorبا شکست مواجه شود (مثلاً کاربر اجازهی نوشتن روی پرونده مقصد را دارد اما اجازهی نوشتن در پوشهی والد آن را ندارد)، این متد به استفاده از copy_function روی میآورد؛ در این حالت src با استفاده از copy_function به مقصد کپی میشود و سپس حذف میگردد.در مورد پیوندهای نمادین، یک پیوند نمادین جدید که به هدف src اشاره میکند، در مقصد یا بهعنوان مقصد ایجاد خواهد شد و src حذف خواهد شد.
اگر copy_function داده شده باشد، باید یک شیء فراخوانیپذیر باشد که ۲ آرگومان src و مقصد را میگیرد و در صورتی که نتوان از
os.rename()استفاده کرد، برای کپی src به مقصد از آن استفاده خواهد شد. اگر مبدأ یک پوشه باشد،copytree()فراخوانی میشود و copy_function به آن ارسال میشود. copy_function پیشفرض،copy2()است. استفاده ازcopy()بهعنوان copy_function اجازه میدهد جابهجایی در مواردی که کپی فراداده نیز ممکن نیست با موفقیت انجام شود، به بهای آنکه هیچگونه فرادادهای کپی نمیشود.یک رویداد حسابرسی
shutil.moveرا با آرگومانهایsrcوdstپرتاب میکند.تغییر یافته در نسخهی 3.3: مدیریت صریح پیوندهای نمادین برای سامانه فایلبندیهای خارجی اضافه شد، بدین ترتیب آن با رفتار mv در GNU تطبیق داده شد. اکنون dst را برمیگرداند.
تغییر یافته در نسخهی 3.5: آرگومان کلیدواژهای copy_function افزوده شد.
تغییر یافته در نسخهی 3.8: ممکن است از فراخوانیهای سیستمی کپی سریع مختص پلتفرم بهصورت داخلی استفاده شود تا پرونده با کارایی بیشتری کپی شود. بخش عملیات کپی کارآمد وابسته به سکو را ببینید.
تغییر یافته در نسخهی 3.9: یک path-like object را برای هر دو src و dst میپذیرد.
- shutil.disk_usage(path)¶
آمار استفاده از دیسک برای مسیر دادهشده را بهصورت یک named tuple با ویژگیهای total، used و free برمیگرداند که مقدار فضای کل، استفادهشده و آزاد را بر حسب بایت نشان میدهند. path میتواند یک پرونده یا یک پوشه باشد.
توجه
در سامانه فایلبندیهای یونیکس، path باید به مسیری درون یک افراز از سامانه فایلبندی سوارشده اشاره کند. در آن سکوها، CPython تلاشی برای دریافت اطلاعات استفاده از دیسک از سامانه فایلبندیهای سوارنشده نمیکند.
اضافه شده در نسخهی 3.3.
تغییر یافته در نسخهی 3.8: در ویندوز، path اکنون میتواند یک پرونده یا پوشه باشد.
دسترسپذیری: Unix, Windows.
- shutil.chown(path, user=None, group=None, *, dir_fd=None, follow_symlinks=True)¶
مالکیت user و/یا group مسیر دادهشده path را تغییر میدهد.
user میتواند نام کاربری سیستم یا uid باشد؛ همین موضوع برای group نیز صدق میکند. حداقل ۱ آرگومان لازم است.
همچنین ببینید
os.chown()، تابع زیربنایی.یک رویداد حسابرسی
shutil.chownرا با آرگومانهایpath،userوgroupپرتاب میکند.دسترسپذیری: Unix.
اضافه شده در نسخهی 3.3.
تغییر یافته در نسخهی 3.13: پارامترهای dir_fd و follow_symlinks افزوده شدند.
- shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)¶
مسیر یک پرونده اجرایی را برمیگرداند که اگر cmd دادهشده فراخوانی شود، اجرا میشود. اگر هیچ cmd فراخوانی نشود،
Noneبرمیگرداند.mode یک نقاب مجوز (permission mask) است که به
os.access()ارسال میشود و بهطور پیشفرض تعیین میکند که آیا پرونده وجود دارد و قابل اجرا است یا خیر.path یک «رشته
PATH» است که پوشههایی را که باید در آنها جستجو شود، مشخص میکند و باos.pathsepجدا میشود. هنگامی که path مشخصنشده باشد، متغیر محیطیPATHازos.environخوانده میشود و در صورت تنظیمنشدن آن، بهos.defpathبازمیگردد.اگر cmd شامل یک جزء پوشه باشد،
which()فقط مسیر مشخصشده را بهطور مستقیم بررسی میکند و پوشههای فهرستشده در path یا در متغیر محیطیPATHسیستم را جستوجو نمیکند.در ویندوز، اگر mode شامل
os.X_OKنباشد، پوشه فعلی به ابتدای path افزوده میشود. هنگامی که mode شاملos.X_OKباشد، از API ویندوزNeedCurrentDirectoryForExePathWبرای تعیین اینکه آیا پوشه فعلی باید به ابتدای path افزوده شود استفاده میشود. برای اجتناب از بررسی پوشه کاری فعلی برای پروندههای اجرایی: متغیر محیطیNoDefaultCurrentDirectoryInExePathرا تنظیم کنید.همچنین در ویندوز، از متغیر محیطی
PATHEXTبرای یافتن دستورهایی استفاده میشود که ممکن است از قبل شامل پسوند نباشند. برای مثال، اگرshutil.which("python")را فراخوانی کنید،which()درPATHEXTجستجو میکند تا بداند که باید به دنبالpython.exeدر پوشههای path بگردد. برای مثال، در ویندوز:>>> shutil.which("python") 'C:\\Python33\\python.EXE'
این مورد همچنین زمانی اعمال میشود که cmd مسیری باشد که شامل یک کامپوننت پوشه باشد:
>>> shutil.which("C:\\Python33\\python") 'C:\\Python33\\python.EXE'
اضافه شده در نسخهی 3.3.
تغییر یافته در نسخهی 3.8: نوع
bytesاکنون پذیرفته میشود. اگر نوع cmd از نوعbytesباشد، نوع نتیجه نیزbytesخواهد بود.تغییر یافته در نسخهی 3.12: در ویندوز، اگر mode شامل
os.X_OKباشد و WinAPINeedCurrentDirectoryForExePathW(cmd)نادرست باشد، پوشه جاری دیگر به ابتدای مسیر جستجو افزوده نمیشود؛ در غیر این صورت، پوشه جاری حتی اگر از قبل در مسیر جستجو باشد، به ابتدای آن افزوده میشود؛ اکنون ازPATHEXTاستفاده میشود، حتی وقتی cmd شامل یک کامپوننت پوشه باشد یا با پسوندی موجود درPATHEXTتمام شود؛ و اکنون میتوان نام پروندههایی که پسوند ندارند را پیدا کرد.
- exception shutil.Error¶
این استثنا، استثناهایی را که در حین یک عملیات چندپروندهای پرتاب میشوند، جمعآوری میکند. برای
copytree()، آرگومان استثنا فهرستی از تاپلهای ۳-تایی (srcname, dstname, exception) است.
عملیات کپی کارآمد وابسته به سکو¶
از پایتون 3.8 به بعد، همهی توابع مربوط به کپی پرونده (copyfile()، copy()، copy2()، copytree() و move()) ممکن است از فراخوانیهای سیستمی «کپی سریع» (fast-copy) ویژهی سکو استفاده کنند تا پرونده را کارآمدتر کپی کنند (به bpo-33671 مراجعه کنید). «کپی سریع» به این معنا است که عملیات کپی درون کرنل انجام میشود و از استفاده از بافرهای فضای کاربر در پایتون، مانند outfd.write(infd.read())، اجتناب میشود.
در macOS، از fcopyfile برای کپی کردن محتوای پرونده (نه فراداده) استفاده میشود.
در لینوکس از os.copy_file_range() یا os.sendfile() استفاده میشود.
در سولاریس، از os.sendfile() استفاده میشود.
در ویندوز، shutil.copyfile() از اندازه پیشفرض بافر بزرگتری (۱ MiB به جای ۶۴ KiB) استفاده میکند و از یک گونه مبتنی بر memoryview() برای shutil.copyfileobj() استفاده میشود.
اگر عملیات کپی سریع (fast-copy) ناموفق باشد و هیچ دادهای در پرونده مقصد نوشته نشده باشد، shutil بهصورت داخلی و بیصدا به تابع کمبازدهتر copyfileobj() بازمیگردد.
تغییر یافته در نسخهی 3.8.
تغییر یافته در نسخهی 3.14: Solaris اکنون از os.sendfile() استفاده میکند.
تغییر یافته در نسخهی 3.14: ممکن است کپی در زمان نوشتن (Copy-on-write) یا کپی سمت سرور بهصورت داخلی از طریق os.copy_file_range() در سامانه فایلبندیهای لینوکسی پشتیبانیشده استفاده شود.
مثال copytree¶
مثالی که از تابع کمکی ignore_patterns() استفاده میکند:
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
این کار همهچیز را به جز پروندههای .pyc و پروندهها یا پوشههایی که نام آنها با tmp شروع میشود، کپی میکند.
مثالی دیگر که از آرگومان ignore برای افزودن یک فراخوانی گزارش استفاده میکند:
from shutil import copytree
import logging
def _logpath(path, names):
logging.info('Working in %s', path)
return [] # nothing will be ignored
copytree(source, destination, ignore=_logpath)
مثال rmtree¶
این مثال نشان میدهد که چگونه میتوان یک درخت پوشه را در ویندوز حذف کرد، در حالتی که بیت فقطخواندنی برخی از پروندهها تنظیم شده است. این مثال از کالبک onexc برای پاک کردن بیت فقطخواندنی و تلاش دوباره برای حذف استفاده میکند. هر شکست بعدی منتشر خواهد شد.
import os, stat
import shutil
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onexc=remove_readonly)
عملیات بایگانی¶
اضافه شده در نسخهی 3.2.
تغییر یافته در نسخهی 3.5: پشتیبانی از قالب xztar اضافه شد.
ابزارهای سطح بالا برای ایجاد و خواندن پروندههای فشرده و بایگانیشده نیز ارائه شدهاند. این ابزارها به ماژولهای zipfile و tarfile متکی هستند.
- shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])¶
یک پرونده آرشیو (مانند zip یا tar) ایجاد میکند و نام آن را برمیگرداند.
base_name نام پروندهای است که ایجاد میشود، شامل مسیر، بدون هیچ پسوند مخصوص قالب.
format قالب بایگانی است: یکی از "zip" (اگر ماژول
zlibدر دسترس باشد)، "tar"، "gztar" (اگر ماژولzlibدر دسترس باشد)، "bztar" (اگر ماژولbz2در دسترس باشد)، "xztar" (اگر ماژولlzmaدر دسترس باشد)، یا "zstdtar" (اگر ماژولcompression.zstdدر دسترس باشد).root_dir پوشهای است که پوشهی ریشهی بایگانی خواهد بود؛ همهی مسیرهای داخل بایگانی نسبت به آن نسبی خواهند بود؛ برای مثال، معمولاً پیش از ایجاد بایگانی، با chdir وارد root_dir میشویم.
base_dir پوشهای است که بایگانی را از آن آغاز میکنیم؛ یعنی base_dir پیشوند مشترک همهی پروندهها و پوشههای درون بایگانی خواهد بود. base_dir باید نسبت به root_dir داده شود. برای چگونگی استفاده از base_dir و root_dir با یکدیگر، به مثال بایگانی با base_dir مراجعه کنید.
root_dir و base_dir هر دو بهطور پیشفرض برابر با پوشه جاری هستند.
اگر dry_run درست باشد، هیچ بایگانیای ایجاد نمیشود، اما عملیاتی که اجرا میشدند، در logger ثبت میشوند.
owner و group هنگام ایجاد یک آرشیو tar استفاده میشوند. بهطور پیشفرض، از مالک و گروه فعلی استفاده میشود.
logger باید یک شیء سازگار با PEP 282 باشد، معمولاً یک نمونه از
logging.Logger.آرگومان verbose استفاده نمیشود و منسوخ است.
یک رویداد حسابرسی
shutil.make_archiveرا با آرگومانهایbase_name،format،root_dir،base_dirپرتاب میکند.توجه
این تابع زمانی که بایگانیکنندههای سفارشی ثبتشده با
register_archive_format()از آرگومان root_dir پشتیبانی نمیکنند، ایمنی نخی ندارد. در این حالت، پوشه کاری فعلی فرایند را بهطور موقت به root_dir تغییر میدهد تا بایگانی انجام شود.تغییر یافته در نسخهی 3.8: قالب مدرن pax (POSIX.1-2001) اکنون بهجای قالب قدیمی GNU برای بایگانیهای ایجادشده با
format="tar"استفاده میشود.تغییر یافته در نسخهی 3.10.6: این تابع اکنون هنگام ایجاد بایگانیهای استاندارد
.zipو tar، ایمن از نظر نخی (thread-safe) شده است.
- shutil.get_archive_formats()¶
فهرستی از قالبهای پشتیبانیشده برای بایگانی برمیگرداند. هر عنصر از دنبالهی برگرداندهشده یک تاپل
(name, description)است.بهطور پیشفرض
shutilاین قالبها را فراهم میکند:zip: پرونده ZIP (اگر ماژول
zlibدر دسترس باشد).tar: پرونده tar فشردهنشده. برای بایگانیهای جدید از قالب POSIX.1-2001 pax استفاده میکند.
gztar: پرونده tar فشردهشده با gzip (اگر ماژول
zlibدر دسترس باشد).bztar: پرونده tar فشردهشده با bzip2 (اگر ماژول
bz2در دسترس باشد).xztar: پرونده tar فشردهشده با xz (اگر ماژول
lzmaدر دسترس باشد).zstdtar: پرونده tar فشردهشده با Zstandard (اگر ماژول
compression.zstdدر دسترس باشد).
با استفاده از
register_archive_format()میتوانید قالبهای جدید را ثبت کنید یا بایگانیکننده (archiver) خودتان را برای هر یک از قالبهای موجود ارائه دهید.
- shutil.register_archive_format(name, function[, extra_args[, description]])¶
یک بایگانیکننده برای قالب name ثبت کنید.
function یک شیء فراخوانیپذیر است که برای ایجاد بایگانیها استفاده خواهد شد. این شیء فراخوانیپذیر، base_name پروندهای که ایجاد میشود و سپس base_dir را (که پیشفرض آن
os.curdirاست) دریافت میکند تا بایگانی از آن آغاز شود. آرگومانهای بیشتر بهصورت آرگومانهای کلیدواژهای ارسال میشوند: owner، group، dry_run و logger (همانطور که درmake_archive()ارسال میشوند).اگر ویژگی سفارشی
function.supports_root_dirبرای function رویTrueتنظیم شده باشد، آرگومان root_dir بهعنوان یک آرگومان کلیدواژهای ارسال میشود. در غیر این صورت، پوشه کاری جاری فرایند پیش از فراخوانی function بهطور موقت به root_dir تغییر مییابد. در این حالتmake_archive()نخایمن نیست.در صورت ارائه، extra_args دنبالهای از جفتهای
(name, value)است که هنگام استفاده از شیء فراخوانیپذیر آرشیوکننده، بهعنوان آرگومانهای کلیدواژهای اضافی استفاده میشوند.description توسط
get_archive_formats()استفاده میشود، که فهرست بایگانیکنندهها را برمیگرداند. مقدار پیشفرض آن یک رشته خالی است.تغییر یافته در نسخهی 3.12: پشتیبانی از توابعی که از آرگومان root_dir پشتیبانی میکنند، افزوده شد.
- shutil.unregister_archive_format(name)¶
قالب بایگانی name را از فهرست قالبهای پشتیبانیشده حذف میکند.
- shutil.unpack_archive(filename[, extract_dir[, format[, filter]]])¶
یک بایگانی را واگشایی کنید. filename مسیر کامل بایگانی است.
extract_dir نام پوشه هدفی است که آرشیو در آن واگشایی میشود. اگر ارائه نشود، از پوشه کاری جاری استفاده میشود.
format قالب بایگانی است: یکی از "zip"، "tar"، "gztar"، "bztar"، "xztar" یا "zstdtar". یا هر قالب دیگری که با
register_unpack_format()ثبتشده باشد. اگر ارائه نشود،unpack_archive()از پسوند نام پرونده بایگانی استفاده میکند و بررسی میکند که آیا واگشایندهای برای آن پسوند ثبتشده است یا خیر. در صورتی که هیچ موردی یافت نشود، یکValueErrorپرتاب میشود.آرگومان filter که فقط کلیدواژهای است، به تابع واگشایی زیربنایی ارسال میشود. برای پروندههای zip، filter پذیرفته نمیشود. برای پروندههای tar، توصیه میشود از
'data'استفاده کنید (از Python 3.14 پیشفرض است)، مگر اینکه از ویژگیهای خاص tar و سامانه فایلبندیهای شبهUNIX استفاده کنید. (برای جزئیات، فیلترهای استخراج را ببینید.)یک رویداد حسابرسی
shutil.unpack_archiveرا با آرگومانهایfilename،extract_dirوformatپرتاب میکند.هشدار
هرگز بایگانیها را از منابع غیرقابلاعتماد بدون بررسی پیشین استخراج نکنید. ممکن است پروندهها خارج از مسیر مشخصشده در آرگومان extract_dir ایجاد شوند، برای مثال اعضایی که نامپروندههای مطلق یا نامپروندههایی دارای اجزای ".." دارند.
از پایتون 3.14، پیشفرضهای هر دو قالب توکار (پروندههای zip و tar) از خطرناکترینِ این مشکلات امنیتی جلوگیری خواهند کرد، اما از تمام رفتارهای ناخواسته جلوگیری نخواهند کرد. برای جزئیات مختص tar، بخش نکاتی برای تأیید بیشتر را مطالعه کنید.
تغییر یافته در نسخهی 3.7: یک path-like object را برای filename و extract_dir میپذیرد.
تغییر یافته در نسخهی 3.12: آرگومان filter اضافه شد.
- shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])¶
یک قالب واگشایی را ثبت میکند. name نام قالب است و extensions فهرستی از پسوندهای متناظر با قالب است، مانند
.zipبرای پروندههای Zip.function فراخوانیپذیری است که برای واگشایی آرشیوها استفاده خواهد شد. این فراخوانیپذیر دریافت خواهد کرد:
مسیر بایگانی، بهعنوان یک آرگومان جایگاهی؛
پوشهای که بایگانی باید در آن استخراج شود، بهعنوان یک آرگومان جایگاهی؛
احتمالاً یک آرگومان کلیدواژهای filter، اگر به
unpack_archive()داده شده باشد؛آرگومانهای کلیدواژهای اضافی، که توسط extra_args بهصورت دنبالهای از تاپلهای
(name, value)مشخصشدهاند.
میتوان description را برای توصیف قالب ارائه کرد، و توسط تابع
get_unpack_formats()بازگردانده میشود.
- shutil.unregister_unpack_format(name)¶
ثبت یک قالب واگشایی را لغو میکند. name نام قالب است.
- shutil.get_unpack_formats()¶
فهرستی از تمام قالبهای ثبتشده برای واگشایی را برمیگرداند. هر عنصر از دنبالهی برگرداندهشده یک تاپل
(name, extensions, description)است.بهطور پیشفرض
shutilاین قالبها را فراهم میکند:zip: پرونده ZIP (واگشایی پروندههای فشرده فقط زمانی کار میکند که ماژول مربوطه در دسترس باشد).
tar: پرونده tar فشردهنشده.
gztar: پرونده tar فشردهشده با gzip (اگر ماژول
zlibدر دسترس باشد).bztar: پرونده tar فشردهشده با bzip2 (اگر ماژول
bz2در دسترس باشد).xztar: پرونده tar فشردهشده با xz (اگر ماژول
lzmaدر دسترس باشد).zstdtar: پرونده tar فشردهشده با Zstandard (اگر ماژول
compression.zstdدر دسترس باشد).
با استفاده از
register_unpack_format()، میتوانید قالبهای جدید را ثبت کنید یا واگشای (unpacker) خودتان را برای هر قالب موجود فراهم کنید.
مثال بایگانی¶
در این مثال، یک بایگانی tar فشردهشده با gzip ایجاد میکنیم که شامل همهی پروندههای موجود در پوشهی .ssh کاربر است:
>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'gztar', root_dir)
'/Users/tarek/myarchive.tar.gz'
بایگانی حاصل شامل:
$ tar -tzvf /Users/tarek/myarchive.tar.gz
drwx------ tarek/staff 0 2010-02-01 16:23:40 ./
-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys
-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config
-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa
-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub
-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa
-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub
-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts
مثال بایگانی با base_dir¶
در این مثال، مشابه مثال بالا، نحوه استفاده از make_archive() را نشان میدهیم، اما این بار با استفاده از base_dir. اکنون ساختار پوشه زیر را داریم:
$ tree tmp
tmp
└── root
└── structure
├── content
└── please_add.txt
└── do_not_add.txt
در بایگانی نهایی، please_add.txt باید گنجانده شود، اما do_not_add.txt نباید گنجانده شود. بنابراین از دستور زیر استفاده میکنیم:
>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> make_archive(
... archive_name,
... 'tar',
... root_dir='tmp/root',
... base_dir='structure/content',
... )
'/Users/tarek/myarchive.tar'
فهرست پروندههای موجود در آرشیو حاصل به این صورت است:
$ python -m tarfile -l /Users/tarek/myarchive.tar
structure/content/
structure/content/please_add.txt
پرسوجوی اندازهی پایانهی خروجی¶
- shutil.get_terminal_size(fallback=(columns, lines))¶
اندازهی پنجرهی پایانه را بگیرید.
برای هر یک از دو بُعد، متغیر محیطی مربوطه، بهترتیب
COLUMNSوLINES، بررسی میشود. اگر متغیر تعریف شده باشد و مقدار آن یک عدد صحیح مثبت باشد، از آن استفاده میشود.هنگامی که
COLUMNSیاLINESتعریف نشده باشد، که حالت رایج است، از پایانهی متصل بهsys.__stdout__با فراخوانیos.get_terminal_size()پرسوجو میشود.اگر نتوان اندازه پایانه را با موفقیت پرسوجو کرد، چه به این دلیل که سیستم از پرسوجو پشتیبانی نمیکند و چه به این دلیل که به یک پایانه متصل نباشیم، از مقدار دادهشده به پارامتر
fallbackاستفاده میشود. مقدار پیشفرضfallbackبرابر(80, 24)است که اندازه پیشفرض مورد استفاده بسیاری از شبیهسازهای پایانه است.مقدار بازگشتی یک چندگانهی نامدار (named tuple) از نوع
os.terminal_sizeاست.همچنین ببینید: The Single UNIX Specification, Version 2، Other Environment Variables.
اضافه شده در نسخهی 3.3.
تغییر یافته در نسخهی 3.11: در صورتی که
os.get_terminal_size()صفرها را برگرداند، از مقدارهایfallbackنیز استفاده میشود.