الفرق بين المراجعتين لصفحة: «Bash/shell expansion»
أسامه-دمراني (نقاش | مساهمات) إدخال 2.0 محتوى أولي |
أسامه-دمراني (نقاش | مساهمات) مراجعة 6: إضافة تصانيف |
||
(9 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:التوسعات في Bash}}</noinclude> | <noinclude>{{DISPLAYTITLE:التوسعات في Bash}}</noinclude> | ||
بعد تقسيم الأمر في Bash إلى وحدات (Tokens) -انظر [[Bash/building blocks#.D8.A7.D9.84.D8.A8.D9.86.D9.8A.D8.A9 .D8.A7.D9.84.D9.84.D8.BA.D9.88.D9.8A.D8.A9 .D9.84.D9.84.D8.B5.D8.AF.D9.81.D8.A9 .28Shell Syntax.29|وحدات البناء الأساسية في Bash، البنية اللغوية للصدفة]]- فإن تلك الوحدات توسَّع (expanded) أو تُستبيَن (resolved)، وسنفصّل الآن تلك التوسعات وفقًا لترتيب كل منها، ثم بعد إتمام جميع التوسعات تُنفّذ عملية حذف الاقتباسات. | |||
==توسُّع القوس المعقوف {}== | |||
توسع القوس المعقوف هو آلية يمكن من خلالها إنشاء نصوص عشوائية (arbitrary strings)، إذ تأخذ الأنماط (patterns) التي سيُنفَّذ عليها توسع القوس المعقوف باستهلال اختياري (optional preamble) متبوع بسلسلة من النصوص تفصل بين كل منها فاصلة، وتكون تلك النصوص بين قوسين معقوفين <code>{}</code> ثم تأتي بعد ذلك حاشية (postscript) اختيارية أيضًا. ويوضع الاستهلال في بداية كل نص داخل القوس -بعد التوسع- ثم تُلحَق الحاشية بنهاية كل نص أيضًا، وذلك بالترتيب من اليسار إلى اليمين. | |||
قد تتداخل توسعات القوس المعقوف لكن ذلك لا يعني أن النتائج يمكن تصنيفها، بل يظل الترتيب كما هو من اليسار إلى اليمين، انظر المثال التالي للتوضيح:<syntaxhighlight lang="bash"> | |||
hsoub ~> echo sp{el,il,al}l | hsoub ~> echo sp{el,il,al}l | ||
spell spill spall | spell spill spall | ||
</syntaxhighlight>يُنفَّذ توسع القوس المعقوف قبل أي توسع | </syntaxhighlight>يُنفَّذ توسع القوس المعقوف قبل أي توسع آخر، ويُحتفظ في النتيجة بأي محارف ذات معاني خاصة بالنسبة للتوسعات الأخرى، ذلك أن هذ التوسع نصي حصرًا فلا تفسر Bash البنية اللغوية لسياق التوسع ولا للنص الذي بين القوسين المعقوفين. كذلك فإن النص <code>}$</code> ليس صالحًا لتوسع القوس المعقوف من أجل تجنب التعارض الذي قد يحدث. | ||
إن | ويجب أن يحتوي توسع القوس المعقوف على قوسين معقوفيْن بدون علامات اقتباس حول أي منهما وفاصلة <code>,</code> واحدة على الأقل لا تكون بين علامات اقتباس أيضًا، وأي توسّع للقوس المعقوف يكون على خلاف تلك الصيغة فإنه يُترك دون تغيير. | ||
==توسع المَدَّة (~)== | |||
إن بدأت كلمة بمحرف المَدَّة <code>~</code> دون علامات اقتباس فإن كل المحارف حتى أول شرطة مائلة <code>/</code> بدون علامات اقتباس -أو كل المحارف إن لم توجد شرطة مائلة بدون علامات اقتباس- تُعد مقدمة للمدَّة (tilde-prefix) ، وتُعامل المحارف التي تأتي بعد المدة في '''مقدمة المدة''' (tilde-prefix) على أنها اسم لتسجيل الدخول، وذلك إن لم يوضع أي محرف من محارف '''مقدمة المَدَّة''' داخل علامتي اقتباس، فإن كان اسم تسجيل الدخول ذاك فارغًا فإن المدة تُستبدل بقيمة متغير <code>HOME</code>، فإن كان متغير <code>HOME</code> غير مضبوط على أي قيمة فإن مجلد home الخاص بالمستخدم الذي يُنفّذ الصدفةَ يُستخدم مكانه، وإلا فإن مقدمة المَدة تُستبدل بمجلد المنزل المرتبط باسم تسجيل الدخول. | |||
إن كان اسم تسجيل الدخول غير | إن كانت '''مقدمة المدة''' هي <code>+~</code> فإن قيمة المتغير <code>PWD</code> تحل محلها، أما إن كانت '''مقدمة المدة''' <code>-~</code> فإن قيمة المتغير <code>OLDPWD</code> هي التي تحل محلها، في حال ضبط قيمة ما لذلك المتغير. وإن كانت المحارف التي تلي المدة في '''مقدمة المدة''' تتكون من عدد N (قد) يسبقه <code>+</code> أو <code>-</code> فإن '''مقدمة المدة''' تُستبدل بالعنصر الذي يماثلها من مكدس المجلدات (Directory Stack)، كما سيُعرض كوسيط في أمر <code>dirs</code> الذي تستدعيه المحارف التي تلي المَدّة في '''مقدمة المدة'''، فإن كانت المحارف التي تلي المَدة تتكون من عدد بدون إشارة موجب أو سالب قبله فسيُفترض أن هذا العدد موجب. كذلك إن كان اسم تسجيل الدخول غير صالح، أو فشلَ توسع المدة فإن الكلمة تترك دون تغيير. | ||
تُفحص تعيينات المتغيرات بعد <code>:</code> أو <code>=</code> مباشرة بحثًا عن مقدمات للمدة لا تكون بين علامات اقتباس، وتُوسّع المدة في تلك الحالات، وعليه يمكن استخدام أسماء ملفات فيها محرف المدة في التعيينات التي تكون لمتغيرات <code>PATH</code> و <code>MAILPATH</code> و <code>CDPATH</code>، وتُعيّن الصدفة القيمةَ الموسعة. | |||
مثال:<syntaxhighlight lang="bash"> | مثال:<syntaxhighlight lang="bash"> | ||
hsoub ~> export PATH="$PATH:~/testdir" | hsoub ~> export PATH="$PATH:~/testdir" | ||
</syntaxhighlight>سيوسَّع testdir/~ إلى HOME/testdir$، لذا إن كان HOME$ هو var/home/hsoub/ فإن مجلد var/home/hsoub/testdir/ يضاف إلى محتويات متغير PATH. | </syntaxhighlight>سيوسَّع <code>testdir/~</code> إلى <code>HOME/testdir$</code>، لذا إن كان <code>HOME$</code> هو <code>var/home/hsoub/</code> فإن مجلد <code>var/home/hsoub/testdir/</code> يضاف إلى محتويات متغير <code>PATH</code>. | ||
==معامل الصدفة وتوسع المتغير== | |||
== معامل الصدفة وتوسع المتغير == | يسبق محرف <code>$</code> توسع المعامِل (parameter expansion) وإحلال الأوامر (command substitution) والتوسعات الحسابية (arithmetic expansion)، قد يكون اسم المعامِل الذي سيوسَّع -أو رمزه- بين قوسين معقوفيْن وذلك اختياري لكنه يحمي المتغير الذي سيوسَّع من المحارف التي تليه والتي قد تُفسر على أنها جزء من الاسم. وحين تُستخدم الأقواس المعقوفة فإن الطرف الثاني من القوس هو أول <code>{</code> غير مهرَّب بواسطة شرطة مائلة خلفية <code>\</code> أو بين نص مقتبَس أو داخل توسع حسابي مضمَّن (embedded arithmetic expansion) أو أمر تم إحلاله أو توسُّع لمعامِل. | ||
والصورة الأساسية لتوسع المعامِل هي <code>{PARAMETER}$</code>، وتُستبدل قيمة <code>PARAMETER</code>، وتكون الأقواس ضرورية حين يكون <code>PARAMETER</code> معامِلًا موضعيًا بأكثر من رقم واحد أو حين يُتبع <code>PARAMETER</code> بمحرَف لن يُفسر كجزء من الاسم. | |||
وإن كان أول محرف من المعامِل <code>PARAMETER</code> علامة تعجب فإن <code>Bash</code> تستخدم قيمة المتغير المتكون من بقية <code>PARAMETER</code> كاسم للمتغير، ويوسَّع ذلك المتغير وتُستخدم تلك القيمة في بقية الاستبدال بدلًا من قيمة <code>PARAMETER</code> نفسه، ويُعرف هذا باسم التوسع غير المباشر، على خلاف التوسع المباشر المنتشر والذي يحدث في أبسط الحالات مثل الحالة السابقة أو هذه الحالة:<syntaxhighlight lang="bash"> | |||
hsoub ~> echo $SHELL | hsoub ~> echo $SHELL | ||
/bin/bash | /bin/bash | ||
سطر 48: | سطر 35: | ||
hsoub ~> echo ${!N*} | hsoub ~> echo ${!N*} | ||
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH | NNTPPORT NNTPSERVER NPX_PLUGIN_PATH | ||
</syntaxhighlight>لاحظ أن هذا يختلف عن *echo $N | </syntaxhighlight>لاحظ أن هذا يختلف عن <code>*echo $N</code>، تسمح بنية <code>{VAR:=value}$</code> بإنشاء المتغير المذكور إن لم يكن قد أنشئ من قبل، انظر المثال التالي للتوضيح:<syntaxhighlight lang="bash"> | ||
تسمح بنية | |||
hsoub ~> echo $HSOUB | hsoub ~> echo $HSOUB | ||
hsoub ~> echo ${HSOUB:=Hsoub} | hsoub ~> echo ${HSOUB:=Hsoub} | ||
Hsoub | Hsoub | ||
</syntaxhighlight>قد لا تُعيَّن المعاملات الخاصة -ضمن معاملات موضعية أخرى- بهذه الطريقة. | </syntaxhighlight>قد لا تُعيَّن المعاملات الخاصة -ضمن معاملات موضعية أخرى- بهذه الطريقة. سنناقش استخدام الأقواس المعقوفة في معاملة المتغيرات في [[Bash/more on variables|المزيد حول المتغيرات في Bash]]، ستجد معلومات أكثر كذلك في صفحات دليل <code>info</code>. | ||
==إحلال الأوامر== | |||
سنناقش استخدام الأقواس المعقوفة في معاملة المتغيرات في [[Bash/more on variables|المزيد حول المتغيرات في Bash]]، ستجد معلومات أكثر كذلك | يسمح إحلال الأوامر لخرج أمر ما أن يحِل محل الأمر نفسه، ويحدث إحلال الأوامر حين يكون أمر ما على هذه الصورة: <code>(الأمر)$</code> أو على هذه الصورة باستخدام الفاصلة العليا المائلة `: <code>`الأمر`</code> | ||
== | |||
يسمح | |||
(الأمر)$ | |||
تنفّذ Bash التوسع بتنفيذ الأمر واستبدال إحلال الأمر بالخرج العادي للأمر مع حذف أي أسطر جديدة تابعة (trailing newlines)، ولا تُحذف الأسطر الجديدة المضمنة لكن قد تُحذف أثناء انقسام الكلمات.<syntaxhighlight lang="bash"> | |||
hsoub ~> echo `date` | hsoub ~> echo `date` | ||
Thu Feb 6 10:06:20 CET 2003 | Thu Feb 6 10:06:20 CET 2003 | ||
</syntaxhighlight> | </syntaxhighlight>تحتفظ الشرطة المائلة الخلفية <code>\</code> بمعناها الحرفي عند استخدام صيغة الاقتباس الخلفي القديمة للإحلال (backquoted form of substitution)، إلا حين تُتبَع إتباعها بعلامة <code>$</code> أو <code>`</code> أو <code>\</code>، ويُنهي إحلالَ الأمرِ أولُ فاصلة عليا مائلة <code>`</code> (backtick) غير مسبوقة بشرطة خلفية مائلة <code>\</code> (backslash)، وعند استخدام صيغة <code>(COMMAND)$</code> فإن كل المحارف بين القوسين تُعد مكونة للأمر ولا يعامل أي منها بشكل خاص. | ||
كذلك يمكن أن تتداخل إحلالات الأوامر، ولكي تصنع تداخلًا أثناء استخدام صيغة الاقتباس الخلفي، اسبق الفواصل العليا المائلة بشَرّط مائلة خلفية. لا تنقسم الكلمات إن ظهر الإحلال بين علامتي اقتباس مزدوجة، وتوسَّع أسماء الملفات على النتائج. | |||
==التوسع الحسابي== | |||
يسمح التوسع الحسابي بتقييم تعبير حسابي وإحلال نتيجته، وصيغة التوسع الحسابي هي <code>((التعبير الحسابي))$</code>، ويعامل التعبير كما لو كان بين علامات اقتباس مزدوجة، لكن لا تُعامل علامة الاقتباس المزدوجة داخل القوسين . وتخضع كل الوحدات داخل التعبير لتوسع المعامل وإحلال الأمر وإزالة الاقتباس، كما يمكن أن تتداخل الإحلالات الحسابية. | |||
يتم تقييم التعبيرات الحسابية في أرقام ثابتة العرض بدون تفقد للفائض رغم أن القسمة على الصفر | يتم تقييم التعبيرات الحسابية في أرقام ثابتة العرض (fixed-width integers) بدون تفقد للفائض رغم أن القسمة على الصفر تُلتقط وتعرّف على أنها خطأ، والمعامِلات (operators) هي نفسها تقريبًا التي في لغة C البرمجية. ومن أجل تقليل الأولوية فإن القائمة تكون مشابهة لهذه: | ||
جدول 3.4 : المعاملات الحسابية | '''جدول 3.4 : المعاملات الحسابية''' | ||
{| class="wikitable" | {| class="wikitable" | ||
|المعامِل | |'''المعامِل''' | ||
|المعنى | |'''المعنى''' | ||
|- | |- | ||
|< | |<code>++VAR</code> و <code>--VAR</code> | ||
|الزيادة اللاحقة للمتغير والتناقص اللاحق له | |الزيادة اللاحقة للمتغير والتناقص اللاحق له | ||
|- | |- | ||
|VAR++ و VAR-- | |<code>VAR++</code> و <code>VAR--</code> | ||
|الزيادة السابقة للمتغير والتناقص السابق له | |الزيادة السابقة للمتغير والتناقص السابق له | ||
|- | |- | ||
|< | |<code>-</code> و <code>+</code> | ||
|إشارتي ناقص وزائد أحاديتين | |إشارتي ناقص وزائد أحاديتين | ||
|- | |- | ||
|! و ~ | |<code>!</code> و <code>~</code> | ||
|النفي المنطقي (Logical Negation) والنفي البِتِّي (Bitwise Negation) | |النفي المنطقي (Logical Negation) والنفي البِتِّي (Bitwise Negation) | ||
|- | |- | ||
|** | |<code>**</code> | ||
|الأُسِّية -رفع القوة الجبرية- | |الأُسِّية -رفع القوة الجبرية- | ||
|- | |- | ||
|*و / و % | |<code>*</code> و <code>/</code> و <code>%</code> | ||
|الضرب والقسمة والباقي (remainder) | |الضرب والقسمة والباقي (remainder) | ||
|- | |- | ||
|< | |<code>+</code> و <code>-</code> | ||
|الجمع والطرح | |الجمع والطرح | ||
|- | |- | ||
|<< و >> | |<code><<</code> و <code>>></code> | ||
|النقلات البِتِّية (bitwise shifts) -على مستوى البِتّ bit- لليمين واليسار | |النقلات البِتِّية (bitwise shifts) -على مستوى البِتّ bit- لليمين واليسار | ||
|- | |- | ||
|<= و >= و < و > | |<code><=</code> و <code>>=</code> و <code><</code> و <code>></code> | ||
|معامِلات المقارنة | |معامِلات المقارنة | ||
|- | |- | ||
|== و != | |<code>==</code> و <code>!=</code> | ||
|التساوي وعدم التساوي | |التساوي وعدم التساوي | ||
|- | |- | ||
|& | |<code>&</code> | ||
|بوابة AND البِتِّية | |بوابة AND البِتِّية | ||
|- | |- | ||
|^ | |<code>^</code> | ||
|بوابة OR البِتِّية الحصرية | |بوابة OR البِتِّية الحصرية | ||
|- | |- | ||
|<nowiki>|</nowiki> | |<code><nowiki>|</nowiki></code> | ||
|بوابة OR البِتِّية | |بوابة OR البِتِّية | ||
|- | |- | ||
|&& | |<code>&&</code> | ||
|بوابة AND | |بوابة AND | ||
|- | |- | ||
|<nowiki>||</nowiki> | |<code><nowiki>||</nowiki></code> | ||
|بوابة OR | |بوابة OR | ||
|- | |- | ||
|expr ? expr : expr | |<code>expr ?</code> <code>expr :</code> <code>expr</code> | ||
|التقييم الشرطي | |التقييم الشرطي | ||
|- | |- | ||
|< | |<code>=</code> و <code>*=</code> و <code>/=</code> و <code>%=</code> و <code>+=</code> و <code>-=</code> و <code><<=</code> و <code>>>=</code> و <code>&=</code> و <code>^=</code> و <code><nowiki>|=</nowiki></code> | ||
|التعيينات | |التعيينات | ||
|- | |- | ||
|, | |<code>,</code> | ||
|الفاصلة التي تفصل بين التعبيرات | |الفاصلة التي تفصل بين التعبيرات | ||
|} | |}قد يُشار إلى متغيرات الصدفة بالاسم داخل التعبير بدون استخدام بنية التوسع اللغوية (expansion syntax)، وتُقيَّم قيمة المتغير كتعبير حسابي حين يشار إليها. كذلك يُسمح بمتغيرات الصدفة كعوامل (operands)، ولا يحتاج متغير الصدفة أن تكون خاصيته الرقمية (integer attribute) نشطة عند الإشارة إليه. | ||
تُفسَّر الثوابت التي تبدأ بصفر كأرقام ثُمانيّة (وفق النظام الثُماني)، أما <code>0x</code> و <code>0X</code> فتدل على النظام السداسي العشري (hexadecimal). وتأخذ الأرقام التي ليست من هذه ولا تلك صيغة <code>BASE'#']N]</code>، حيث يكون <code>BASE</code> رقمًا عشريًا بين 2 و 64 ممثلًا القاعدة الحسابية، ويكون <code>N</code> رقمًا في تلك القاعدة. | |||
ويُستخدم رقم 10 كافتراضي إن أهمل الرقم الممثل للقاعدة الحسابية كدلالة على النظام العشري، وتُمثل الأرقام الأكبر من 9 بأحرف من الحالة الصغرى (lowercase)، والكبرى (uppercase)، و "@" و"_"، بذلك الترتيب. أما إن كان رقم القاعدة <code>BASE</code> أقل من أو يساوي 36 فيمكن استخدام أحرف من الحالتين بالتبادل لتمثيل أرقام بين 10 و35. وتُقيَّم المعامِلات بأولوية الترتيب، وتُقيَّم التعبيرات الفرعية (sub-expressions) التي في الأقواس أولًا وربما تلغي قاعدة الأولوية المذكورة قبل قليل. | |||
وينبغي على | وينبغي على من يستخدم Bash أن يحاول استخدام البنية اللغوية للتعبير باستخدام أقواس مربعة كلما أمكن: <code>[التعبير]$</code>، لكن على أي حال سيحسب ذلك نتيجة التعبير فقط ولن يُجري أي اختبارات:<syntaxhighlight lang="bash"> | ||
[التعبير]$ | |||
لكن على أي حال | |||
hsoub ~> echo $[365*24] | hsoub ~> echo $[365*24] | ||
8760 | 8760 | ||
</syntaxhighlight>انظر المقارنات الرقمية في [[Bash/introduction to if|مقدمة إلى if في Bash]] لترى أمثلة عملية في برامج الصدفة. | </syntaxhighlight>انظر المقارنات الرقمية في [[Bash/introduction to if|مقدمة إلى if في Bash]] لترى أمثلة عملية في برامج الصدفة. | ||
==إحلال العمليات== | |||
إحلال العمليات مدعوم في الأنظمة التي تدعم الأنابيب المسماة (FIFOs- First In First Out) أو أسلوب <code>dev/fd/</code> في تسمية الملفات، وتكون صيغته كالتالي: <code>(LIST)></code> أو <code>(LIST)<</code>. | |||
وتجري عملية <code>LIST</code> بحيث تكون مدخلاتها ومخرجاتها متصلة بأنبوب مُسمَّى (FIFO) أو ملف ما في <code>dev/fd/</code>، ويُمرر اسم هذا الملف كوسيط إلى الأمر الحالي كنتيجة للتوسع. وإن استُخدمَت صيغة <code>(LIST)<</code> فإن الكتابة إلى الملف ستزود القائمة <code>LIST</code> بالمدخلات، أما إن استُخدِمت صيغة <code>(LIST)></code> فيجب أن يُقرأ الملف الذي مُرِّر كوسيط من أجل الحصول على خرج القائمة <code>LIST</code>. لاحظ أنه يجب ألا تظهر مسافات بين علامات <code><</code> أو <code>></code> و القوس الأيسر، وإلا فإن البنية ستفسر على أنها إعادة توجيه. | |||
== انقسام الكلمات == | يُنفذ إحلال العمليات بالتزامن مع توسع المعامل والمتغير، وإحلال الأوامر والتوسع الحسابي كلما أمكن. انظر [[Bash/catching user input#.D8.A5.D8.B9.D8.A7.D8.AF.D8.A9 .D8.A7.D9.84.D8.AA.D9.88.D8.AC.D9.8A.D9.87 .D9.88.D9.88.D8.A7.D8.B5.D9.81.D8.A7.D8.AA .D8.A7.D9.84.D9.85.D9.84.D9.81.D8.A7.D8.AA|إعادة التوجيه وواصفات الملفات]]. | ||
تمسح الصدفة نتائج توسع | ==انقسام الكلمات== | ||
تمسح الصدفة نتائج توسع المعاملات وإحلال الأوامر والتوسعات الحسابية التي لم تقع داخل علامتي اقتباس مزدوجة بحثًا عن انقسام للكلمات. وتعامل الصدفة كل محرف من فاصل الحقل الداخلي (internal field separator) أو <code>IFS$</code> كمحرف محدِّد (delimiter) ، وتقسِّم نتائج التوسعات الأخرى في كلمات عن تلك المحارف، وفي حالة عدم ضبط الفاصل IFS أو كانت قيمته الافتراضية هي <code>"'<مسافة (space)><جدول(tab)><سطر جديد (newline)>'"</code> تحديدًا، فإن أي تسلسل لمحارف IFS يعمل لتحديد الكلمات. | |||
ويتم تجاهل تسلسل محارف المسافات البيضاء <code>المسافة(space)</code> و<code>الجدول(tab)</code> في بداية ونهاية الكلمة إن كانت قيمة IFS خلاف القيمة الافتراضية، طالما أن محرف المسافة البيضاء يكون في قيمة IFS (محرف مسافة بيضاء لمتغير IFS). | |||
وأي محرف في متغير IFS ليس | وأي محرف في متغير IFS ليس بمحرف مسافة بيضاء فإنه يحدِّد حقلًا، وكذلك أي محارف مسافات بيضاء في أي IF قريب (IF- Internal Field)، ويُعامَل تسلسل محارف المسافات البيضاء للفاصل IFS كمحدِّد أيضًا، وأما إن كانت قيمة IFS فارغة فلا يحدث انقسام للكلمات. | ||
يُحتفظ بالوسائط الفارغة الصريحة (<code>""""</code> أو <code>"<nowiki>''</nowiki>"</code>) وتُحذف الوسائط الضمنية غير المقتبَسة الناتجة من توسع المعامِلات التي ليس لها قيَم، وينتج نص فارغ ويُحتفظ به عند توسع معامل ليس له قيَم بين علامات اقتباس مزدوجة.<blockquote>'''التوسع وانقسام الكلمات'''</blockquote><blockquote>إن لم يحدث توسع فلا يُنفذ أي انقسام.</blockquote> | |||
==توسع أسماء الملفات== | |||
تمسح Bash كل كلمة بعد انقسام الكلمات ما لم يُحدد خيار <code>f-</code> بحثًا عن محارف <code>*</code> و <code>?</code> و <code>]</code> (انظر [[Bash/debugging Bash scripts#.D8.AA.D9.86.D9.82.D9.8A.D8.AD .D8.A3.D8.AC.D8.B2.D8.A7.D8.A1 .D9.85.D9.86 .D8.A7.D9.84.D8.B5.D8.AF.D9.81.D8.A9|تنقيح أجزاء من الصدفة]])، فإن لم يظهر أي من تلك المحارف فتُعد الكلمة نمطًا (<code>PATTERN</code>) وتستبدل بقائمة من أسماء الملفات الموافقة للنمط مرتبة أبجديًا. | |||
فإن لم يوجد أي اسم مطابق وكان خيار الصدفة <code>nullglob</code> معطلًا فإن الكلمة تترك كما هي. وإن ضُبط خيار <code>nullglob</code> ولم توجد تطابقات فإن الكلمة تُحذف. وإن كان خيار <code>nocaseglob</code> مفعلًا فيُنفَّذ التطابق دون النظر لحالة المحارف الأبجدية. | |||
فإن لم | وحين يُستخدم نمط لتوليد اسم ملف فإن محرف <code>.</code> في بداية اسم الملف أو بعد شرطة مائلة مباشرة يجب أن يُطابَق صراحةً (explicitly) ما لم يحدد خيار <code>dotglob</code>. وعند مطابقة اسم ملف يجب أن تطابَق الشرطة المائلة دومًا صراحةً. قد لا تُعامل <code>.</code> بشكل خاص في بعض الحالات. | ||
قد يُستخدم متغير <code>GLOBIGNORE</code> لتقييد مجموعة أسماء الملفات التي تطابق نمطًا ما، وإن ضُبط <code>GLOBEIGNORE</code> على قيمة ما فيُحذف من قائمة أسماء الملفات المطابِقة كل اسم يطابق أحد الأنماط في <code>GLOBIGNORE</code>. | |||
ويتم تجاهل <code>.</code> و <code>..</code> كأسماء ملفات حتى لو ضُبط <code>GLOBIGNORE</code>، لكن على أي حال فإن ضبط <code>GLOBIGNORE</code> له ينشِّط خيار <code>dotglob</code>، لذا ستتطابق كل أسماء الملفات الأخرى التي تبدأ بـ <code>.</code> ، ولكي تحصل على السلوك القديم لتجاهل أسماء الملفات التي تبدأ بـ <code>.</code> ، اجعل <code>*.</code> أحد الأنماط في <code>GLOBIGNORE</code>. واعلم أن خيار <code>dotglob</code> يُعطَّل عند إلغاء ضبط <code>GLOBEIGNORE</code>. | |||
== انظر أيضًا == | |||
* [[Bash/creating and running a script|إنشاء وتشغيل برامج Bash]]. | |||
* [[Bash/script basics|أساسيات كتابة برامج Bash]]. | |||
<span> </span> | == مصادر == | ||
* <span> </span>[http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html دليل Bash للمبتدئين، صفحة التوسُّعات في Bash]. | |||
[[تصنيف:Bash]] | |||
[[تصنيف:Bash Expansion]] | |||
[[تصنيف:Bash Command Substitution]] | |||
[[تصنيف:Bash Process Substitution]] | |||
[[تصنيف:Bash File Name Expansion]] |
المراجعة الحالية بتاريخ 15:33، 6 سبتمبر 2018
بعد تقسيم الأمر في Bash إلى وحدات (Tokens) -انظر وحدات البناء الأساسية في Bash، البنية اللغوية للصدفة- فإن تلك الوحدات توسَّع (expanded) أو تُستبيَن (resolved)، وسنفصّل الآن تلك التوسعات وفقًا لترتيب كل منها، ثم بعد إتمام جميع التوسعات تُنفّذ عملية حذف الاقتباسات.
توسُّع القوس المعقوف {}
توسع القوس المعقوف هو آلية يمكن من خلالها إنشاء نصوص عشوائية (arbitrary strings)، إذ تأخذ الأنماط (patterns) التي سيُنفَّذ عليها توسع القوس المعقوف باستهلال اختياري (optional preamble) متبوع بسلسلة من النصوص تفصل بين كل منها فاصلة، وتكون تلك النصوص بين قوسين معقوفين {}
ثم تأتي بعد ذلك حاشية (postscript) اختيارية أيضًا. ويوضع الاستهلال في بداية كل نص داخل القوس -بعد التوسع- ثم تُلحَق الحاشية بنهاية كل نص أيضًا، وذلك بالترتيب من اليسار إلى اليمين.
قد تتداخل توسعات القوس المعقوف لكن ذلك لا يعني أن النتائج يمكن تصنيفها، بل يظل الترتيب كما هو من اليسار إلى اليمين، انظر المثال التالي للتوضيح:
hsoub ~> echo sp{el,il,al}l
spell spill spall
يُنفَّذ توسع القوس المعقوف قبل أي توسع آخر، ويُحتفظ في النتيجة بأي محارف ذات معاني خاصة بالنسبة للتوسعات الأخرى، ذلك أن هذ التوسع نصي حصرًا فلا تفسر Bash البنية اللغوية لسياق التوسع ولا للنص الذي بين القوسين المعقوفين. كذلك فإن النص }$
ليس صالحًا لتوسع القوس المعقوف من أجل تجنب التعارض الذي قد يحدث.
ويجب أن يحتوي توسع القوس المعقوف على قوسين معقوفيْن بدون علامات اقتباس حول أي منهما وفاصلة ,
واحدة على الأقل لا تكون بين علامات اقتباس أيضًا، وأي توسّع للقوس المعقوف يكون على خلاف تلك الصيغة فإنه يُترك دون تغيير.
توسع المَدَّة (~)
إن بدأت كلمة بمحرف المَدَّة ~
دون علامات اقتباس فإن كل المحارف حتى أول شرطة مائلة /
بدون علامات اقتباس -أو كل المحارف إن لم توجد شرطة مائلة بدون علامات اقتباس- تُعد مقدمة للمدَّة (tilde-prefix) ، وتُعامل المحارف التي تأتي بعد المدة في مقدمة المدة (tilde-prefix) على أنها اسم لتسجيل الدخول، وذلك إن لم يوضع أي محرف من محارف مقدمة المَدَّة داخل علامتي اقتباس، فإن كان اسم تسجيل الدخول ذاك فارغًا فإن المدة تُستبدل بقيمة متغير HOME
، فإن كان متغير HOME
غير مضبوط على أي قيمة فإن مجلد home الخاص بالمستخدم الذي يُنفّذ الصدفةَ يُستخدم مكانه، وإلا فإن مقدمة المَدة تُستبدل بمجلد المنزل المرتبط باسم تسجيل الدخول.
إن كانت مقدمة المدة هي +~
فإن قيمة المتغير PWD
تحل محلها، أما إن كانت مقدمة المدة -~
فإن قيمة المتغير OLDPWD
هي التي تحل محلها، في حال ضبط قيمة ما لذلك المتغير. وإن كانت المحارف التي تلي المدة في مقدمة المدة تتكون من عدد N (قد) يسبقه +
أو -
فإن مقدمة المدة تُستبدل بالعنصر الذي يماثلها من مكدس المجلدات (Directory Stack)، كما سيُعرض كوسيط في أمر dirs
الذي تستدعيه المحارف التي تلي المَدّة في مقدمة المدة، فإن كانت المحارف التي تلي المَدة تتكون من عدد بدون إشارة موجب أو سالب قبله فسيُفترض أن هذا العدد موجب. كذلك إن كان اسم تسجيل الدخول غير صالح، أو فشلَ توسع المدة فإن الكلمة تترك دون تغيير.
تُفحص تعيينات المتغيرات بعد :
أو =
مباشرة بحثًا عن مقدمات للمدة لا تكون بين علامات اقتباس، وتُوسّع المدة في تلك الحالات، وعليه يمكن استخدام أسماء ملفات فيها محرف المدة في التعيينات التي تكون لمتغيرات PATH
و MAILPATH
و CDPATH
، وتُعيّن الصدفة القيمةَ الموسعة.
مثال:
hsoub ~> export PATH="$PATH:~/testdir"
سيوسَّع testdir/~
إلى HOME/testdir$
، لذا إن كان HOME$
هو var/home/hsoub/
فإن مجلد var/home/hsoub/testdir/
يضاف إلى محتويات متغير PATH
.
معامل الصدفة وتوسع المتغير
يسبق محرف $
توسع المعامِل (parameter expansion) وإحلال الأوامر (command substitution) والتوسعات الحسابية (arithmetic expansion)، قد يكون اسم المعامِل الذي سيوسَّع -أو رمزه- بين قوسين معقوفيْن وذلك اختياري لكنه يحمي المتغير الذي سيوسَّع من المحارف التي تليه والتي قد تُفسر على أنها جزء من الاسم. وحين تُستخدم الأقواس المعقوفة فإن الطرف الثاني من القوس هو أول {
غير مهرَّب بواسطة شرطة مائلة خلفية \
أو بين نص مقتبَس أو داخل توسع حسابي مضمَّن (embedded arithmetic expansion) أو أمر تم إحلاله أو توسُّع لمعامِل.
والصورة الأساسية لتوسع المعامِل هي {PARAMETER}$
، وتُستبدل قيمة PARAMETER
، وتكون الأقواس ضرورية حين يكون PARAMETER
معامِلًا موضعيًا بأكثر من رقم واحد أو حين يُتبع PARAMETER
بمحرَف لن يُفسر كجزء من الاسم.
وإن كان أول محرف من المعامِل PARAMETER
علامة تعجب فإن Bash
تستخدم قيمة المتغير المتكون من بقية PARAMETER
كاسم للمتغير، ويوسَّع ذلك المتغير وتُستخدم تلك القيمة في بقية الاستبدال بدلًا من قيمة PARAMETER
نفسه، ويُعرف هذا باسم التوسع غير المباشر، على خلاف التوسع المباشر المنتشر والذي يحدث في أبسط الحالات مثل الحالة السابقة أو هذه الحالة:
hsoub ~> echo $SHELL
/bin/bash
أما المثال التالي فهو لتوسع غير مباشر:
hsoub ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
لاحظ أن هذا يختلف عن *echo $N
، تسمح بنية {VAR:=value}$
بإنشاء المتغير المذكور إن لم يكن قد أنشئ من قبل، انظر المثال التالي للتوضيح:
hsoub ~> echo $HSOUB
hsoub ~> echo ${HSOUB:=Hsoub}
Hsoub
قد لا تُعيَّن المعاملات الخاصة -ضمن معاملات موضعية أخرى- بهذه الطريقة. سنناقش استخدام الأقواس المعقوفة في معاملة المتغيرات في المزيد حول المتغيرات في Bash، ستجد معلومات أكثر كذلك في صفحات دليل info
.
إحلال الأوامر
يسمح إحلال الأوامر لخرج أمر ما أن يحِل محل الأمر نفسه، ويحدث إحلال الأوامر حين يكون أمر ما على هذه الصورة: (الأمر)$
أو على هذه الصورة باستخدام الفاصلة العليا المائلة `: `الأمر`
تنفّذ Bash التوسع بتنفيذ الأمر واستبدال إحلال الأمر بالخرج العادي للأمر مع حذف أي أسطر جديدة تابعة (trailing newlines)، ولا تُحذف الأسطر الجديدة المضمنة لكن قد تُحذف أثناء انقسام الكلمات.
hsoub ~> echo `date`
Thu Feb 6 10:06:20 CET 2003
تحتفظ الشرطة المائلة الخلفية \
بمعناها الحرفي عند استخدام صيغة الاقتباس الخلفي القديمة للإحلال (backquoted form of substitution)، إلا حين تُتبَع إتباعها بعلامة $
أو `
أو \
، ويُنهي إحلالَ الأمرِ أولُ فاصلة عليا مائلة `
(backtick) غير مسبوقة بشرطة خلفية مائلة \
(backslash)، وعند استخدام صيغة (COMMAND)$
فإن كل المحارف بين القوسين تُعد مكونة للأمر ولا يعامل أي منها بشكل خاص.
كذلك يمكن أن تتداخل إحلالات الأوامر، ولكي تصنع تداخلًا أثناء استخدام صيغة الاقتباس الخلفي، اسبق الفواصل العليا المائلة بشَرّط مائلة خلفية. لا تنقسم الكلمات إن ظهر الإحلال بين علامتي اقتباس مزدوجة، وتوسَّع أسماء الملفات على النتائج.
التوسع الحسابي
يسمح التوسع الحسابي بتقييم تعبير حسابي وإحلال نتيجته، وصيغة التوسع الحسابي هي ((التعبير الحسابي))$
، ويعامل التعبير كما لو كان بين علامات اقتباس مزدوجة، لكن لا تُعامل علامة الاقتباس المزدوجة داخل القوسين . وتخضع كل الوحدات داخل التعبير لتوسع المعامل وإحلال الأمر وإزالة الاقتباس، كما يمكن أن تتداخل الإحلالات الحسابية.
يتم تقييم التعبيرات الحسابية في أرقام ثابتة العرض (fixed-width integers) بدون تفقد للفائض رغم أن القسمة على الصفر تُلتقط وتعرّف على أنها خطأ، والمعامِلات (operators) هي نفسها تقريبًا التي في لغة C البرمجية. ومن أجل تقليل الأولوية فإن القائمة تكون مشابهة لهذه:
جدول 3.4 : المعاملات الحسابية
المعامِل | المعنى |
++VAR و --VAR
|
الزيادة اللاحقة للمتغير والتناقص اللاحق له |
VAR++ و VAR--
|
الزيادة السابقة للمتغير والتناقص السابق له |
- و +
|
إشارتي ناقص وزائد أحاديتين |
! و ~
|
النفي المنطقي (Logical Negation) والنفي البِتِّي (Bitwise Negation) |
**
|
الأُسِّية -رفع القوة الجبرية- |
* و / و %
|
الضرب والقسمة والباقي (remainder) |
+ و -
|
الجمع والطرح |
<< و >>
|
النقلات البِتِّية (bitwise shifts) -على مستوى البِتّ bit- لليمين واليسار |
<= و >= و < و >
|
معامِلات المقارنة |
== و !=
|
التساوي وعدم التساوي |
&
|
بوابة AND البِتِّية |
^
|
بوابة OR البِتِّية الحصرية |
|
|
بوابة OR البِتِّية |
&&
|
بوابة AND |
||
|
بوابة OR |
expr ? expr : expr
|
التقييم الشرطي |
= و *= و /= و %= و += و -= و <<= و >>= و &= و ^= و |=
|
التعيينات |
,
|
الفاصلة التي تفصل بين التعبيرات |
قد يُشار إلى متغيرات الصدفة بالاسم داخل التعبير بدون استخدام بنية التوسع اللغوية (expansion syntax)، وتُقيَّم قيمة المتغير كتعبير حسابي حين يشار إليها. كذلك يُسمح بمتغيرات الصدفة كعوامل (operands)، ولا يحتاج متغير الصدفة أن تكون خاصيته الرقمية (integer attribute) نشطة عند الإشارة إليه.
تُفسَّر الثوابت التي تبدأ بصفر كأرقام ثُمانيّة (وفق النظام الثُماني)، أما 0x
و 0X
فتدل على النظام السداسي العشري (hexadecimal). وتأخذ الأرقام التي ليست من هذه ولا تلك صيغة BASE'#']N]
، حيث يكون BASE
رقمًا عشريًا بين 2 و 64 ممثلًا القاعدة الحسابية، ويكون N
رقمًا في تلك القاعدة.
ويُستخدم رقم 10 كافتراضي إن أهمل الرقم الممثل للقاعدة الحسابية كدلالة على النظام العشري، وتُمثل الأرقام الأكبر من 9 بأحرف من الحالة الصغرى (lowercase)، والكبرى (uppercase)، و "@" و"_"، بذلك الترتيب. أما إن كان رقم القاعدة BASE
أقل من أو يساوي 36 فيمكن استخدام أحرف من الحالتين بالتبادل لتمثيل أرقام بين 10 و35. وتُقيَّم المعامِلات بأولوية الترتيب، وتُقيَّم التعبيرات الفرعية (sub-expressions) التي في الأقواس أولًا وربما تلغي قاعدة الأولوية المذكورة قبل قليل.
وينبغي على من يستخدم Bash أن يحاول استخدام البنية اللغوية للتعبير باستخدام أقواس مربعة كلما أمكن: [التعبير]$
، لكن على أي حال سيحسب ذلك نتيجة التعبير فقط ولن يُجري أي اختبارات:
hsoub ~> echo $[365*24]
8760
انظر المقارنات الرقمية في مقدمة إلى if في Bash لترى أمثلة عملية في برامج الصدفة.
إحلال العمليات
إحلال العمليات مدعوم في الأنظمة التي تدعم الأنابيب المسماة (FIFOs- First In First Out) أو أسلوب dev/fd/
في تسمية الملفات، وتكون صيغته كالتالي: (LIST)>
أو (LIST)<
.
وتجري عملية LIST
بحيث تكون مدخلاتها ومخرجاتها متصلة بأنبوب مُسمَّى (FIFO) أو ملف ما في dev/fd/
، ويُمرر اسم هذا الملف كوسيط إلى الأمر الحالي كنتيجة للتوسع. وإن استُخدمَت صيغة (LIST)<
فإن الكتابة إلى الملف ستزود القائمة LIST
بالمدخلات، أما إن استُخدِمت صيغة (LIST)>
فيجب أن يُقرأ الملف الذي مُرِّر كوسيط من أجل الحصول على خرج القائمة LIST
. لاحظ أنه يجب ألا تظهر مسافات بين علامات <
أو >
و القوس الأيسر، وإلا فإن البنية ستفسر على أنها إعادة توجيه.
يُنفذ إحلال العمليات بالتزامن مع توسع المعامل والمتغير، وإحلال الأوامر والتوسع الحسابي كلما أمكن. انظر إعادة التوجيه وواصفات الملفات.
انقسام الكلمات
تمسح الصدفة نتائج توسع المعاملات وإحلال الأوامر والتوسعات الحسابية التي لم تقع داخل علامتي اقتباس مزدوجة بحثًا عن انقسام للكلمات. وتعامل الصدفة كل محرف من فاصل الحقل الداخلي (internal field separator) أو IFS$
كمحرف محدِّد (delimiter) ، وتقسِّم نتائج التوسعات الأخرى في كلمات عن تلك المحارف، وفي حالة عدم ضبط الفاصل IFS أو كانت قيمته الافتراضية هي "'<مسافة (space)><جدول(tab)><سطر جديد (newline)>'"
تحديدًا، فإن أي تسلسل لمحارف IFS يعمل لتحديد الكلمات.
ويتم تجاهل تسلسل محارف المسافات البيضاء المسافة(space)
والجدول(tab)
في بداية ونهاية الكلمة إن كانت قيمة IFS خلاف القيمة الافتراضية، طالما أن محرف المسافة البيضاء يكون في قيمة IFS (محرف مسافة بيضاء لمتغير IFS).
وأي محرف في متغير IFS ليس بمحرف مسافة بيضاء فإنه يحدِّد حقلًا، وكذلك أي محارف مسافات بيضاء في أي IF قريب (IF- Internal Field)، ويُعامَل تسلسل محارف المسافات البيضاء للفاصل IFS كمحدِّد أيضًا، وأما إن كانت قيمة IFS فارغة فلا يحدث انقسام للكلمات.
يُحتفظ بالوسائط الفارغة الصريحة (""""
أو "''"
) وتُحذف الوسائط الضمنية غير المقتبَسة الناتجة من توسع المعامِلات التي ليس لها قيَم، وينتج نص فارغ ويُحتفظ به عند توسع معامل ليس له قيَم بين علامات اقتباس مزدوجة.
التوسع وانقسام الكلمات
إن لم يحدث توسع فلا يُنفذ أي انقسام.
توسع أسماء الملفات
تمسح Bash كل كلمة بعد انقسام الكلمات ما لم يُحدد خيار f-
بحثًا عن محارف *
و ?
و ]
(انظر تنقيح أجزاء من الصدفة)، فإن لم يظهر أي من تلك المحارف فتُعد الكلمة نمطًا (PATTERN
) وتستبدل بقائمة من أسماء الملفات الموافقة للنمط مرتبة أبجديًا.
فإن لم يوجد أي اسم مطابق وكان خيار الصدفة nullglob
معطلًا فإن الكلمة تترك كما هي. وإن ضُبط خيار nullglob
ولم توجد تطابقات فإن الكلمة تُحذف. وإن كان خيار nocaseglob
مفعلًا فيُنفَّذ التطابق دون النظر لحالة المحارف الأبجدية.
وحين يُستخدم نمط لتوليد اسم ملف فإن محرف .
في بداية اسم الملف أو بعد شرطة مائلة مباشرة يجب أن يُطابَق صراحةً (explicitly) ما لم يحدد خيار dotglob
. وعند مطابقة اسم ملف يجب أن تطابَق الشرطة المائلة دومًا صراحةً. قد لا تُعامل .
بشكل خاص في بعض الحالات.
قد يُستخدم متغير GLOBIGNORE
لتقييد مجموعة أسماء الملفات التي تطابق نمطًا ما، وإن ضُبط GLOBEIGNORE
على قيمة ما فيُحذف من قائمة أسماء الملفات المطابِقة كل اسم يطابق أحد الأنماط في GLOBIGNORE
.
ويتم تجاهل .
و ..
كأسماء ملفات حتى لو ضُبط GLOBIGNORE
، لكن على أي حال فإن ضبط GLOBIGNORE
له ينشِّط خيار dotglob
، لذا ستتطابق كل أسماء الملفات الأخرى التي تبدأ بـ .
، ولكي تحصل على السلوك القديم لتجاهل أسماء الملفات التي تبدأ بـ .
، اجعل *.
أحد الأنماط في GLOBIGNORE
. واعلم أن خيار dotglob
يُعطَّل عند إلغاء ضبط GLOBEIGNORE
.