المسارات
/
Bash
Bash
/
المنهج
/
المستندات المضمّنة
ال

المستندات المضمّنة في Bash

{zero: "لا توجد تمارين", one: "1 تمرين", two: "تمرينان", few: "%{count} تمارين", many: "%{count} تمرينًا", other: "%{count} تمرين"}

نبذة عن المستندات المضمّنة

في كتابة سكربتات Bash، يعيد "مستند Here" (أو "heredoc") توجيه عدة أسطر من المدخلات إلى أمر أو برنامج، كأنك تكتبها مباشرة في الطرفية. إنها أداة قوية لتضمين نص متعدد الأسطر داخل سكربتاتك دون الحاجة إلى ملفات خارجية أو معالجة معقدة للسلاسل النصية.

الميزات الأساسية والصياغة

  1. المحدِّد: يبدأ مستند Here بالعامل << متبوعًا بكلمة محدِّدة (يُسمّى هذا غالبًا "العلامة" أو "المُنهي"). يمكن أن يكون هذا المحدِّد أي كلمة تختارها، لكن من الشائع استخدام شيء مثل EOF أو END أو TEXT للتوضيح. ولجعل الكود أكثر قابلية للقراءة، يمكنك استخدام كلمة وصفية كمحدِّد، مثل END_INSTALLATION_INSTRUCTIONS.

  2. المحتوى: بعد << DELIMITER الأولي، تكتب المحتوى الذي تريد إعادة توجيهه. يمكن أن يكون هذا عدة أسطر من النص أو الكود أو أي شيء آخر.

  3. الإنهاء: ينتهي مستند Here عندما تظهر الكلمة المحدِّدة مرة أخرى في سطر بمفردها، دون أي مسافات بادئة أو لاحقة.

الصياغة الأساسية

command << DELIMITER
  Content line 1
  Content line 2
  ...
  Content line N
DELIMITER

كيف يعمل

  • يقرأ Bash كل الأسطر بين بداية << DELIMITER ونهاية DELIMITER.
  • يربط Bash هذا المحتوى بالمدخل القياسي للأمر.
  • يعالج الأمر هذا المدخل كما لو كان قادمًا من لوحة المفاتيح.

المثال 1: إخراج نص بسيط

cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF

الإخراج:

This is the first line.
This is the second line.
This is the third line.

في هذا المثال:

  • الأمر هو cat.
  • << EOF يبدأ مستند Here مع EOF كمحدِّد.
  • الأسطر الثلاثة من النص هي المحتوى.
  • EOF في سطر بمفرده ينهي مستند Here.
  • ثم يُخرج cat المحتوى الذي استقبله.

المثال 2: الاستخدام مع wc (عدّ الكلمات)

wc -l << END
Line 1
Line 2
Line 3
END

الإخراج:

3

هنا، يحسب wc -l عدد الأسطر. ويوفّر مستند Here الأسطر الثلاثة كمدخل.

المثال 3: تمرير البيانات إلى سكربت

السكربت:

#!/usr/bin/env bash

# Script to process input
while IFS= read -r line; do
  echo "Processing: $line"
done

استدعِ السكربت من موجّه bash التفاعلي باستخدام مستند Here:

./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA

الإخراج:

Processing: Item 1
Processing: Item 2
Processing: Item 3

الصيغ المتنوعة والميزات المتقدمة

المحتوى الحرفي

ينفّذ Bash توسيع المتغيرات واستبدال الأوامر والتوسيع الحسابي داخل مستند Here. بهذا المعنى، تتصرّف مستندات Here مثل السلاسل النصية المحاطة بعلامات اقتباس مزدوجة.

cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF

الإخراج:

The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4

عندما يكون المحدِّد بين علامات اقتباس (باستخدام علامات اقتباس مفردة أو مزدوجة)، تُمنع هذه التوسيعات. ويُؤخذ المحتوى حرفيًا. وهذا يشبه السلاسل النصية المحاطة بعلامات اقتباس مفردة.

cat << 'EOF'
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
EOF

الإخراج:

The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))

إزالة علامات الجدولة البادئة

إذا استخدمت <<- (مع شرطة لاحقة) بدلًا من <<، فسيُزيل Bash أي علامات جدولة بادئة من كل سطر في مستند Here. هذا مفيد لعمل إزاحة بادئة لمحتوى مستند Here داخل سكربتك دون التأثير على الإخراج.

# Note, the leading whitespace is tab characters only, not spaces!
# The ending delimiter can have leading tabs as well.
cat <<- END
	This line has 1 leading tab.
	  This line has a leading tab and some spaces.
		This line 2 leading tabs.
	END

يُطبع الإخراج بعد إزالة جميع علامات الجدولة البادئة:

