في كتابة سكربتات Bash، يعيد "مستند Here" (أو "heredoc") توجيه عدة أسطر من المدخلات إلى أمر أو برنامج، كأنك تكتبها مباشرة في الطرفية. إنها أداة قوية لتضمين نص متعدد الأسطر داخل سكربتاتك دون الحاجة إلى ملفات خارجية أو معالجة معقدة للسلاسل النصية.
المحدِّد: يبدأ مستند Here بالعامل << متبوعًا بكلمة محدِّدة (يُسمّى هذا غالبًا "العلامة" أو "المُنهي").
يمكن أن يكون هذا المحدِّد أي كلمة تختارها، لكن من الشائع استخدام شيء مثل EOF أو END أو TEXT للتوضيح.
ولجعل الكود أكثر قابلية للقراءة، يمكنك استخدام كلمة وصفية كمحدِّد، مثل END_INSTALLATION_INSTRUCTIONS.
المحتوى: بعد << DELIMITER الأولي، تكتب المحتوى الذي تريد إعادة توجيهه.
يمكن أن يكون هذا عدة أسطر من النص أو الكود أو أي شيء آخر.
الإنهاء: ينتهي مستند Here عندما تظهر الكلمة المحدِّدة مرة أخرى في سطر بمفردها، دون أي مسافات بادئة أو لاحقة.
command << DELIMITER
Content line 1
Content line 2
...
Content line N
DELIMITER
<< DELIMITER ونهاية DELIMITER.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 المحتوى الذي استقبله.wc (عدّ الكلمات)wc -l << END
Line 1
Line 2
Line 3
END
الإخراج:
3
هنا، يحسب wc -l عدد الأسطر.
ويوفّر مستند Here الأسطر الثلاثة كمدخل.
السكربت:
#!/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.
لا يوصي المؤلف بهذا الاستخدام. فرغم أنه قد يحسّن قابلية قراءة السكربت،
قد يكون الاستخدام النموذجي هو توفير نص مساعدة:
#!/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 (أو "herestrings") مدخلات إلى أمر.
لكن بينما تُقدَّم مستندات Here ككتلة نصية، تُقدَّم نصوص Here كسلسلة نصية واحدة.
تستخدم نصوص Here الصياغة <<< "text".
tr 'a-z' 'A-Z' <<< "upper case this string"
الإخراج:
UPPER CASE THIS STRING
على خلاف مستندات 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"
إليك تطبيقًا واقعيًا لهذا المثال:
# 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.
لأنها مجرد أشكال من إعادة التوجيه، يمكن دمجها مع عمليات إعادة توجيه أخرى:
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، لكنها تقدّم صياغة أبسط وأكثر ديناميكية.