لتمرير اسم ملف يحتوي على مسافات إلى سكريبت shell على نظام macOS، ضع المسار بين علامتي اقتباس كوسيطة واحدة عند تشغيل السكريبت، ثم استخدم "$1" داخل السكريبت. على سبيل المثال، يمرر ./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf" اسم ملف واحد؛ وبدون علامات الاقتباس، يقسم shell المسار إلى عدة وسائط. تعمل هذه الطريقة أيضًا مع المسارات التي تحتوي على أحرف أخرى حساسة لـ shell عند وضعها بين علامات اقتباس بشكل صحيح.

تشغيل السكريبت مع المسار كوسيطة واحدة

في تطبيق Terminal، ضع علامتي اقتباس مزدوجتين حول اسم الملف الكامل أو المسار، بما في ذلك مجلداته، مع إبقاء اسم السكريبت منفصلاً:

./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf"

وضع شرطة مائلة عكسية (backslash) قبل كل مسافة يعمل أيضًا مع المسار البسيط المكتوب يدويًا: ./process-file.sh /Users/sam/Documents/Quarterly\ Report.pdf. لكن وضع المسار بالكامل بين علامتي اقتباس يسهل قراءته ويكون أقل عرضة للأخطاء، خاصة عندما يحتوي على مسافات متعددة. علامات الاقتباس هي جزء من بناء جملة shell؛ فهي تجمع المسار في وسيطة واحدة وليست جزءًا من اسم الملف الذي يستقبله السكريبت. يقوم shell بتقسيم الكلمات بعد التوسيعات، لذا يمكن تقسيم المسار غير المحاط بعلامات اقتباس عند مواضع المسافات. Bash Reference Manual: Quoting

إذا كان الملف في الدليل الحالي، فإن استخدام مسار نسبي يفي بالغرض أيضًا:

./process-file.sh "Quarterly Report.pdf"

يجب أن يشير المسار مع ذلك إلى ملف موجود بالفعل انطلاقًا من الدليل الذي تشغل الأمر منه. إذا لم يكن السكريبت نفسه قابلاً للتنفيذ، فقم باستدعائه باستخدام shell بدلاً من ذلك، على سبيل المثال bash process-file.sh "/Users/sam/Documents/Quarterly Report.pdf". كلتا الصيغتين تمرر المسار كوسيطة؛ ويحتاج السكريبت إلى إذن قراءة للملف كما يجب عليه معالجة أي أذونات مطلوبة أخرى.

استخدام الوسيطة بأمان داخل السكريبت

احفظ هذا الملف باسم process-file.sh:

#!/bin/bash

if [ "$#" -ne 1 ]; then
  printf 'Usage: %s FILE\n' "$0" >&2
  exit 2
fi

file=$1
if [ ! -f "$file" ]; then
  printf 'Not a regular file: %s\n' "$file" >&2
  exit 1
fi

printf 'Received one file: %s\n' "$file"

يتحقق السكريبت من أنه تلقى وسيطة واحدة بالضبط، ويتحقق من أن المسار يشير إلى ملف عادي، ثم يطبع المسار المستلم. يمثل $# عدد الوسائط؛ ويمثل $1 الوسيطة الأولى. احرص على إبقاء توسيعات المتغيرات بين علامتي اقتباس—"$file"—عند تمرير مسار إلى أمر أو استخدامه في اختبار شرطي. وإلا فقد يقسم shell القيمة التي تحتوي على مسافات إلى كلمات منفصلة ويعامل أحرف البدل (wildcards) كأنماط لأسماء الملفات. يوثق دليل Bash المعلمات الموضعية وخطوات تقسيم الكلمات وتوسيع أسماء الملفات في shell. Bash Reference Manual: Positional Parameters and Shell Expansions

لمعالجة أسماء ملفات متعددة، ضع كل مسار بين علامتي اقتباس عند استدعاء السكريبت، واستخدم حلقة تكرار مع "$@" لكي تظل كل وسيطة متميزة ومستقلة:

for file in "$@"; do
  printf 'Received: %s\n' "$file"
done

لا تستخدم $* أو $@ بدون علامات اقتباس لهذا الغرض: فقد يؤدي ذلك إلى دمج قيم الوسائط أو تقسيمها. إذا كان السكريبت يتوقع ملفًا واحدًا فقط، فاحتفظ بالتحقق من وجود وسيطة واحدة ومرر مسارًا واحدًا مقتبسًا.

عندما يقوم AppleScript بتشغيل أمر shell

يأخذ أمر do shell script في AppleScript سلسلة نصية تحتوي على كود shell. إذا قمت بدمج مسار مباشرة في هذا الأمر، فسيتم تفسير مسار مثل /Users/sam/Quarterly Reports/report.pdf على أنه عدة كلمات في shell. توثق شركة Apple استخدام quoted form كوسيلة لإنتاج نص آمن لتفسير shell، بما في ذلك السلاسل النصية التي تحتوي على مسافات وأحرف اقتباس مضمنة. Apple: Calling Command-Line Tools

بالنسبة للمسار المعروف، قم بوضع علامات الاقتباس حوله باستخدام quoted form of قبل دمجه:

set filePath to "/Users/sam/Quarterly Reports/report.pdf"
set safePath to quoted form of filePath
do shell script "/path/to/process-file.sh " & safePath

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

set filePath to POSIX path of (choose file)
do shell script "/path/to/process-file.sh " & quoted form of filePath

يوضح مرجع AppleScript من Apple هذا النمط لمجلد تم اختياره ويشير إلى أن quoted form يتعامل أيضًا مع علامات الاقتباس المفردة المضمنة. AppleScript Language Guide: Commands Reference

معالجة الأخطاء الشائعة

إذا أفاد السكريبت بأنه تلقى وسائط متعددة، فتحقق من الأمر الذي يشغله: يجب أن يكون المسار الكامل داخل زوج واحد من علامات الاقتباس. وإذا تلقى مسارًا يحتوي على علامات اقتباس حرفية، فتحقق مما إذا كانت هذه العلامات قد تم تضمينها في سلسلة اسم الملف نفسها؛ يجب أن تعمل علامات اقتباس shell على تجميع الوسيطة، لا أن تصبح جزءًا من قيمتها.

إذا استقبل السكريبت المسار بشكل صحيح ولكن فشل أمر لاحق، فتحقق من وسائط ذلك الأمر أيضًا. وضع علامات اقتباس في أمر التشغيل لا يحمي تلقائيًا متغيرًا غير موضوع بين علامات اقتباس داخل السكريبت: استخدم صيغًا مثل some-command "$file". بالنسبة إلى AppleScript، لا تضف علامات اقتباس حول المسار يدويًا؛ بل ادمج quoted form of للمسار مع أمر shell. يعالج هذا الأمر تحليل shell فقط، ولا يضمن وجود مسار غير صالح، أو يمنح حق الوصول إلى الملف، أو يضمن أن البرنامج المستدعى يقبل الملف.

المصادر