This line has 1 leading tab.
    This line has a leading tab and some spaces.
This line 2 leading tabs.
Caution

لا يوصي المؤلف بهذا الاستخدام. فرغم أنه قد يحسّن قابلية قراءة السكربت،

  1. من السهل أن تستبدل علامات الجدولة بالمسافات عن غير قصد (وقد يفعل محرّرك هذا تلقائيًا)، و
  2. من الصعب ملاحظة الفرق بين المسافات وعلامات الجدولة.

متى تستخدم مستندات Here

  • المدخلات متعددة الأسطر: عندما تحتاج إلى تمرير عدة أسطر من النص إلى أمر.
  • ملفات الإعدادات: تضمين مقتطفات إعدادات صغيرة داخل سكربت.
  • توليد الكود: إنشاء كود في أثناء التشغيل داخل سكربت.
  • محاكاة التفاعلات: محاكاة مدخلات المستخدم للبرامج التفاعلية.
  • تجنّب الملفات الخارجية: عندما تريد تفادي إنشاء ملفات مؤقتة.

قد يكون الاستخدام النموذجي هو توفير نص مساعدة:

#!/usr/bin/env bash

usage() {
    cat << END_USAGE
Refresh database tables.

usage: ${0##*/} [-h|--help] [-A|--no-archive]

where: --no-archive flag will _skip_ the archive jobs
END_USAGE
}

# ... parsing command line options here ...

if [[ $flag_help == "true" ]]; then
  usage
  exit 0
fi

العيوب المحتملة

  • قد تجعل المستندات المضمّنة الكبيرة الكود أصعب في القراءة. وقد يكون من الأفضل نشر سكربتك مع التوثيق في ملفات منفصلة.
  • قد تقطع مستندات Here تدفّق الكود. قد تكون في قسم متداخل بعمق من الكود عندما تريد تمرير بعض النص إلى برنامج. وقد تبدو إزاحة مستند Here ناشزة مقارنة بالكود المحيط.

نصوص Here

مثل مستندات Here، توفّر نصوص Here (أو "herestrings") مدخلات إلى أمر. لكن بينما تُقدَّم مستندات Here ككتلة نصية، تُقدَّم نصوص Here كسلسلة نصية واحدة. تستخدم نصوص Here الصياغة <<< "text".

tr 'a-z' 'A-Z' <<< "upper case this string"

الإخراج:

UPPER CASE THIS STRING

على خلاف مستندات Here، لا حاجة إلى محدِّد إنهاء.

لماذا تستخدم نصوص Here؟

يمكن استخدام خط أنابيب بدلًا من نص Here:

echo "upper case this string" | tr 'a-z' 'A-Z'

فلماذا تستخدم نص Here؟

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

some_long_running_calculation | first_command
some_long_running_calculation | second_command

النهج الأكثر كفاءة هو التقاط مخرَج العملية الحسابية (باستخدام استبدال الأوامر)، واستخدام نصوص Here لتوفير المدخلات إلى الأمرين التاليين:

result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"

إليك تطبيقًا واقعيًا لهذا المثال:

  • التقاط استجابة JSON لطلب REST API (المقسّم إلى صفحات)،
  • تمرير بيانات JSON إلى برنامج jq لتحليل النتائج وإخراجها إلى ملف، ثم
  • تمرير بيانات JSON إلى برنامج jq آخر لتحديد عنوان URL للطلب التالي.
# initialize the output CSV file
echo "ID,VALUE" > data.csv

url='https//example.com/api/query?page=1'

while true; do
  json=$( curl "$url" )

  # convert the results part of the response into CSV
  jq -r '.results[] | [.id, .value] | @csv' <<< "$json"

  # get the URL for the next page
  url=$( jq -r '.next_url // ""' <<< "$json" )
  if [[ "$url" == "" ]]; then
    break
  fi
done >> data.csv

لاحظ موضع إعادة توجيه الإخراج. سيُلحق كل إخراج حلقة while بالملف data.csv.

مستندات Here ونصوص Here كإعادة توجيه

لأنها مجرد أشكال من إعادة التوجيه، يمكن دمجها مع عمليات إعادة توجيه أخرى:

cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT

awk '...' <<< "$my_var" >> result.csv

الخلاصة

مستندات Here (أو "heredocs") طريقة مرنة ومريحة لإدارة المدخلات متعددة الأسطر في سكربتات Bash. فهي تبسّط عملية تضمين النصوص والبيانات مباشرة داخل سكربتاتك، فتجعلها أكثر اكتفاءً ذاتيًا وأسهل في القراءة.

نصوص Here (أو "herestrings") تشبه مستندات Here، لكنها تقدّم صياغة أبسط وأكثر ديناميكية.

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة