hdiutil أصبح مهملاً في macOS 27. بديله متوفر بالفعل

macOSTahoe ·
hdiutil أصبح مهملاً في macOS 27. بديله متوفر بالفعل

أهملت Apple أداة hdiutil في macOS 27 لصالح diskutil image، وهذا الأمر متوفر بالفعل على جهاز Mac الخاص بك اليوم — لكنه يفتقد ميزات ربما تستخدمها.

تحمل صفحة الدليل (man page) في macOS 27 Golden Gate سطراً لم يكن موجوداً من قبل:

في macOS 27.0، أصبحت hdiutil مهملة. استخدم diskutil image بدلاً منها لجميع عمليات صور الأقراص.

كانت hdiutil هي الطريقة التي يتم بها إنشاء صور الأقراص وتركيبها وتحويلها وفحصها على جهاز Mac منذ Mac OS X 10.0. إذا سبق لك أن أصدرت ملف .dmg، أو كتبت سكريبت تثبيت، أو بنيت مهمة CI تُغلّف تطبيق Mac، أو أنشأت حاوية مشفّرة للحفاظ على خصوصية شيء ما، فأنت قد استخدمتها — سواء مباشرة أو عبر أداة أخرى استدعتها نيابةً عنك.

وهذا هو الجزء الذي فاتته معظم التغطيات الإعلامية: البديل ليس قادماً في المستقبل، بل هو موجود بالفعل على جهاز Mac الخاص بك. افتح Terminal الآن على macOS 26 Tahoe ونفّذ diskutil image. سترى أنها تستجيب.

أبرز النقاط

  • تعمل diskutil image بالفعل على macOS 26. تم التحقق من ذلك على macOS 26.5.2 (الإصدار 25F84). يمكنك ترحيل واختبار السكريبتات الخاصة بك اليوم، قبل صدور macOS 27.
  • الإهمال ليس إزالة. لا تزال hdiutil تعمل في macOS 27. لا شيء يتعطل في اليوم الأول. لكن Apple ظلت تقلّص هذه الأداة على مدار سبع سنوات، وصفحة الدليل توثّق كل خطوة من ذلك.
  • مساحة الأوامر أصغر بكثير. تعرض hdiutil 23 فعلاً (verb). بينما تعرض diskutil image 5 أوامر فرعية فقط.
  • لا يوجد أمر detach. يمكنك تركيب (attach) صورة قرص باستخدام diskutil image، لكن لا يمكنك فصلها بنفس الطريقة — فقد انتقلت هذه الوظيفة إلى diskutil eject.
  • بعض الأشياء ليس لها بديل حقيقي حتى الآن، بما في ذلك verify وcompact وmakehybrid. إذا كانت سكريبتات البناء لديك تستخدم هذه الأوامر، فلا يوجد أمامك مسار ترحيل اليوم.

أولاً: تحقق من ذلك بنفسك على جهاز Mac الخاص بك

لا تأخذ كلامي على محمل التصديق دون تحقق. أمر واحد كفيل بذلك:

diskutil image

على macOS 26.5.2 تظهر النتيجة التالية:

OVERVIEW: Manipulate disk images (attach, create, etc)

USAGE: diskutil image [--verbose] [--stdinpassphrase] [--plist] <subcommand>

SUBCOMMANDS:
  attach                  Attach a disk image as a device.
  info                    Print info regarding a disk image.
  create                  Create a disk image. Either blank or from an existing
                          source (disk, disk image or folder).
  resize                  Resize a given image to a specified size if
                          applicable.
  chpass                  Change the passphrase of a given encrypted image.

خمسة أوامر فرعية فقط. والآن قارن ذلك بما تقدّمه hdiutil، مباشرة من صفحة الدليل الخاصة بها:

Common verbs include attach, detach, verify, create, convert, and compact.

The rest of the verbs are currently: help, info, burn, checksum, chpass,
erasekeys, imageinfo, isencrypted, mountvol, unmount, plugins, udifrez,
udifderez, resize, segment, makehybrid, and pmap.

هذه 23 فعلاً مقابل 5 أوامر فرعية. هذه النسبة مقلقة للوهلة الأولى، وهي أيضاً مضلّلة، لأن المقارنة المباشرة فعلاً بفعل تعطي إجابة خاطئة. فبعض أفعال hdiutil تم دمجها في diskutil image تحت أسماء مختلفة، وبعضها الآخر كان مهملاً بالفعل منذ سنوات، وفعل واحد مهم انتقل بالكامل إلى أمر مختلف.

معرفة أي فعل يقابل أيّها هو صلب عملية الترحيل الفعلية، لذا دعونا نقوم بذلك بشكل صحيح.

هذا لم يأتِ من فراغ

قبل جدول الترحيل، إليك بعض السياق الذي يجعل هذا الإهمال يبدو أقل مفاجأة. تحتوي صفحة دليل hdiutil على قسم توافق يُقرأ وكأنه سجل مدته سبع سنوات لتقليص Apple لهذه الأداة تدريجياً. هذا القسم موجود على جهازك الآن — نفّذ man hdiutil وابحث عن عناوين الإصدارات:

macOS 10.15

  • إدخال ضغط lzma في تنسيق ULMO
  • إهمال دعم الملفات ثنائية الفرع بأسلوب OS 9 (‏hdiutil flatten/unflatten)
  • إزالة الأمر المهمل hdiutil internet-enable وأعلام (flags) التركيب الخاصة بـ IDME

macOS 11.0

  • إزالة دعم تنسيقات DiskCopy42 وDART وNDIF
  • إزالة دعم ترميزَي AppleSingle وMacBinary
  • إزالة دعم الملفات ثنائية الفرع بأسلوب OS 9
  • تغيير نظام الملفات الافتراضي للصور الجديدة إلى APFS

macOS 12.0

  • إهمال تنسيق UDBZ (ضغط bzip2)
  • إهمال صور UDIF المجزأة (‏hdiutil segment، ‏-segmentSize)
  • إهمال hdiutil udifrez/udifderez (تضمين واستخراج الموارد)

macOS 13.0

  • إزالة خيار encrypted-encoding-version؛ أصبحت جميع الصور المشفّرة الجديدة تستخدم الإصدار 2

كما تشير صفحة الدليل صراحة إلى أن -passphrase غير آمن، وأن الصور المجزأة مهملة، وأن UDBZ مهمل أيضاً.

إذا قرأت هذا كخط زمني متصل، فإن إهمال macOS 27 ليس سوى الخطوة الأخيرة في عملية بدأت حوالي عام 2019، وليس قراراً اتُّخذ هذا الصيف. وهذا أمر مهم للتخطيط: تُزيل Apple الأشياء من هذه الأداة تدريجياً، وتعلن عنها في صفحة الدليل أولاً. hdiutil في macOS 27 مهملة، وليست مُزالة، ولا يوجد تاريخ معلن للإزالة.

جدول الترحيل

هذه هي الخريطة الكاملة. لقد اختبرت كل واحد من هذه العناصر على macOS 26.5.2.

ما الذي تريد فعلهhdiutildiskutil image
تركيب صورة (mount)hdiutil attach x.dmgdiskutil image attach x.dmg
فك تركيب صورة (unmount)hdiutil detach /dev/diskNغير متوفر في diskutil image — استخدم diskutil eject /dev/diskN
إنشاء صورة فارغةhdiutil create -size 1g -fs APFS x.dmgdiskutil image create blank --size 1g x.dmg
إنشاء صورة من مجلدhdiutil create -srcfolder ./dir x.dmgdiskutil image create from ./dir x.dmg
تحويل التنسيقhdiutil convert in.dmg -format UDZO -o out.dmgdiskutil image create from in.dmg out.dmg --format UDZO
فحص صورةhdiutil imageinfo x.dmgdiskutil image info x.dmg
التحقق من التشفيرhdiutil isencrypted x.dmgdiskutil image info → Is Encrypted:
تغيير الحجمhdiutil resize -size 2g x.dmgdiskutil image resize
تغيير عبارة المرورhdiutil chpass x.dmgdiskutil image chpass x.dmg
التحقق من المجموع الاختباريhdiutil verify x.dmgلا يوجد مكافئ
ضغط صورة متفرقة (sparse)hdiutil compact x.sparsebundleلا يوجد مكافئ
إنشاء صورة هجينة/ISOhdiutil makehybridلا يوجد مكافئ
تضمين اتفاقية ترخيصhdiutil udifrezلا يوجد مكافئ (مهمل منذ macOS 12)
النسخ على وسائط ضوئيةhdiutil burnلا يوجد مكافئ

مفاجأة convert

أكثر خطأ شائع رأيته في التعليقات المبكرة على هذا الموضوع هو الاعتقاد بأنه «لا يوجد convert». والحقيقة أنه موجود — لكن باسم مختلف.

OVERVIEW: Create a disk image from an existing source (disk, disk image or
folder).

Source and destination disk image can be the same, which will perform the
conversion in place.

يقبل أمر diskutil image create from صورة قرص كمصدر له، وبالتالي فهو hdiutil convert تحت اسم مختلف، بل ويدعم أيضاً التحويل في المكان (in-place)، وهو ما لم يفعله hdiutil convert أبداً. إذا اكتفيت بعدّ الأفعال بدلاً من قراءة نص المساعدة، فستستنتج خطأً أن قدرة ما قد أُسقطت، بينما هي في الواقع قد تم توسيعها.

فجوة detach حقيقية فعلاً

هذه الحالة ليست مجرد إعادة تسمية. فلا وجود لأمر detach على الإطلاق داخل diskutil image:

$ diskutil image detach /dev/disk12
Error: 2 unexpected arguments: 'detach', '/dev/disk12'
Usage: diskutil image [--verbose] [--stdinpassphrase] [--plist] <subcommand>

البديل هو الأمر diskutil في مستواه الأعلى:

$ diskutil eject /dev/disk12
Disk /dev/disk12 ejected

وهذا يعمل بشكل جيد — لكن لاحظ ما يفعله ذلك بسكريبتاتك. فالتناظر الواضح بين hdiutil attach وhdiutil detach يتحول إلى diskutil image attach وdiskutil eject، وهما مستويان مختلفان من الأوامر الفرعية لنفس الملف الثنائي. أي دالة غلاف (wrapper) لديك تربط بين attach وdetach ستحتاج إلى إعادة هيكلة، لا مجرد بحث واستبدال.

ترحيل سكريبتات صور الأقراص

ما الذي تفعله diskutil image بشكل أفضل

سيكون من غير المنصف تقديم هذا الأمر باعتباره خسارة صِرفة. فهناك ثلاثة أمور تحسّنت فعلياً.

ASIF، وهو تنسيق لا تستطيع hdiutil إنشاءه إطلاقاً

تدعم diskutil image تنسيق Apple Sparse Image Format (ASIF)، بينما لا تدعمه hdiutil. إذا كنت تريد استخدام ASIF — وهو التنسيق الذي كانت Apple تتجه نحوه لأقراص الأجهزة الافتراضية على APFS — فإن diskutil image هي الأداة الوحيدة القادرة على إنتاجه.

من المفيد معرفة قوائم التنسيقات المدعومة:

create blank --format : RAW, ASIF, UDSB          (default RAW)
create from  --format : ASIF, RAW, UDRO, UDSB,
                        UDZO, ULFO, ULMO         (default ULFO)

يمكنها التركيب عبر HTTP وإنشاء أقراص RAM مباشرة

من نص مساعدة الأمر attach:

Supports 'ram://<size>', file paths, http[s].

كان إنشاء قرص RAM على macOS تقليدياً عملية من خطوتين مرهقتين نوعاً ما، وهي hdiutil attach -nomount ram://<sectors> ثم newfs_hfs أو diskutil eraseVolume. أما هنا فالأمر مجرد وسيطة واحدة لعلَم موثّق.

إنها أسرع بشكل ملحوظ

قام Jeff Johnson من Lapcat Software بإجراء اختبار أداء بين الأداتين أثناء تحقيقه في موضوع الإهمال في أوائل أغسطس 2026، ووجد أن diskutil image تُنجز عملية الإنشاء في 40 إلى 45 ثانية مقابل 110 إلى 115 ثانية لـhdiutil، مع إنتاج صورة أصغر حجماً في الوقت نفسه. هذا ليس فرقاً بسيطاً يمكن تجاهله. وبالنسبة لمهمة CI تبني صور أقراص عند كل commit، فهذا فرق ذو دلالة حقيقية.

ما الذي سيتعطل فعلياً في سكريبتاتك

تحذيرات الإهمال وحدها لا تُعطّل عمليات البناء. لكن هذه الأمور ستفعل.

1. لا بديل لـ -puppetstrings

يُصدر علَم -puppetstrings في hdiutil مخرجات تقدّم قابلة للتحليل آلياً، وهو بالضبط ما يحتاجه نظام البناء. ويشير Johnson إلى غياب هذا العلَم باعتباره إحدى الفجوات اللافتة. تمتلك diskutil image علَم --plist لإخراج نتائج منظمة، وتطبع تقدماً قابلاً للقراءة البشرية على النحو التالي:

[5% completed] [79% completed] [98% completed] [100% completed]
test.dmg created

إذا كانت لديك أدوات تحلل أسطر PERCENT: الصادرة من hdiutil، فلن يجد ذلك المحلِّل أي شيء يستند إليه بعد الآن.

2. عدة خيارات لأمر create اختفت ببساطة

يسرد مقال Johnson الخيارات -[no]crossdev و-[no]scrub و-[no]anyowners و-skipunreadable و-[no]atomic و-copyuid باعتبارها بلا نظير في الأداة الجديدة. إذا كنت تبني صوراً من مجلدات بطريقة محكومة بدقة — تثبيتات، عمليات التقاط أدلة جنائية، أو أي حالة يجب فيها ضبط الملكية أو الملفات المُدرجة بدقة تامة — فاقرأ هذه القائمة بعناية. فخياَرا -skipunreadable و-copyuid بالتحديد أساسيان لعمل بعض سكريبتات التغليف.

3. تغيّر سلوك التنظيف (scrubbing) بصمت

يذكر Johnson أن diskutil image تستبعد الملفات المؤقتة مثل مجلدات المهملات تلقائياً، وكأن خيار -scrub مفعّل دائماً. بينما كانت hdiutil تقوم بالتنظيف فقط عند الطلب. إذا كنت تتوقع أن تكون محتويات صورتك مطابقة بايتاً ببايت لمجلد المصدر، فسينتج عن ذلك صورة مختلفة دون أي تنبيه لك.

4. معالجة الأذونات تفشل بصمت

هذه هي النقطة التي كنت سأختبرها أولاً. وجد Johnson أنه في الحالات التي كانت فيها hdiutil تعرض مطالبة بالمصادقة عند مصادفة ملفات مملوكة لجذر النظام (root)، لا تعرض diskutil image أي مطالبة وتفشل ببساطة. السكريبت الذي كان يتوقف سابقاً في انتظار بيانات الاعتماد سينتج الآن صورة غير مكتملة، وقد يُبلغ بالنجاح اعتماداً على طريقة معالجة الأخطاء لديك.

إذا كنت تبني صوراً من مجلدات تحتوي على ملفات لا تملكها، فتحقق من الناتج بدلاً من الثقة بكود الخروج (exit code).

5. السجلّات أقل تفصيلاً

المخرجات المفصّلة (verbose) من diskutil image أقل تفصيلاً من مخرجات hdiutil. وستدرك ذلك تماماً عندما تتعطل عملية البناء في الثالثة صباحاً.

كيف تُرحّل دون كسر دعم macOS 26

معظمنا مضطر لدعم كلا النظامين لفترة من الوقت. والخبر الجيد، وهو أساس هذا المقال بأكمله، هو أنك لست بحاجة إلى التفرّع بناءً على إصدار النظام، لأن diskutil image موجودة أيضاً على macOS 26.

اكتشف القدرة المتوفرة، لا الإصدار:

#!/bin/bash
# Prefer diskutil image; fall back to hdiutil where unavailable.

if diskutil image --help >/dev/null 2>&1; then
  USE_DISKUTIL=1
else
  USE_DISKUTIL=0
fi

make_image_from_folder() {
  local src="$1" dst="$2"
  if [ "$USE_DISKUTIL" -eq 1 ]; then
    diskutil image create from "$src" "$dst" --format UDZO
  else
    hdiutil create -srcfolder "$src" -format UDZO "$dst"
  fi
}

attach_image() {
  local img="$1"
  if [ "$USE_DISKUTIL" -eq 1 ]; then
    diskutil image attach "$img" --nobrowse
  else
    hdiutil attach "$img" -nobrowse
  fi
}

detach_device() {
  # Note the asymmetry: detach is NOT under `diskutil image`.
  local dev="$1"
  if [ "$USE_DISKUTIL" -eq 1 ]; then
    diskutil eject "$dev"
  else
    hdiutil detach "$dev"
  fi
}

بعد ذلك، تحقق من الناتج، لأن الفروقات الصامتة تكمن هناك بالتحديد:

# Compare what actually landed in the image against the source.
diskutil image attach build.dmg --nobrowse --mountPoint /tmp/verify_mnt
diff -rq ./src /tmp/verify_mnt/src
diskutil eject /tmp/verify_mnt

خطوة diff -rq هذه هي التي لن أتخطاها أبداً. فبين التنظيف الدائم التفعيل وفشل الأذونات الصامت، فإن الصورة التي تُبنى بنجاح ليست بالضرورة نفس الصورة التي تحتوي على ما قصدته فعلاً.

إذا كنت تبني بيئة تطوير على Mac من الصفر، فإن دليلنا إعداد بيئة تطوير Apple silicon يغطي الأدوات المحيطة بهذا الموضوع، ويغطي دليل إتقان Terminal أساسيات الصَدَفة (shell) التي تفترضها هذه السكريبتات مسبقاً.

التحقق من محتويات صورة القرص

مثال عملي كامل من البداية إلى النهاية

إليك دورة تشغيل كاملة نُفذت على macOS 26.5.2، لكي ترى الناتج الحقيقي بدلاً من إعادة بناء افتراضية له.

إنشاء صورة من مجلد:

$ mkdir -p src && echo "hello" > src/file.txt
$ diskutil image create from src --format UDZO test.dmg
[5% completed] [79% completed] [98% completed] [99% completed] [100% completed]
test.dmg created

فحص الصورة:

$ diskutil image info test.dmg
Image Format: UDZO
Format Description: UDIF read-only compressed image (zlib)

	Identity Info:
		UUID: 061189CB-7502-4EA6-BFE3-424442C16D10

	Size Info:
		Empty Bytes: 3437056
		Total Bytes: 4233216

	Compression Info:
		Compressed Bytes: 4124
		Compression Type: zlib

	Encryption Info:
		Is Encrypted: 0

	Master Checksum Info:
		Checksum Type: crc32
		Checksum Value: c4 e3 90 4b

لاحظ أن أمر info يغطي ما كانت توفره سابقاً كل من hdiutil imageinfo وisencrypted وجزء من checksum بشكل منفصل. لكنه يُبلغ فقط عن المجموع الاختباري المخزَّن — ولا يتحقق منه فعلياً. وهذه هي بالضبط فجوة hdiutil verify.

تركيبها:

$ diskutil image attach test.dmg
/dev/disk12  	GUID_partition_scheme
/dev/disk13s1	Apple_APFS_Volume    	/Volumes/src

فصلها — باستخدام الأمر المختلف:

$ diskutil eject /dev/disk12
Disk /dev/disk12 ejected

الصور المشفّرة

إذا كنت تستخدم صور الأقراص كحاويات مشفّرة، فإن الآلية بسيطة ومباشرة، لكن الخيارات المتاحة أضيق.

# Create an encrypted blank image
diskutil image create blank --encrypt --size 10g --volumeName Vault vault.dmg

# Provide the passphrase on stdin rather than interactively
printf '%s' "$PASSPHRASE" | diskutil image create blank --encrypt --stdinpassphrase \
  --size 10g --volumeName Vault vault.dmg

# Change the passphrase later
diskutil image chpass vault.dmg

علَم --encrypt موثّق كتشفير AES-256 دون أي خيار لاختيار الخوارزمية، وهذا تبسيط وليس خسارة — فقد أزالت Apple إصدار الترميز المشفّر القديم سابقاً في macOS 13.

علَم --stdinpassphrase هو ما ينبغي استخدامه في أي سكريبت. وتحذّر صفحة دليل hdiutil نفسها من أن -passphrase غير آمن، لسبب بسيط وهو أن عبارة المرور الموضوعة في سطر الأوامر تكون مرئية في جدول العمليات (process table) لكل مستخدم على الجهاز.

إذا كنت تعتمد على صور الأقراص لأغراض الخصوصية لا للراحة فقط، فيستحق الأمر قراءة دليل أمان وخصوصية Mac لمعرفة موقع الصورة المشفّرة بالنسبة لـ FileVault — فكلاهما يحل مشكلة مختلفة، وملف .dmg المشفّر لا يحمي أي شيء طالما أنه مُركَّب (mounted).

ما الذي لا تزال صور الأقراص تُستخدم من أجله

يستحق الأمر أن نسأل لماذا يهم كل هذا أساساً، لأن مصطلح «صورة القرص» يبدو للوهلة الأولى وكأنه من مخلفات الماضي، بينما الأدوات المحيطة به لا تزال تؤدي دوراً جوهرياً بصمت في عدة مواضع.

توزيع التطبيقات. لا يزال ملف .dmg هو الطريقة القياسية لتوزيع تطبيقات Mac خارج App Store. فالصورة المضغوطة والمخصصة للقراءة فقط، والتي تحتوي على حزمة التطبيق ورابطاً رمزياً (symlink) إلى /Applications، هي اصطلاح السحب-للتثبيت الذي يعرفه المستخدمون. وكل واحدة من هذه الصور يُنشئها سكريبت يستدعي أداة صور أقراص.

الحاويات المشفّرة. ملف .dmg المشفّر هو خزنة محمولة ومكتفية ذاتياً، تُركَّب كوحدة تخزين (volume) وتعمل على أي جهاز Mac دون برامج خاصة. وعلى عكس FileVault، التي تحمي القرص بأكمله وهو في حالة سكون، تحمي الصورة المشفّرة مجموعة محددة من الملفات يمكنك نقلها بحرية — إلى عصا USB، أو إلى تخزين سحابي، أو إلى زميل عمل.

أقراص الأجهزة الافتراضية. هنا يكتسب ASIF أهميته، وهنا يتضح اتجاه Apple بجلاء.

حزم Sparsebundle للنسخ الاحتياطي الشبكي. عندما تنسخ Time Machine احتياطياً إلى وجهة شبكية، فإنها تخزّن النسخة الاحتياطية داخل حزمة sparsebundle — وهي صورة قرص مقسّمة إلى عدد كبير من ملفات النطاقات (bands) الصغيرة بحيث لا يلزم مزامنة سوى النطاقات المتغيرة فقط. وأي شخص أدار واحدة من هذه الحزم سبق له أن نفّذ hdiutil compact لاستعادة المساحة من النطاقات المحذوفة.

الأدلة الجنائية والأرشفة. صورة على مستوى الكتل (block-level) لوحدة تخزين، مصحوبة بمجموع اختباري، هي الطريقة التي تحافظ بها على الحالة الدقيقة لقرص ما. وأمر hdiutil verify هو الطريقة التي تتأكد بها من ذلك لاحقاً.

قارن هذه القائمة بجدول الترحيل، وستجد أن الفجوات تصطف مع مجتمعات مستخدمين محددة بدلاً من أن تكون عشوائية. فمطورو التطبيقات يفقدون آلية اتفاقية الترخيص وعلَم -puppetstrings. ومستخدمو النسخ الاحتياطي وsparsebundle يفقدون compact. ومستخدمو الأرشفة والأدلة الجنائية يفقدون verify. أما كل من يقوم بعمليات إنشاء وتحويل وتركيب روتينية فلا مشكلة لديه على الإطلاق.

ASIF: التنسيق الذي لا تنتجه سوى الأداة الجديدة

تنسيق Apple Sparse Image Format هو أوضح إشارة على سبب رغبة Apple في نقل المستخدمين بعيداً عن hdiutil، لأن hdiutil غير قادرة على إنتاجه إطلاقاً.

الصورة المتفرقة (sparse) لا تشغل مساحة على القرص إلا للكتل التي تحتوي فعلياً على بيانات. فصورة متفرقة بحجم 100 جيجابايت تحمل 10 جيجابايت من الملفات تشغل نحو 10 جيجابايت فقط على القرص، وتنمو كلما أضفت بيانات جديدة. كان تنسيقا الصورة المتفرقة القديم UDSP وحزمة sparsebundle UDSB يفعلان الشيء نفسه، لكن مع مشاكل معروفة: تتفتت حزم sparsebundle إلى آلاف من ملفات النطاقات، وكان كلا التنسيقين تاريخياً ضعيفاً في استعادة المساحة، وهذا بالضبط هو سبب وجود hdiutil compact أصلاً.

صُمم ASIF ليعمل بشكل متكامل مع APFS بدلاً من أن يُلحق به لاحقاً، مما يتيح لدعم الملفات المتفرقة المدمج في نظام الملفات نفسه أن يقوم بالعمل بدلاً من أن يحاكيه تنسيق الصورة. ومن الناحية العملية، تظهر الفائدة بأكبر وضوح في المحاكاة الافتراضية، حيث يكون قرص الجهاز الافتراضي ملفاً كبيراً فارغاً في معظمه ويتغير باستمرار — وهي الحالة التي كانت الأكثر إيلاماً للتنسيقات القديمة.

يمكنك إنشاء واحدة اليوم:

# A 100GB ASIF image that occupies only what it uses
diskutil image create blank --format ASIF --size 100g \
  --volumeName VMDisk vmdisk.asif

# Convert an existing image to ASIF
diskutil image create from old.dmg new.asif --format ASIF

لاحظ أن التنسيق يُستنتج من امتداد الملف — يعود create blank افتراضياً إلى RAW «ما لم يكن مسار الصورة يحمل امتداد ‎.asif أو ‎.sparsebundle». تسمية الملف بشكل صحيح كافية وحدها؛ وتمرير --format أيضاً هو مجرد احتياط إضافي.

المقايضة هنا هي قابلية النقل. فـASIF تنسيق جديد، ولن تُفتح صورة ASIF على إصدار أقدم من macOS أو على أي جهاز ليس Mac. وهذا غير ذي أهمية بالنسبة لقرص جهاز افتراضي أو وحدة تخزين عمل محلية. أما بالنسبة لأي شيء ستسلّمه لشخص آخر، فاستخدم UDZO للحفاظ على التوافقية.

أين يقع هذا الأمر ضمن خط أنابيب التوزيع (distribution pipeline)

إذا كنت تُصدر تطبيق Mac خارج App Store، فإن خطوة صورة القرص تقع في منتصف سلسلة من الخطوات، ويستحق الأمر أن نرى أين يقع التغيير بالضبط.

#!/bin/bash
set -euo pipefail

APP="build/MyApp.app"
DMG="dist/MyApp.dmg"
STAGE="$(mktemp -d)"

# 1. Sign the app bundle (unchanged by any of this)
codesign --force --options runtime --timestamp \
  --sign "Developer ID Application: Example Inc (TEAMID123)" \
  "$APP"

# 2. Stage the contents the user will see
cp -R "$APP" "$STAGE/"
ln -s /Applications "$STAGE/Applications"

# 3. Build the image — the step this article is about
diskutil image create from "$STAGE" "$DMG" --format UDZO

# 4. Sign the image itself
codesign --force --timestamp \
  --sign "Developer ID Application: Example Inc (TEAMID123)" \
  "$DMG"

# 5. Notarize and staple
xcrun notarytool submit "$DMG" --keychain-profile "AC_NOTARY" --wait
xcrun stapler staple "$DMG"

rm -rf "$STAGE"

الخطوة 3 فقط هي التي تتغير. أما التوقيع والتوثيق الرسمي (notarization) والتدبيس (stapling) فلا تتأثر — فهي تعمل على الصورة النهائية ولا يهمها أي أداة أنتجتها.

هناك أمران يستحقان المراقبة في خط أنابيب حقيقي. أولاً، تحقق من أن محتويات المرحلة المؤقتة (staged) وصلت بشكل صحيح، بسبب سلوك التنظيف الصامت والأذونات الموصوف أعلاه — فتنفيذ diff -rq بين $STAGE والنتيجة المُركَّبة هو تأمين رخيص التكلفة. ثانياً، إذا كان سكريبتك الحالي يُضمّن اتفاقية ترخيص باستخدام hdiutil udifrez، فاعلم أن هذه الخطوة ليس لها بديل وأنها مهملة منذ macOS 12. أبقِ على hdiutil من أجلها ما دامت لا تزال موجودة، وخطط لبديل.

استكشاف المشكلات الشائعة وإصلاحها

«diskutil image: command not found» أو عدم التعرف على الأمر الفرعي

المشكلة: أنت تستخدم إصداراً من macOS أقدم من 26، حيث لا يوجد فيه الفعل image أصلاً.

الحل: استخدم فحص القدرة الموضح أعلاه بدلاً من الافتراض. يعيد diskutil image --help >/dev/null 2>&1 قيمة غير صفرية على الأنظمة التي تفتقد هذه القدرة، وهو تفرّع موثوق. لا تختبر sw_vers — فما يهمك فعلياً هو وجود الأمر الفرعي نفسه.

الصورة تُبنى لكن تفتقد بعض الملفات

المشكلة: سببان محتملان. إما أن diskutil image تخطّت ملفات لم تستطع قراءتها بصلاحيات مستخدمك دون أن تطالب بالمصادقة، أو أن تنظيفها الدائم التفعيل أزال عناصر كانت hdiutil ستُدرجها.

الحل: ركّب الناتج ونفّذ عليه diff -rq مقارنة بمجلد المصدر. إذا كانت الملفات مفقودة بسبب الملكية، فشغّل عملية البناء بالصلاحيات اللازمة بدلاً من انتظار مطالبة. لا تعتمد على كود الخروج وحده.

تعطّل تحليل التقدم (progress parsing) في CI

المشكلة: لا يوجد مكافئ لـ-puppetstrings في diskutil image، لذا فإن السكريبتات التي كانت تحلل تقدم hdiutil القابل للقراءة آلياً لم يعد أمامها ما تقرأه.

الحل: استخدم --plist للحصول على نتيجة منظمة، وتعامل مع التقدم على أنه غير متاح. إذا كان نظام CI لديك يحتاج إلى التقدم تحديداً، فإن الإبقاء على hdiutil لهذه الخطوة أمر مشروع تماماً — فهي مهملة وليست مُزالة، ولا يوجد تاريخ معلن للإزالة.

تعذّر الفصل — «resource busy»

المشكلة: هناك عملية ما لا تزال تُبقي وحدة التخزين مفتوحة. وهذا السلوك لم يتغير عما كان عليه دائماً.

الحل: نفّذ lsof +D /Volumes/YourVolume لتحديد العملية الممسكة بالوحدة، ثم diskutil eject. غالباً ما يكون فهرسة Spotlight أو برامج مكافحة الفيروسات هي الجاني؛ ويساعد التركيب باستخدام --nobrowse في تجنب بعض هذه الحالات عبر إبقاء وحدة التخزين خارج نطاق Finder.

ملف .dmg يحتوي على اتفاقية ترخيص لم يعد يُبنى

المشكلة: تعتمد آلية اتفاقية الترخيص على hdiutil udifrez، التي أهملتها Apple سابقاً في macOS 12 ولا يوجد لها نظير في diskutil image.

الحل: لا يوجد مسار بديل. استمر في استخدام hdiutil لهذه الخطوة ما دامت موجودة، وخطط لطريقة توزيع لا تعتمد على اتفاقية مُضمّنة. وقد كان هذا الأمر معلناً منذ أربع سنوات، وهو أمر يستحق معرفته إن كنت تكتشفه الآن فقط.

الأسئلة الشائعة

هل لا تزال hdiutil تعمل في macOS 27؟

نعم. فهي مهملة، وليست مُزالة. الإهمال هو إشارة من Apple إلى نيّتها وبداية عد تنازلي، وليس تغييراً وظيفياً. لا شيء يعمل اليوم سيتوقف عن العمل عند تثبيت macOS 27.

متى ستُزال hdiutil فعلياً؟

لم تُعلن Apple عن ذلك. وبالنظر إلى تاريخ صفحة الدليل نفسها، فإن نمط Apple مع هذه الأداة كان إهمال ميزة في إصدار ما ثم إزالتها بعد إصدار رئيسي واحد أو أكثر — فقد استغرقت كل من internet-enable ودعم OS 9 ثنائي الفرع دورة كاملة على الأقل. وأي شخص يعطيك رقم إصدار محدد للإزالة إنما يخمّن فحسب.

هل يمكنني استخدام diskutil image على macOS 26 Tahoe؟

نعم، وهذه هي الحقيقة الأكثر فائدة في هذا المقال. تم التحقق من ذلك على macOS 26.5.2 (الإصدار 25F84). يمكنك ترحيل سكريبتاتك واختبارها الآن، على النظام الذي تستخدمه بالفعل، بدلاً من انتظار macOS 27.

هل diskutil image بديل كامل لـ hdiutil؟

لا، ليس بعد اليوم. فأوامر verify وcompact وmakehybrid وburn ليس لها نظير، وعدة خيارات لأمر create تُستخدم للتحكم الدقيق في الملفات المُدرجة غير موجودة. أما بالنسبة للمسار الشائع — الإنشاء والتحويل والتركيب والفحص وتغيير الحجم والتشفير — فهي مكتملة تماماً.

لماذا فعلت Apple هذا؟

لم تنشر Apple تبريراً رسمياً لذلك. لكن ما يمكن ملاحظته هو أن diskutil image أسرع في اختبارات الأداء، وتنتج صوراً أصغر حجماً، وتدعم تنسيق ASIF الأحدث الذي لا تستطيع hdiutil إنتاجه، وتقدّم مساحة أوامر أصغر بكثير. ودمج معالجة صور الأقراص ضمن diskutil إلى جانب بقية إدارة التخزين هو اتجاه منطقي ومتماسك. وهذا تفسير مستنبط من الأدلة المتاحة، وليس تصريحاً من Apple.

هل سيتعطل تطبيقي إذا استدعى hdiutil عبر الصَدَفة (shell)؟

لن يتعطل في macOS 27. لكن خطط للانتقال على أي حال — واستخدم فحص القدرة بحيث يغطي مسار برمجي واحد كلا الحالتين، وهذا أسهل مما يبدو، تحديداً لأن الأمر الجديد موجود بالفعل على macOS 26.

الخلاصة

العنوان الرئيسي — أمر Terminal عمره 25 عاماً يُسحب من الخدمة — صحيح لكنه مضلّل في كلا الاتجاهين. فهو يقلّل من شأن التغيير بالنسبة لأي شخص تستخدم سكريبتات البناء لديه verify أو compact أو makehybrid أو خيارات create الدقيقة، لأن هذه الأمور ليس لها مسار للمضي قدماً اليوم. وهو في الوقت نفسه يبالغ في شأنه بالنسبة لكل من عداهم، لأن hdiutil لا تزال تعمل في macOS 27، ولم تُعلن Apple عن أي تاريخ للإزالة، والإهمال ليس سوى الخطوة الأخيرة في عملية تقليص موثّقة في صفحة دليل الأداة نفسها منذ macOS 10.15.

الشيء المفيد حقاً الذي يجب معرفته هو أن البديل ليس أمراً مستقبلياً. فأداة diskutil image موجودة على جهاز Mac الخاص بك الآن، على macOS 26، مع عمل create وattach وinfo وresize وchpass بشكل كامل. يمكنك إجراء هذا الترحيل في عصر يوم ثلاثاء عادي على النظام الذي تملكه بالفعل، والتحقق منه باستخدام diff -rq، ثم التوقف عن التفكير فيه.

فقط تذكّر أن detach ليس حيث تتوقعه.

قراءات ذات صلة: إتقان Terminal على macOS، إعداد بيئة تطوير Apple silicon، وإسقاط وحدات تخزين HFS+ المشفّرة في macOS 28.