لینوکس و دنیای متن‌باز

ترفند مخفی لینوکس: دستور mv که کار سه تا دستور رو با هم انجام میده!

تا حالا شده بخوای دوتا فایل رو با هم جابجا کنی؟ راه سنتیش اینه که اولی رو موقت تغییر نام بدی، دومی رو بیاری جاش، بعد فایل موقت رو بذاری جای دومی! خیلی مسخره و دردسرسازه، مگه نه؟ تازه تو یه لحظه کوتاه، ممکنه یکی از فایل‌ها اصلاً وجود نداشته باشه و سیستم گیج بشه.

خوشبختانه از نسخه ۹.۵ به بعد، ابزار GNU coreutils یه راه حل خفن به اسم mv --exchange گذاشته جلو پای ما که کار رو خیلی راحت کرده. تو این مقاله قراره ببینیم این قابلیت چطور کار می‌کنه، چطور چکش کنیم و چه اشتباهاتی نباید موقع استفاده ازش بکنیم.

روش قدیمی: سه بار جابجایی و دردسرهای فایل موقت

فرض کن دوتا فایل کانفیگ به اسم‌های nginx.conf و nginx.conf.new داری و می‌خوای جدید جای قدیم بشه و فایل قدیمی هم دست‌نخورده بمونه. با دستور کلاسیک mv command باید این شکلی عمل می‌کردی:

mv nginx.conf nginx.conf.tmp
mv nginx.conf.new nginx.conf
mv nginx.conf.tmp nginx.conf.new

این روش دو تا مشکل اساسی داره:

  • خلاء زمانی وجود داره: بین دستور اول و دوم، فایل nginx.conf اصلاً وجود نداره! اگه تو همون صدم ثانیه یه سرویس بخوادش، با خطا روبرو میشه.
  • نصفه کاره موندن کار: اگه دستور دوم به هر دلیلی خطا بده، با یه فایل موقت و یه سیستم به هم ریخته تنها می‌مونی.

حالا آپشن exchange همین کار رو تو یه دستور تکی و تمیز انجام میده:

mv --exchange nginx.conf nginx.conf.new

جابجایی فایل‌ها با mv –exchange

آپشن --exchange به دستور mv می‌گه که این دوتا مسیر رو تو یک عملیات اتمیک با هم جابجا کن. این یعنی درایور سیستم‌عامل با کمک کرنل و با استفاده از سیستمکال renameat2() و Flag مربوط به RENAME_EXCHANGE این کار رو طوری انجام میده که تو هیچ لحظه‌ای فایل گم نشه.

چطور بفهمیم سیستم ما از این قابلیت پشتیبانی می‌کنه؟

اول از همه باید ورژن coreutils رو چک کنی:

mv --version

نکته مهم اینه که شماره ورژن‌ها اعشاری نیستن؛ مثلاً نسخه 9.11 از نسخه 9.5 جدیدتره! می‌تونی از این دستور هم برای چک کردن کمک بگیری:

mv --help | grep exchange

اگه چیزی چاپ نشد، یعنی توزیع لینوکس شما هنوز این قابلیت رو نداره.

تست عملی جابجایی دو فایل

بیاید دوتا فایل تستی بسازیم:

echo "config A" > a.conf
echo "config B" > b.conf

حالا با دستور زیر جابجاشون می‌کنیم:

mv --exchange a.conf b.conf

و نتیجه رو می‌بینیم:

cat a.conf b.conf
config B
config A

به همین سادگی! محتوای فایل‌ها جابجا شد بدون اینکه نیاز به فایل موقت باشه.

mv --exchange - ترفند مخفی لینوکس: دستور mv که کار سه تا دستور رو با هم انجام میده!

جابجایی دو تا دایرکتوری (و اشتباهی که خودم کردم!)

این ترفند برای دایرکتوری‌ها هم کار می‌کنه و اتفاقاً جذاب‌ترم هست. اما بار اولی که تستش کردم به این خطا خوردم:

mkdir release-old release-new
touch release-old/v1 release-new/v2
mv --exchange release-old release-new
mv: cannot exchange 'release-old' and 'release-new/release-old': Unknown error -1

دلیلش اینه که وقتی آرگومان آخر یه دایرکتوری موجود باشه، دستور mv فکر می‌کنه می‌خوای فایل رو بریزی توش! راه حلش استفاده از آپشن -T (یا همون --no-target-directory) است:

mv -T --exchange release-old release-new
ls release-old release-new

حالا کل ساختار دایرکتوری‌ها بدون توجه به حجمشون با هم جابجا شدن.

جاهایی که این دستور به دادمون می‌رسه

  • آپدیت کانفیگ‌ها: می‌تونی فایل جدید رو جایگزین کنی و فایل قبلی رو برای بازگشت سریع (Rollback) نگه داری.
  • سوئیچ کردن دایرکتوری‌های انتشار (Release): آپدیت نسخه سایت تو پوشه‌ها در یک قدم.
  • برگشت به عقب: اجرای دوباره همون دستور، همه‌چیز رو به حالت اول برمی‌گردونه.

محدودیت‌هایی که باید بدونید

هر دو مسیر باید روی یک Filesystem باشن

این قابلیت فقط روی یک Filesystem کار می‌کنه. اگه بخوای یه فایل رو با یه مسیر روی tmpfs یا حافظه رم جابجا کنی، کرنل با خطای نامفهوم Unknown error -1 جلوت رو می‌گیره چون جابجایی اتمیک بین دو تا دیسک یا ساختار جداگانه امکان‌پذیر نیست.

mv --exchange - ترفند مخفی لینوکس: دستور mv که کار سه تا دستور رو با هم انجام میده! (2)

پشتیبانی خود Filesystem

طبیعتاً ساختار زیرساختی و Filesystem شما مثل ext4، Btrfs یا XFS باید از این قابلیت پشتیبانی کنن که خوشبختانه سیستم‌های مدرن امروزی مشکلی ندارند.

نتیجه‌گیری

دستور mv --exchange یکی از اون ابزارهای کوچیک اما فوق‌العاده کاربردیه که کارهای خسته‌کننده توی Terminal رو خیلی راحت‌تر می‌کنه. اگه از توزیع‌های مدرن مثل فدوا یا دبیان استفاده می‌کنی، همین الان می‌تونی ازش لذت ببری!

منبع اصلی: It's FOSS (اخبار لینوکس) | 14 آبان 1405

خسرو عظیمی

خسرو عظیمی هستم. علاقه مند به دنیای اوپن سورس و IT، لینوکس، امنیت، وب و برنامه نویسی. در حال حاضر توسعه دهنده وب، کارشناس سئو و ادمین سیستم عامل هستم. لینک سایت شخصی: khosro-azimi.ir

مطالب مرتبط

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا