اذهب إلى المحتوى

البحث في الموقع

المحتوى عن 'bash scripting'.

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المحتوى


التصنيفات

  • الإدارة والقيادة
  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • السلوك التنظيمي في المؤسسات
  • عالم الأعمال
  • التجارة والتجارة الإلكترونية
  • نصائح وإرشادات
  • مقالات ريادة أعمال عامة

التصنيفات

  • مقالات برمجة عامة
  • مقالات برمجة متقدمة
  • PHP
    • Laravel
    • ووردبريس
  • جافاسكربت
    • لغة TypeScript
    • Node.js
    • React
    • Vue.js
    • Angular
    • jQuery
    • Cordova
  • HTML
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • لغة C#‎
    • ‎.NET
    • منصة Xamarin
  • لغة C++‎
  • لغة C
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • لغة Rust
  • برمجة أندرويد
  • لغة R
  • الذكاء الاصطناعي
  • صناعة الألعاب
  • سير العمل
    • Git
  • الأنظمة والأنظمة المدمجة

التصنيفات

  • تصميم تجربة المستخدم UX
  • تصميم واجهة المستخدم UI
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب GIMP
    • كريتا Krita
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • مقالات DevOps عامة
  • خوادم
    • الويب HTTP
    • البريد الإلكتروني
    • قواعد البيانات
    • DNS
    • Samba
  • الحوسبة السحابية
    • Docker
  • إدارة الإعدادات والنشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
    • ريدهات (Red Hat)
  • خواديم ويندوز
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • شبكات
    • سيسكو (Cisco)

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح
  • مبادئ علم التسويق

التصنيفات

  • مقالات عمل حر عامة
  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • العمل الحر المهني
    • العمل بالترجمة
    • العمل كمساعد افتراضي
    • العمل بكتابة المحتوى

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
    • بريستاشوب
    • أوبن كارت
    • دروبال
  • الترجمة بمساعدة الحاسوب
    • omegaT
    • memoQ
    • Trados
    • Memsource
  • برامج تخطيط موارد المؤسسات ERP
    • تطبيقات أودو odoo
  • أنظمة تشغيل الحواسيب والهواتف
    • ويندوز
    • لينكس
  • مقالات عامة

التصنيفات

  • آخر التحديثات

أسئلة وأجوبة

  • الأقسام
    • أسئلة البرمجة
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات

التصنيفات

  • كتب ريادة الأعمال
  • كتب العمل الحر
  • كتب تسويق ومبيعات
  • كتب برمجة
  • كتب تصميم
  • كتب DevOps

ابحث في

ابحث عن


تاريخ الإنشاء

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


رشح النتائج حسب

تاريخ الانضمام

  • بداية

    نهاية


المجموعة


النبذة الشخصية

تم العثور على 9 نتائج

  1. تساعد الدوال البرمجية على تنظيم سكربتات باش وجعلها أسهل في القراءة، وخاصة السكربتات كبيرة الحجم، إذ يمكننا استدعاء الدالة لأداء المهمة نفسها في عدة مواضع داخل السكربت دون الحاجة لتكرار كتابة التعليمات البرمجية الخاصة بهذه المهمة أكثر من مرة. سنتعلم في هذا المقال كيفية إنشاء الدوال البرمجية Functions في سكربتات باش وتمرير الوسطاء إليها وإرجاع النتائج منها، كما سنتعرف على الفرق بين المتغيرات المحلية والمتغيرات العامة، وعلى ماهية الدوال العودية Recursive Functions وكيفية تحقيقها في باش. إنشاء الدوال في باش توجد صيغتان للتصريح عن الدوال البرمجية في باش، وتُعدّ الصيغة التالية هي الأكثر استخدامًا: function_name () { commands } أما الصيغة الثانية الأقل شهرة، فهي تبدأ بالكلمة المفتاحية function يليها اسم الدالة كما يلي: function function_name { commands } ينبغي الانتباه إلى الأساسيات التالية عن التعامل مع الدوال: لا تعمل الدالة أبدًا ما لم نقم باستدعائها لا يمكننا استدعاء الدالة قبل تعريفها، لذا نجد أن تعريف الدالة في تسلسل تعليمات السكربت يأتي قبل أي استدعاء لها نستدعي الدالة بكتابة اسمها فقط نمرر الوسيط إن وجد مباشرة بعد اسم الدالة لنلقِ نظرة على السكربت fun.sh التالي: #!/bin/bash hello () { echo "Hello World" } hello hello hello عرّفنا في بداية السكربت دالة تدعى hello وظيفتها عرض العبارة Hello World على الطرفية Terminal، ثم استدعينا الدالة ثلاث مرات بكتابة اسمها، لذا عند تنفيذ السكربت ستظهر العبارة Hello World على الشاشة ثلاث مرات كالتالي: kabary@handbook:~$ ./fun.sh Hello World Hello World Hello World إرجاع القيم من الدالة في باش لا تُرجع لنا دوال باش قيمًا عند استدعائها على عكس السائد في معظم لغات البرمجة، فعند انتهاء التنفيذ الدالة تُرجع حالة الخروج من آخر أمر مُنفذ وتُخَزَّن الحالة في المتغير الخاص ‎‏‎‏‏‎‏?$، فإذا كان التنفيذ ناجحًا سيأخذ المتغير ‎‏‏‎‏?$ القيمة صفر، وإذا فشل التنفيذه فسيأخذ قيمة عدد صحيح موجب آخر يقع ضمن المجال [1-255] حسب سبب الفشل. لكن يمكننا استخدام التعليمة return لتغيير حالة الخروج من الدالة كما يوضح السكربت error.sh التالي: #! /bin/bash error () { blabla return 0 } error echo "The return status of the error function is: $?" إذا شغلنا السكربت السابق سنحصل على الخرج التالي: kabary@handbook:~$ ./error.sh ./error.sh: line 4: blabla: command not found The return status of the error function is: 0 الكلمة blabla التي كتبناها في جسم الدالة () error ما هي إلّا كلمة عشوائية لا تمثل أي أمر برمجي، لذا فالتعليمية return 0 هي السبب في حصولنا على حالة خروج صفرية من الدالة () error أي حالة خروج ناجحة، وبدونها ما كانت الدالة ستعطينا هذه النتيجة لأن blabla حتمًا سترجع رسالة خطأ مفادها لم يتم العثور على الأمر. رغم أن دوال باش لا تعيد قيمًا، فقد ساعدتنا طريقة الكتابة السابقة على تغيير حالة الخروج من الدالة ونجاح عملية تنفيذها، وبدونها لن تتمكن الدالة من إرجاع قيمة للبرنامج المستدعي أي لن نحصل على نتيجة تنفيذ الدالة لأن أي رمز خروج غير الصفر يشير إلى وجود خطأ. ملاحظة: لنتذكر دائمًا أن return تعني إنهاء تنفيذ الدالة والخروج منها. تمرير الوسطاء إلى دالة باش يشبه تمرير الوسطاء إلى دوال باش كثيرًا تمرير الوسطاء إلى سكربتات باش، فكل ما يتطلبه الأمر كتابة الوسطاء أو سردها إلى جانب اسم الدالة عند استدعائها. يوضح السكربت iseven.sh التالي طريقة القيام بذلك: #!/bin/bash iseven () { if [ $(($1 % 2)) -eq 0 ]; then echo "$1 is even." else echo "$1 is odd." fi } iseven 3 iseven 4 iseven 20 iseven 111 تُميّز الدالة () iseven في الكود أعلاه بين الأعداد الزوجية والأعداد الفردية، وقد استدعيناها أربع مرات في السكربت وفي كل استدعاء مررنا لها عددًا مختلفًا، وطالما أننا كتبنا الوسيط مباشرة بعد الدالة فهو الوسيط الأول وسيُشير له المتغير $1. لنختبر الآن طريقة عمل السكربت: kabary@handbook:~$ ./iseven.sh 3 is odd. 4 is even. 20 is even. 111 is odd. وسطاء الدالة مغايرين لوسطاء السكربت، وكل منهم يعمل في مستوى خاص مختلف عن الآخر، سيبين السكربت التالي funarg.sh الفرق: #!/bin/bash fun () { echo "$1 is the first argument to fun()" echo "$2 is the second argument to fun()" } echo "$1 is the first argument to the script." echo "$2 is the second argument to the script." fun Yes 7 والآن لنشغل السكربت مع تمرير وسيطين له، ونلاحظ النتيجة: kabary@handbook:~$ ./funarg.sh Cool Stuff Cool is the first argument to the script. Stuff is the second argument to the script. Yes is the first argument to fun()7 is the second argument to fun() لقد استخدمنا المتغيرين $1 و $2 لوظيفتين، للتعبير عن الوسيطين الأول والثاني مرة للدالة ومرة للسكربت، وعند استدعائهما من داخل الدالة كان لهما معنى مختلف عن وسطاء السكربت. المتغيرات المحلية والمتغيرات العامة داخل سكربتات باش تكون متغيرات باش عامة Global Variables أو محلية Local Variables، يمكننا استخدام المتغيرات العامة على مستوى السكربت كاملًا، أما المتغيرات المحلية فلا تستخدم إلّا ضمن نطاق الدالة. يوضح السكربت domain.sh bash التالي الفرق بينهما: #!/bin/bash v1='A' v2='B' myfun() { local v1='C' v2='D' echo "Inside myfun(): v1: $v1, v2: $v2" } echo "Before calling myfun(): v1: $v1, v2: $v2" myfun echo "After calling myfun(): v1: $v1, v2: $v2" عرّفنا في بداية السكربت متغيرين عامين Global هما v1 و v2، ثم في داخل الدالة ()myfun عرّفنا متغير محلي Local يدعى v1 باستخدام الكلمة المفتاحية local، وعدّلنا قيمة المتغير العام v2، نلاحظ أننا نستطيع استخدام الاسم نفسه لمتغيرات محلية مختلفة في دوال مختلفة. إذا شغّلنا السكربت الآن سنحصل على النتيجة التالية: kabary@handbook:~$ ./scope.sh Before calling myfun(): v1: A, v2: B Inside myfun(): v1: C, v2: D After calling myfun(): v1: A, v2: D نستنتج من المثال السابق ما يلي: إذا كان لدينا متغير محلي ومتغير عام لهما الاسم نفسه، فإن المتغير المحلي يتمتع بالأولوية داخل الدالة يمكننا تعديل قيمة متغير عام من داخل الدالة الدوال العودية Recursive Functions الدالة العودية recursive function هي دالة تستدعي نفسها مرات عدة حتى الوصول للشرط المطلوب، وهي تفيدنا في التعامل مع المسائل البرمجية التي يمكن تقسيمها إلى مسائل أصغر مشابهة لها. تُعدّ دالة حساب العاملي factorial function مثال تقليدي على التعادوية، يوضحه السكربت factorial.sh التالي: #!/bin/bash factorial () { if [ $1 -le 1 ]; then echo 1 else last=$(factorial $(( $1 -1))) echo $(( $1 * last )) fi } echo -n "4! is: " factorial 4 echo -n "5! is: " factorial 5 echo -n "6! is: " factorial 6 تبدأ كل دالة عودية بتعريف حالة أساسية أو حدّية base case وعند الوصول إليها تنتهي الاستدعاءات الذاتية للدالة أي تنتهي العودية، والحالة الحدّية للدالة ()factorial في مثالنا السابق الواحد حيث أن عاملي العدد 1 هو العدد 1: if [ $1 -le 1 ]; then echo 1 لنوضح الآن الحالة العودية في دالة حساب العاملي: إن حساب العاملي لأي عدد صحيح موجب مثل n يساوي قيمة العدد n مضروبًا بحساب العاملي للعدد الأصغر منه n-1 وهكذا وفق المعادلة التالية: factorial(n) = n * factorial(n-1) وقد استخدمنا هذه المعادلة في كتابة الحالة العودية recursive case للدالة السابقة وفق التالي: last=$(factorial $(( $1 -1))) echo $(( $1 * last )) لنشغّل السكربت ونتأكد من صحة النتائج: kabary@handbook:~$ ./factorial.sh 4! is: 24 5! is: 120 6! is: 720 يمكن تجربة أفكار أخرى لإتقان مفهوم الدوال العودية، لنحاول مثلًا حساب قيمة سلسلة فيبوناتشي لعدد معين، علينا أن نحدد في البداية الحالة الأساسية ثم الحالة العودية وبعدها نكتب السكربت. الخاتمة وصلنا إلى ختام مقالنا الذي شرحنا فيه أهمية الدوال البرمجية التقليدية والدوال التعاودية وحالات استخدامها في سكربتات باش، نأمل أنه كان مفيدًا، تابع مقالنا التالي والأخير حيث سنطبق فيه كل المبادئ التي تعلمناها على في كافة مقالات سلسلة تعلم باش. ترجمة -وبتصرف- للمقال Using Functions in Bash. اقرأ أيضًا المقال السابق: الحلقات في باش Bash أنشئ برنامجك النصي الأول على صدفة باش Bash استخدام الدوال في سكربات الصدفة Shell Scripts عمليات السلاسل النصية في باش Bash
  2. الحلقات Loops ضرورية في أي لغة برمجة، ولها حالات استخدام متعددة في سكربتات باش سنتعلمها معًا في هذا المقال، وسنتعرف على حلقات For و While و Until، وعلى كيفية التحكم بالحلقات باستخدام تعليمات break و continue، بالإضافة لطريقة كتابة الحلقات اللانهائية، وكيف أنها قد تشير في بعض الأحيان لوجود أخطاء في كتابة السكربت. حلقات For في باش حلقة for هي واحدة من ثلاثة أنواع من الحلقات التكرارية التي يمكننا استخدامها في سكربتات باش، وهي تكتب بطريقتين: حلقة for المكتوبة بأسلوب لغة C حلقة for المعتمدة على قائمة أو مجال محدد من العناصر كتابة حلقة for بأسلوب لغة C في سكربتات باش نكتب هذا النوع من حلقات for بالطريقة نفسها التي نكتبها في لغات البرمجة C و ++C وفق الصيغة العامة التالية: for ((initialize ; condition ; increment)); do [COMMANDS] done إذا طبقنا الصيغة العامة السابقة على المثال أدناه، فإن تنفيذ الحلقة الموجودة فيه سيعرض عبارة "Hello Friend" عشر مرات على شاشة الطرفية: for ((i = 0 ; i < 10 ; i++)); do echo "Hello Friend" done لنفسر الشيفرة السابقة: القيمة الابتدائية لمتغير الحلقة هي 0، وشرط التكرار أن لا تتجاوز قيمة المتغير العدد 10، ومقدار الزيادة هو 1، وبالتالي في كل مرة يتحقق فيها شرط الحلقة سيُنفذ الأمر البرمجي وهو في حالتنا عرض العبارة Hello Friend على الشاشة وتزداد قيمة متغير الحلقة i بمقدار واحد، ثم يُفحص الشرط من جديد وهكذا حتى الوصول للحد الأعلى أي 10. وهذه نتيجة تنفيذ الحلقة: kabary@handbook:~$ bash hello.sh Hello Friend Hello Friend Hello Friend Hello Friend Hello Friend Hello Friend Hello Friend Hello Friend Hello Friend Hello Friend كتابة حلقة for المعتمدة على القوائم في سكربتات باش تفيدنا حلقة for المكتوبة بهذه الطريقة في الحالات التي نتعامل فيها مع قائمة معروفة العناصر، مثل: مجموعة ملفات أو مجموعة سلاسل نصية، أو مجال محدد من الأعداد، أو مصفوفة، أو ربما مخرجات ثابتة لأمر معين أو غير ذلك، ولها الصيغة العامة التالية: for item in [LIST]; do [COMMANDS] done يبين المثال أدناه الحلقة نفسها التي تعاملنا معها في الفقرة السابقة ولكنها مكتوبة هذه المرة بطريقة القائمة: for i in {1..10}; do echo "Hello Friend" done وهذا مثال آخر حيث يعرض السكربت var.sh التالي جميع الملفات الموجودة في المجلد var/: #!/bin/bash for i in /var/*; do echo $i done وسنحصل في الخرج على نتيجة تشبه ما يلي: kabary@handbook:~$ ./var.sh /var/backups /var/cache /var/crash /var/lib /var/local /var/lock /var/log /var/mail /var/metrics /var/opt /var/run /var/snap /var/spool /var/tmp حلقات While في باش هذه هي الصيغة العامة لحلقة while في باش: while [ condition ]; do [COMMANDS] done لنطبق مثالًا عمليًّا: يعرض السكربت التالي المضاعفات العشرة الأولى للعدد 3: #!/bin/bash num=1 while [ $num -le 10 ]; do echo $(($num * 3)) num=$(($num+1)) done وسيكون الخرج كما يلي: kabary@handbook:~$ ./3x10.sh 3 6 9 12 15 18 21 24 27 30 لنُحلّل السكربت أعلاه، في البداية أعطينا المتغير num القيمة الابتدائية 1، وحددنا شرط تكرار الحلقة بأن لا تتجاوز قيمة المتغير العدد 10، وبناءً على ذلك سيُنَفَذ الأمران الموجودان في جسم الحلقة وهما أولًا إظهار ناتج ضرب قيمة المتغير num بالعدد 3 على الشاشة، وثانيًا زيادة قيمة num بمقدار 1، ويُعاد تنفيذهما مرارًا وتكرارًا طالما أن شرط الحلقة محقق. حلقات Until في باش النوع الثالث من الحلقات التكرارية باش هو until، وليس الحلقة do-while التي اعتاد عليها مبرمجو لغة C و ++C، وكما نلاحظ أدناه فالصيغة العامة لحلقة until مطابقة تمامًا لصيغة كتابة حلقة while: until [ condition ]; do [COMMANDS] Done ويكمن الفرق بينهما في طريقة تعامل كل حلقة مع نتيجة اختبار الشرط فيما إذا كان محققًا أو غير محقق، ففي الحلقة while يستمر التنفيذ طالما أن شرط الحلقة محقق، وعلى العكس تمامًا في الحلقة until إذ يستمر التنفيذ طالما أن الشرط غير محقق. لنكتب الآن السكربت السابق باستخدام الحلقة until بدلًا من while، دقق جيدًا في الشرط فهو جوهر الاختلاف بين السكربتين: #!/bin/bash num=1 until [ $num -gt 10 ]; do echo $(($num * 3)) num=$(($num+1)) done الشرط هنا هو أن تكون قيمة المتغير num أكبر من 10، بينما كان الشرط في سكربت while هو أن تكون قيمة المتغير num أصغر من 10وهما كما تلاحظ عكس بعضهما تمامًا. حالات شائعة لاستخدام الحلقات في باش بعد أن تعرفنا على أساسيات الحلقات، سنعرض بعضًا من أشهر استخداماتها في باش: إظهار عناصر مصفوفة بواسطة سكربت باش تُعدّ الحلقة for خيارًا مناسبًا لعرض عناصر أي مصفوفة في باش، يمكن الرجوع لمقالنا استخدام المصفوفات في باش Bash لمعرفة كيفية إنشاء مصفوفات باش والتعامل معها. ألقِ نظرة على السكربت prime.sh التالي، إنه يتضمن مصفوفة تسمى prime وحلقة for تمر على عناصر المصفوفة واحدًا تلو الآخر وتُظهرهم على الشاشة بواسطة الأمر echo: #!/bin/bash prime=(2 3 5 7 11 13 17 19 23 29) for i in "${prime[@]}"; do echo $i done وسيكون الخرج كما يلي: kabary@handbook:~$ ./prime.sh 2 3 5 7 11 13 17 19 23 29 استخدام break و continue في حلقات باش تساعدنا تعليمات break و continue على إنهاء تنفيذ الحلقة قبل الأوان أو تخطي بعضًا من تكراراتها لأغراض تخدم برنامجنا. توقف التعليمة break تنفيذ الحلقة وتنقل التنفيذ إلى التعليمة التالية في البرنامج، فعلى سبيل المثال ستعرض الحلقة التالية الأعداد من واحد إلى ثلاثة فقط على شاشة الطرفية: for ((i=1;i<=10;i++)); do echo $i if [ $i -eq 3 ]; then break fi done وتساعدنا التعليمة continue على تجاوز بعض التكرارات، فكلما وصل تسلسل التنفيذ إلى continue تُهمَل الأوامر التي تليها والتي تقابل قيمًا معينة للمتغير نود تجاوزها، ويُكرر تنفيذ الحلقة بعد زيادة قيمة المتغير. يبين السكربت odd.sh التالي كيفية استخدام continue لتخطي الأعداد الزوجية وإظهار الأعداد الفردية فقط من بين الأعداد من صفر إلى عشرة: #!/bin/bash for ((i=0;i<=10;i++)); do if [ $(($i % 2)) -ne 1 ]; then continue fi echo $i done وستحصل على هذا الخرج: kabary@handbook:~$ ./odd.sh 1 3 5 7 9 الحلقات اللانهائية في باش الحلقات اللانهائية Infinite Loops هي حلقات دائمة التكرار بدون نهاية لأن شرط تكرارها محقق دائمًا. قد يبني المستخدم حلقات لانهائية عن قصد لأهداف معينة، لكن معظم الحلقات النهائية في واقع الأمر تظهر نتيجة أخطاء بشرية غير مقصودة. الهدف من إنشاء الحلقة التالية مثلًا هو إظهار الأرقام من واحد إلى عشرة على شاشة الطرفية لكن بترتيب تنازلي، إذا دققنا فيها سنكتشف خطأ يوقع المستخدم ضحية تكرار لا نهائي للحلقة: for ((i=10;i>0;i++)); do echo $i done إذا دققنا في الكود أعلاه سنلاحظ أن مُنشئ الحلقة هنا يزيد قيمة المتغير i بمقدار واحد بعد كل تنفيذ بدلًا من إنقاصها بمقدار واحد ليصل في النهاية إلى القيمة صفر وهي شرط انتهاء الحلقة، فحتى تعمل الحلقة بالصورة المطلوبة علينا استبدال ++i بالتعليمة --i لتصبح كما يلي: for ((i=10;i>0;i--)); do echo $i done قد تفرض علينا متطلبات العمل إنشاء حلقات لا نهائية لانتظار تحقق شروط معينة على النظام مثلًا أو لأسباب أخرى، وبصرف النظر عن السبب إذا احتجنا لإنشاء هذا النوع من الحلقات فيمكننا ذلك باستخدام إحدى الصيغ التالية. صيغة بناء حلقة لا نهائية باستخدام حلقة for: for ((;;)); do [COMMANDS] done صيغة بناء حلقة لا نهائية باستخدام حلقة while: while [ true ]; do [COMMANDS] done الخلاصة انتهى مقالنا الخاص بالحلقات التكرارية في سكربتات باش، عرضنا فيه الحلقات الأساسية الثلاث مع بعض الأمثلة العملية ووضحنا حالات الاستخدام الخاصة بكل حلقة، ندعوك لمتابعة المقال التالي حول الدوال في باش وتطبيق المزيد من المفاهيم المتقدمة. ترجمة -وبتصرف- للمقال Loops in Bash. اقرأ أيضًا المقال السابق: الجمل الشرطية في باش Bash كيف تستخدم بنى التحكم في سكربتات الصدفة Shell Scripts - الجزء 1 كيف تستخدم بنى التحكم في سكربتات الصدفة Shell Scripts - الجزء 2 كيف تستخدم بنى التحكم في سكربتات الصدفة Shell Scripts - الجزء 3
  3. سنتعلم في هذا المقال كيفية استخدام الجمل والعبارات الشرطية الشائعة مثل if و else و case لكتابة سكربتات باش فعالة، ونتعرف على طريقة التعامل مع سيناريوهات متعددة واتخاذ القرارات المناسبة من خلالها. استخدام الجملة الشرطية if في باش يعد الشرط if العنصر الأساسي في أي بنية برمجية لاتخاذ القرار، ويمكن كتابة الشرط في باش وفق الصيغة العامة التالية: if [ condition ]; then your code fi نلاحظ أن كل عبارات if الشرطية تبدأ في باش بالأمر if وتنتهي بالأمر fi أي if معكوسة. ويجب الانتباه للمسافات الفارغة عند كتابة الجمل الشرطية فهي ذات أهمية، وهذه مواضعها: توجد مسافة فارغة قبل الشرط condition المكتوب بين قوسين وبعده، وإذا أهملناها سنحصل على خطأ توجد مسافة فارغة قبل وبعد العوامل الشرطية مثل = أو == أو => وعدم الالتزام بها سيعطينا رسالة خطأ مفادها unary operator expected أي يتوقع تشغيل عامل فردي. لنجرب الآن كتابة سكربت بسيط باسم root.sh، يعرض على الشاشة عبارة "You are root" في حالة واحدة فقط إذا كان المستخدم الذي ينفذ السكربت هو الجذر root: #!/bin/bash if [ $(whoami) = 'root' ]; then echo "You are root" fi اعتمدنا في هذا السكربت على الأمر whoami الذي يعطينا اسم المستخدم مُنفّذ السكربت، وكتابته ضمن قوسين هلاليين مع رمز الدولار بالصيغة التالية (command)$ فتعني حصولنا على خرج الأمر بهيئة متغير، تدعى هذه العملية تعويض الأوامر command substitutions وقد تعرفنا عليها في مقال المتغيرات في سكربتات الصدفة باش Bash. إذًا سيتحقق الشرط الوارد في جملة if ويطبع العبارة المطلوبة في حالة واحدة فقط وهي عندما ينفذ السكربت المستخدم الجذر root، وتظهر الصورة التالية نتيجة التنفيذ: استخدام الجملة الشرطية if-else في باش يمكننا تضمين أي تعليمة برمجية نريد تنفيذها عندما لا يتحقق الشرط if في الجملة الشرطية else فإذا عدنا للسكربت السابق root.sh مثلًا، وعدّلنا محتواه حتى يعطينا خرجًا معينًا عند عدم تحقق الشرط، فالسكربت في وضعه الحالي لا يظهر لنا أي نتيجة عند التنفيذ من مستخدم آخر غير الجذر وعندما نعدله على النحو التالي: #!/bin/bash if [ $(whoami) = 'root' ]; then echo "You are root" else echo "You are not root" fi ونحاول تشغيل السكربت من حساب المستخدم العادي، سنحصل على تنبيه يخبرنا أن المستخدم ليس المستخدم الجذر كما يلي: kabary@handbook:~$ ./root.sh You are not root استخدام الجملة الشرطية else-if في باش تساعدنا الجملة الشرطية else-if على اختبار أكثر من شرط في الوقت نفسه، وتكتب اختصارًا elif. لنلاحظ على سبيل المثال السكربت age.sh التالي الذي يأخذ معامل العمر AGE كوسيط ويعطينا نتيجة حسب الشروط المحددة في if و elif: #!/bin/bash AGE=$1 if [ $AGE -lt 13 ]; then echo "You are a kid." elif [ $AGE -lt 20 ]; then echo "You are a teenager." elif [ $AGE -lt 65 ]; then echo "You are an adult." else echo "You are an elder." fi يمكنك العودة لمقال تمرير الوسطاء إلى سكربت باش Bash لمطالعة مزيد من المعلومات عن تمرير الوسطاء لسكربتات باش. لننفذ السكربت الآن مع قيم مختلفة لمتغير العمر AGE ونلاحظ النتائج كما يلي: kabary@handbook:~$ ./age.sh 11 You are a kid. kabary@handbook:~$ ./age.sh 18 You are a teenager. kabary@handbook:~$ ./age.sh 44 You are an adult. kabary@handbook:~$ ./age.sh 70 You are an elder. استخدمنا الشرط lt وهو اختصار للعبارة الإنجليزية less than أي أصغر من لاختبار قيمة المتغير AGE$. وتجدر الإشارة لكوننا نستطيع استخدام الجملة الشرطية elif بقدر ما نريد في بنية else-if، أما else فلا تُكتَب فيها إلا مرة واحدة فقط، وأن كافة جمل if الشرطية ينبغي أن تُغلق باستخدام fi. استخدام جمل if الشرطية المتداخلة في باش يُقصد بالجمل الشرطية المتداخلة استخدام جمل if الشرطية داخل جمل if أخرى، لننظر على السكربت التالي weather.sh لتوضيح الأمر: #!/bin/bash TEMP=$1 if [ $TEMP -gt 5 ]; then if [ $TEMP -lt 15 ]; then echo "The weather is cold." elif [ $TEMP -lt 25 ]; then echo "The weather is nice." else echo "The weather is hot." fi else echo "It's freezing outside ..." fi يُظهِر هذا السكربت عبارات تصف الطقس بحسب درجة الحرارة المعطاة له ضمن الوسيط TEMP، فإذا كانت درجة الحرارة أكبر من 5 درجات فستُفَعَل عندها الجملة الشرطية الداخلية if-elif، دعنا نعطي السكربت بعض القيم المتفاوتة ونلاحظ النتائج: kabary@handbook:~$ ./weather.sh 0 It's freezing outside ... kabary@handbook:~$ ./weather.sh 8 The weather is cold. kabary@handbook:~$ ./weather.sh 16 The weather is nice. kabary@handbook:~$ ./weather.sh 30 The weather is hot. استخدام الجملة الشرطية case في باش الجملة الشرطية case هي بديل مناسب يغني في بعض الحالات التعقيد المصاحب لكثرة استخدام if ضمن السكربت، فالجملة case أسهل في القراءة والإعداد، وهذه صيغتها العامة: case "variable" in "pattern1" ) Command … ;; "pattern2" ) Command … ;; "pattern2" ) Command … ;; esac لننتبه للتالي عند كتابة case: توجد مسافة فارغة وقوس هلالي ) بعد كل حالة أو نمط من أنماط الجملة الشرطية case تنتهي جميع الأوامر بمسافة فارغة وفاصلة منقوطة مزدوجة ;; والمسافة الفارغة هنا إلزامية تنتهي جملة case دائمًا بالأمر esac وهو عبارة عن كلمة case معكوسة أكثر حالات استخدام case عند مطابقة المتغير مع أنماط أو خيارات محددة وواضحة كما في السكربت char.sh التالي: CHAR=$1 case $CHAR in [a-z]) echo "Small Alphabet." ;; [A-Z]) echo "Big Alphabet." ;; [0-9]) echo "Number." ;; *) echo "Special Character." esac يقبل هذا السكربت وسيطًا واحدًا هو CHAR، وتطابق الجملة case قيمته مع مجموعة أنماط، لتقرر فيما إذا كان المتغير حرفًا أبجديًا كبيرًا أو صغيرًا، أو عددًا أو محرفًا خاصًا. لنلاحظ نتائج تنفيذ السكربت مع قيم مختلفة للمتغير: kabary@handbook:~$ ./char.sh a Small Alphabet. kabary@handbook:~$ ./char.sh Z Big Alphabet. kabary@handbook:~$ ./char.sh 7 Number. kabary@handbook:~$ ./char.sh $ Special Character. يُمثل رمز النجمة * هنا الحالة الافتراضية للجملة case وهو يقابل else في جملة if الشرطية. شروط الاختبار في باش تعتمد شروط الاختبار المستخدمة في الجمل الشرطية السابقة في نهاية الأمر على معاملات منطقية، وتختلف طبيعتها حسب نوع البيانات المتعامل معها سواء كانت أعدادًا أو سلاسل نصية أو ملفات، ويبين الجدول التالي أشهر هذه الشروط: الشرط المكافئ a -lt $b$ قيمة a أصغر من قيمة b a -gt $b$ قيمة a أكبر من قيمة b a -le $b$ قيمة a أصغر أو تساوي قيمة b a -ge $b$ قيمة a أكبر أو تساوي قيمة b a -eq $b$ قيمة a تساوي قيمة b a -ne $b$ قيمة a لا تساوي قيمة b e $FILE- المتغير FILE$ موجود d $FILE- المتغير FILE$ موجود وهو مجلد f $FILE- المتغير FILE$ موجود وهو ملف عادي L $FILE- المتغير FILE$ موجود وهو رابط مرن soft link ‎$STRING1 = $STRING2‎ قيمة السلسلة النصية STRING1 تساوي قيمة السلسلة النصية STRING2 ‎$STRING1 != $STRING2 قيمة السلسلة النصية STRING1 لا تساوي قيمة السلسلة النصية STRING2 ‎-z $STRING1 قيمة السلسلة النصية STRING1 فارغة لا يتوجب حفظ هذه الشروط عن ظهر قلب فهي متوفرة في دليل مساعد يشرح طريقة كتابتها عندما نحتاجها، ويمكننا الوصول إليه بالتعليمة التالية: kabary@handbook:~$ man test لنطبق مثالًا عمليًّا على شروط باش، سننشئ السكربت filetype.sh الذي يبين طبيعة العنصر المعطى له إذا كان ملفًا أو مجلدًا أو رابطًا مرنًا soft link: #!/bin/bash if [ $# -ne 1 ]; then echo "Error: Invalid number of arguments" exit 1 fi file=$1 if [ -f $file ]; then echo "$file is a regular file." elif [ -L $file ]; then echo "$file is a soft link." elif [ -d $file ]; then echo "$file is a directory." else echo "$file does not exist" fi تفحص الجملة الشرطية الموجودة في بداية السكربت عدد الوسطاء الممررة له، وإذا تبين عدم وجود أي وسيط أو كان عدد الوسطاء أكبر من 1 فستُنهي هذه الجملة تنفيذ السكربت دون الانتقال للخطوة التالية، وتعطي المستخدم رسالة تحذيرية تطالبه بالتأكد من صحة الوسطاء المقدمة. لننفذ السكربت على عناصر مختلفة ونتفقد النتائج: kabary@handbook:~$ ./filetype.sh weather.sh weather.sh is a regular file. kabary@handbook:~$ ./filetype.sh /bin /bin is a soft link. kabary@handbook:~$ ./filetype.sh /var /var is a directory. kabary@handbook:~$ ./filetype.sh Error: Invalid number of arguments طريقة كتابة جملة if-else في سطر واحد يمكنك استخدام الجمل الشرطية if-else في ورؤية نتائجها في الصدفة shell مباشرةً دون الحاجة لكتابتها في سكربت خاص وتنفيذه عند اللزوم، وهذا مثال: if [ $(whoami) = 'root' ]; then echo "You are root" else echo "You are not root" fi بوسعنا كتابة هذا المثال في سطر واحد لتسهيل التعامل معه، ويجري ذلك بإضافة فاصلة منقوطة بين كل أمر وآخر كما يلي: if [ $(whoami) = 'root' ]; then echo "root"; else echo "not root"; fi نستطيع الآن تنفيذه في الصدفة مباشرةً، لننسخه ونلصقه في الطرفية terminal ونلاحظ النتيجة. الخلاصة حاولنا في هذه المقالة تكوين فكرةً عامة عن استخدام الجمل الشرطية في سكربتات باش من خلال أمثلة عملية متنوعة، ولفهم الموضوع بشكل أفضل ننصح بالتفكير بحالات اتخاذ قرار جديدة ومحاولة كتابة سكربتات مناسبة لها، فهذا من شأنه تعزيز فهم الموضوع والتعامل معه بكفاءة. ترجمة -وبتصرف- للمقال Decision Making With If Else and Case Statements. اقرأ أيضًا المقال السابق: عمليات السلاسل النصية في باش Bash البُنى الشرطية في Bash الاستخدامات المتقدمة لعبارة if الشرطية في Bash استخدام البنية case في باش أساسيات كتابة برامج Bash
  4. يدرك كل من تعامل مع متغيرات باش عدم وجود أي فرق بين تعريف متغير نوعه عدد صحيح int ومتغير نوعه سلسلة نصية string، فمهما كان نوع البيانات المتغير في باش هو متغير فقط. وقد تعرفنا في مقالنا السابق على معاملات العمليات الحسابية للتعامل مع الأعداد، وسنتعرف في هذا المقال على وظائف باش الخاصة بالتعامل مع السلاسل النصية، مثل حساب طول سلسلة نصية، وربط السلاسل النصية ببعضها، واستخراج السلاسل النصية الفرعية منها، واستبدال السلاسل النصية الفرعية وغير ذلك. معرفة طول السلسلة النصية السلسلة النصية string هي مجموعة أو مصفوفة من المحارف المتسلسلة فيما بينها. لنُعرّف سلسلة نصية جديدة أو متغير جديد في باش باسم distro مثلًا ونعطيه القيمة "Ubuntu" نكتب التالي: distro="Ubuntu" يمكن الحصول على طول هذه السلسلة أي عدد محارفها بكتابة الرمز # قبل اسمها ضمن تعليمة echo كما يلي: kabary@handbook:~/scripts$ echo ${#distro} 6 تنحصر وظيفة الأمر echo بإظهار النتيجة، أما الصيغة {string#} فهي التي احتسبت طول السلسلة الفعلي. دمج السلاسل النصية نعني بدمج السلاسل concatenation إلحاق سلسلة نصية أولى بنهاية سلسلة نصية أخرى للحصول على سلسلة أطول. لننشئ على سبيل المثال السلسلتين النصيتين "str1" و "str2" كما يلي: str1="hand" str2="book" لندمج الآن السلسلتين معًا ونخزن النتيجة بسلسلة ثالثة: str3=$str1$str2 توضح الصورة التالية النتيجة: إيجاد السلاسل النصية الفرعية تساعدنا هذه العملية على فهرسة index أو إيجاد موضع محرف معين أو تسلسل محارف معين ضمن سلسلة نصية، لتوضيح الفكرة لننشئ السلسلة النصية "str" كالتالي: str="Bash is Cool" يمكننا الآن معرفة موضع السلسلة الفرعية "Cool" ضمن الجملة السابقة باستخدام الأمر expr، وفق التالي: kabary@handbook:~/scripts$ word="Cool" kabary@handbook:~/scripts$ expr index "$str" "$word" 9 بعد تنفيذ الأمر حصلنا على العدد 9 في النتيجة، وهو يشير إلى ترتيب أول محرف من محارف السلسلة الفرعية "Cool" ضمن السلسلة الأصلية "Bash is Cool"، أي أنه مثل فهرس index لموضع السلسلة الفرعية. ملاحظة: لم نستخدم الجملة الشرطية if في الأمثلة التي أوردناها في هذا المقال لأننا سنخصص لها مقالًا لاحقًا. استخراج السلاسل النصية الفرعية يعني استخراج سلسلة فرعية من سلسلة أخرى استخراج حرف أو كلمة أو مجموعة كلمات من سلسلة نصية معينة. سنكتب الأمر التالي لإنشاء سلسلة نصية جديدة اسمها "foss" كما يلي: foss="Fedora is a free operating system" لنفترض الآن أننا نرغب باستخراج السلسلة الفرعية "fedora" من السلسلة السابقة، فكيف سننجز ذلك؟ ما نحتاجه هو فهرس السلسلة الفرعية أو موضع أول محرف فيها، بالإضافة إلى طولها الذي يُمثّل عدد المحارف التي نريد استخراجها. إذًا كي نستخرج السلسلة "fedora" سنبدأ من المحرف الذي ترتيبه 0، وسنستخرج بعده 6 محارف، وفق التالي: kabary@handbook:~/scripts$ echo ${foss:0:6} Fedora نلاحظ أن ترتيب المحارف في سلاسل باش النصية يبدأ من الصفر وليس من الواحد، وهذا ينسجم مع ترتيب أول عنصر في مصفوفات باش التي تبدأ دائمًا بالصفر. يمكننا أيضًا تحديد موضع البداية فقط وعدم ذكر عدد المحارف المطلوب استخراجها وعندها سيستخرج باش جميع المحارف من موضع البداية وحتى نهاية السلسلة. على سبيل المثال إذا أردنا استخراج السلسلة الفرعية "free operating system" من السلسلة "foss" السابقة، فسنحدد فقط موضع البداية وهو في حالتنا 12 كما يلي: kabary@handbook:~/scripts$ echo ${foss:12} free operating system استبدال السلاسل النصية الفرعية تتيح لنا هذه العملية استبدال سلسلة نصية فرعية بسلسلة أخرى، فيمكننا على سبيل المثال استبدال السلسلة النصية الفرعية "fedora" بالسلسلة النصية الفرعية "Ubuntu" ضمن السلسلة "foss" السابقة، وذلك وفق التالي: kabary@handbook:~/scripts$ echo ${foss/Fedora/Ubuntu} Ubuntu is a free operating system لنجرب استبدالًا آخر وهو تبديل السلسلة "free" بالسلسلة "popular" مثلًا: kabary@handbook:~/scripts$ echo ${foss/free/popular} Fedora is a popular operating system تجدر الإشارة هنا لأننا أجرينا في كلا المثالين السابقين استبدالًا ظاهريًا للسلاسل النصية الفرعية أي عند عرض السلاسل فقط من خلال الأمر echo، حيث أظهرنا السلسلة مرة باستبدال "fedora" ومرة "free" لكننا لم نبدل القيمة الفعلية للسلسلة "foss" حيث بقيت القيمة المخزنة فيها كما هي. حذف السلاسل النصية الفرعية يمكننا حذف أي سلسلة نصية فرعية من أي سلسلة نريدها باستخدام /، لننشئ مثلًا السلسلة النصية "fact" التالية: fact="Sun is a big star" لنحذف منها السلسلة الفرعية "big": kabary@handbook:~/scripts$ echo ${fact/big} Sun is a star لننشئ سلسلة أخرى مختلفة قليلًا اسمها "cell": cell="112-358-1321" لنفترض أننا نريد حذف الشرطات "-" منها، فإذا كتبنا الأمر التالي فإنه سيحذف الشرطة الأولى فقط كما يلي: kabary@handbook:~/scripts$ echo ${cell/-} 112358-1321 أما لحذف جميع الشرطات الموجودة في السلسلة فينبغي كتابة الرمز / مرتين، وفق التالي: kabary@handbook:~/scripts$ echo ${cell//-} 1123581321 نلاحظ أننا نحذف السلاسل النصية الفرعية في خرج الأمر echo فقط ولم نحذفها من القيمة الأصلية للسلسلة النصية "cell" التي بقيت كما هي ولم تتأثر بالحذف. أما إذا رغبنا بتعديل القيمة الأصلية للسلسلة النصية، وحذف الشرطات منها فعليًّا، فهذه هي الطريقة: kabary@handbook:~/scripts$ echo $cell 112-358-1321 kabary@handbook:~/scripts$ cell=${cell//-} kabary@handbook:~/scripts$ echo $cell 1123581321 تغيير حالة الحروف بين كبيرة وصغيرة في السلاسل النصية يتيح لنا باش تغيير حالة الحروف الأبجدية في السلاسل النصية من كبيرة إلى صغيرة أو بالعكس بسهولة. لننشئ في البداية سلسلتين نصيتين كما يلي: legend="john nash" actor="JULIA ROBERTS" لنحوّل حالة الحروف في السلسلة النصية الأولى "legend" من حروف صغيرة إلى حروف كبيرة، وفق التالي: kabary@handbook:~/scripts$ echo ${legend^^} JOHN NASH ولنحول أيضًا حروف السلسلة النصية "actor" إلى حروف صغيرة: kabary@handbook:~/scripts$ echo ${actor,,} julia roberts نستطيع أيضًا تحويل حالة الحرف الأول فقط في "legend" إلى حرف كبير: kabary@handbook:~/scripts$ echo ${legend^} John nash والحرف الأول فقط في "actor" إلى حرف صغير: kabary@handbook:~/scripts$ echo ${actor,} jULIA ROBERTS يمكننا أيضًا تحويل حالة حروف بعينها فقط من حروف كبيرة إلى صغيرة أو العكس؛ فعلى سبيل المثال يمكن تغيير الحرفين j و n من السلسلة النصية "legend" إلى حروف كبيرة كما يلي: kabary@handbook:~/scripts$ echo ${legend^^[jn]} JohN Nash الخلاصة بهذا نكون قد وصلنا إلى ختام المقال الذي شرحنا فيه كيفية التعامل مع السلاسل النصية في سكربتات باش، وسنتطرق في المقال القادم لشرح مهارات جديدة ونوضح طريقة اتخاذ القرار ضمن سكربتات باش من خلال الجمل الشرطية بمختلف أشكالها. ترجمة -وبتصرف- للمقال String Operations in Bash. اقرأ أيضًا المقال السابق: استخدام المعاملات الحسابية في سكربتات باش Bash أنواع المتغيرات في Bash ميزات صدفة Bash تنفيذ الأوامر في Bash
  5. تدخل العمليات الحسابية في العديد من سكربتات باش Bash Scripts، فقد تحتاج لحساب المساحة المتبقية من القرص الصلب مثلًا، أو حجوم الملفات أو عرض النطاق الترددي للشبكة، أو تواريخ انتهاء صلاحيات كلمات المرور، أو أعداد المضيفين hosts أو غير ذلك. وسنتعلم في مقالنا الخامس من سلسلة باش للمبتدئين طريقة استخدام معاملات باش bash operators لإجراء العمليات الحسابية داخل السكربت، وسنبدأ بجدول يتضمن المعاملات الحسابية: المعامل الوصف + الجمع - الطرح * الضرب / قسمة الأعداد الصحيحة بدون بواقي عشرية % قسمة المعاملات التي تُرجع باقي عملية القسمة فقط ** الأُس مثلًا x أُس y تنفيذ الجمع والطرح في باش لننشئ سكربت باش يدعى مثلًا addition.sh يجمع حجمي ملفين بالبايت Byte ويعطيك النتيجة، سنستعمل في السكربت وسطاء باش وقد شرحنا طريقة طريقة التعامل معها في مقال تمرير الوسطاء إلى سكربت باش، بالإضافة إلى الأمرين cut و du. يُستَخدَم الأمر du لمعرفة أحجام الملفات، ويمكن استخدام الراية أو الخيار d- بعد الأمر وهو اختصار لكلمة bytes لجعل المخرجات بالحجم الفعلي للملف بالبايتات فبدون هذا الخيار سيعرض du الحجم بالوحدة الافتراضية كيلوبايت. يُظهر هذا الأمر في النتيجة كلًا من اسم الملف وحجمه أي أنه يعطي عمودين أو مُخرَجَين، لذا سنحتاج الأمر cut لاقتطاع جزء النتيجة الذي نريده فقط وهو الحجم. وبالتالي سنستخدم أنبوب إعادة التوجيه | لتمرير خرج الأمر du إلى دخل الأمر cut. سيكون نص السكربت addition.sh كما يلي: #!/bin/bash fs1=$(du -b $1 | cut -f1) fs2=$(du -b $2 | cut -f1) echo "File size of $1 is: $fs1" echo "File size of $2 is: $fs2" total=$(($fs1 + $fs2)) echo "Total size is: $total" يحتاج السكربت السابق وسيطين، وهنا مرر له الملفين etc/passwd/ و etc/group/، ثم نفذنا السكربت وسنحصل على النتيجة التالية: kabary@handbook:~/scripts$ ./addition.sh /etc/passwd /etc/group File size of /etc/passwd is: 2795 File size of /etc/group is: 1065 Total size is: 3860 لاحظ السطر التالي الذي يتضمن عملية الجمع باستخدام المعامل +: total=$(($fs1 + $fs2)) ينبغي أن تكتب العمليات الحسابية دائمًا بين قوسين هلاليين مزدوجين (()) بالصيغة التالية: $((arithmetic-expression)) يمكنك استخدام معامل الطرح - بالطريقة نفسها، فمثلًا المتغير sub التالي سيحمل القيمة سبعة: sub=$((10-3)) تنفيذ عمليتي الضرب والقسمة في باش لننشئ سكربت بسيط اسمه giga2mega.sh مثلًا يجري عملية التحويل من جيجا بايت GB إلى ميجا بايت MB وفق التالي: #!/bin/bash GIGA=$1 MEGA=$(($GIGA * 1024)) echo "$GIGA GB is equal to $MEGA MB" لنُشغل السكربت الآن لنعرف كم تعادل 4 جيجا بايت بالميجا بايت: kabary@handbook:~/scripts$ ./giga2mega.sh 4 4 GB is equal to 4096 MB لقد استخدمنا معامل الضرب * لضرب عدد الجيجا بايت بالعدد 1024 للحصول على مكافئها بالميجا بايت: MEGA=$(($GIGA * 1024)) يمكنك تعديل السكربت نفسه ليحول الحجم من جيجا بايت إلى كيلو بايت: KILO=$(($GIGA * 1024 * 1024)) وبالطريقة نفسها حَوِّله إلى بايت. لنجرب الآن عملية القسمة باستخدام المعامل / كما يلي ونُخَزِّن النتيجة في المتغير div الذي سيحمل القيمة خمسة في مثالنا: div=$((20 / 4)) القسمة المستخدمة هنا هي قسمة الأعداد الصحيحة، وبالتالي ستكون النتيجة عددًا صحيحًا حتمًا، فلو قَسَّمتَ 5 على 2 باستخدام المعامل / فستحصل على 2 لأن هذه القسمة تهمل البواقي فهي لا تُرجع أعدادًا عشرية. kabary@handbook:~/scripts$ div=$((5 / 2)) kabary@handbook:~/scripts$ echo $div 2 إذا رغبت بالتعامل مع الأعداد العشرية فستحتاج للأمر bc، وهذا مثال على طريقة استخدامه مع القسمة الصحيحة: echo "5/2" | bc -l 2.50000000000000000000 وتبين الصورة أدناه استخدامه مع العمليات الحسابية الأخرى: استخدام الأس وباقي القسمة لننشئ سكربت اسمه power.sh يقبل وسيطين عدديين ليكونا مثلًا a و b، ويُظهر نتيجة b مرفوعًا للأُس b كما يلي: #!/bin/bash a=$1 b=$2 result=$((a**b)) echo "$1^$2=$result" إذًا فقد استخدمنا المعامل ** لحساب نتيجة a مرفوعًا للأس b، لنجرب السكربت على أعداد مختلفة كما يلي: kabary@handbook:~/scripts$ ./power.sh 2 3 2^3=8 kabary@handbook:~/scripts$ ./power.sh 3 2 3^2=9 kabary@handbook:~/scripts$ ./power.sh 5 2 5^2=25 kabary@handbook:~/scripts$ ./power.sh 4 2 4^2=16 سنتعلم الآن استخدام المعامل % أي باقي القسمة modulo، يرجع هذا المعامل باقي القسمة فقط ويكون عددًا صحيحًا، فالمتغير rem في المثال التالي سيحمل القيمة 2: rem=$((17%5)) الباقي هنا هو 2 لأننا نحصل على 17 بمضاعفة العدد 5 ثلاث مرات وإضافة 2 للنتيجة. إنشاء محول مقاييس لدرجات الحرارة باستخدام باش لنطبق مثالًا شاملًا يستخدم كل العمليات الحسابية التي تعلمناها في الفقرات السابقة، سنكتب سكربت جديد باسم c2f.sh يحول درجة الحرارة من درجة مئوية إلى فهرنهايت وفق المعادلة التالية: F = C x (9/5) + 32 الطريقة المستخدمة هنا هي إحدى الطرق المتبعة لكتابة هذا السكربت، مع العلم أنه توجد طرق أخرى تعطيك النتيجة نفسها، سنعرف بداية المتغيرات فالمتغيرCيمثل درجة الحرارة المئوية، والمتغيرFيمثل درجة الحرارة بالفهرنهايت. #!/bin/bash C=$1 F=$(echo "scale=2; $C * (9/5) + 32" | bc -l) echo "$C degrees Celsius is equal to $F degrees Fahrenheit." استخدمنا الأمر bc هنا لأننا نتعامل مع أعداد عشرية، والأمر scale=2 لإظهار خانتين فقط بعد الفاصلة العشرية. لنجري بعض الآن التحويلات باستخدام السكربت التالي الذي يقرأ درجة الحرارة المدخلة بالدرجة المئوية، وتحويلها إلى الفهرنهايت، ثم عرض النتيجة لكل قيمة مدخلة: kabary@handbook:~/scripts$ ./c2f.sh 2 2 degrees Celsius is equal to 35.60 degrees Fahrenheit. kabary@handbook:~/scripts$ ./c2f.sh -3 -3 degrees Celsius is equal to 26.60 degrees Fahrenheit. kabary@handbook:~/scripts$ ./c2f.sh 27 27 degrees Celsius is equal to 80.60 degrees Fahrenheit. الخلاصة إلى هنا نكون قد انتهينا من مقالنا الذي شرحنا فيه العمليات الحسابية الأساسية في سكربتات باش مع التطبيق العملي، نرجو أن يكون المقال قد قدم الفائدة المرجوة، وندعوك لمطالعة مقالنا التالي حول التعامل مع السلاسل النصية Strings في باش. ترجمة -وبتصرف- للمقال Using Arithmetic Operators in Bash Scripting. اقرأ أيضًا المقال السابق: استخدام المصفوفات في باش Bash قراءة وضبط متغيرات الصدفة Shell والبيئة في لينكس التوسعات في باش ميزات صدفة باش
  6. قد تحتاج في سكريتات باش للتعامل مع مئات المتغيرات التي يدخلها المستخدم وفي هذه الحالة لن يكون من المناسب أن تنشئ هذه المتغيرات يدويًا، وهنا يأتي دور المصفوفات Arrays الحل المنقذ في مثل هذه الحالات، سنشرح في هذا المقال أساسيات التعامل مع المصفوفات في باش وتعديلها بكفاءة. أنشئ مصفوفتك الأولى في باش لنفترض أنك تحتاج لكتابة سكربت بسيط لتحديث الطابع الزمني timestamp لخمس ملفات مختلفة، والطابع الزمنية هي مجموعة محارف وأرقام تدل على تاريخ ووقت إجراء تعديل معين على الملف. لننشئ السكربت timestamp.sh الخاص بهذه العملية أولًا بطريقة المتغيرات دون استخدام المصفوفات، فسيكون على الشكل التالي: #!/bin/bash file1="f1.txt" file2="f2.txt" file3="f3.txt" file4="f4.txt" file5="f5.txt" touch $file1 touch $file2 touch $file3 touch $file4 touch $file5 لننشئه الآن باستخدام المصفوفات ونلاحظ الفرق، سنخزن في المصفوفة أسماء الملفات الخمسة عوضًا عن تعريف خمس متغيرات تقابل أسماء الملفات الخمسة، وفيما يلي الصيغة العامة لتعريف المصفوفات في باش: array_name=(value1 value2 value3 … ) لنطبق الصيغة على حالتنا، فستكون مصفوفة أسماء الملفات وفق التالي: files=("f1.txt" "f2.txt" "f3.txt" "f4.txt" "f5.txt") السكربت الآن أوضح وأكثر كفاءة وأقرب لمعايير الكود النظيف، فقد استبدلنا خمسة متغيرات بمصفوفة واحدة فقط. الوصول لعناصر مصفوفات باش تبدأ فهرسة مصفوفات باش بالصفر 0 ويستخدم الدليل n-1 للوصول إلى العنصر n من المصفوفة. فإذا رغبنا بإظهار العنصر الثاني في المصفوفة فسنكتب التالي: echo ${files[1]} وللوصول للعنصر الثالث: echo ${files[2]} وهكذا لبقية العناصر. لنجرب أمرًا آخر، ألقِ نظرة على السكربت التالي reverse.sh الذي سيظهر كامل عناصر مصفوفتك بترتيب عكسي من العنصر الأخير إلى الأول: #!/bin/bash files=("f1.txt" "f2.txt" "f3.txt" "f4.txt" "f5.txt") echo ${files[4]} echo ${files[3]} echo ${files[2]} echo ${files[1]} echo ${files[0]} وستحصل بتنفيذه على الخرج التالي: سنتعلم لاحقًا كيف نظهر عناصر المصفوفة باستخدام الحلقات Loops، فتكرار الأمر echo للغرض نفسه عددً كبيرًا من المرات ليس الطريقة الأفضل لإظهار عناصر المصفوفة. يمكننا أيضًا إظهار عناصر المصفوفة دفعة واحدة في سطرٍ واحد كما في الأمر التالي: echo ${files[*]} f1.txt f2.txt f3.txt f4.txt f5.txt ويساعدك الأمر التالي على إظهار عدد عناصر المصفوفة الذي يسمى اصطلاحًا حجم المصفوفة size of array: echo ${#files[@]} 5 وبوسعك تغيير قيمة أي عنصر من عناصر المصفوفة بسهولة، ألقِ نظرة على السطر أدناه إذ نغير فيه قيمة العنصر الأول إلى القيمة "a.txt": files[0]="a.txt" إضافة عناصر جديدة إلى مصفوفة باش لننشئ مثلًا المصفوفة التالية التي تتضمن أسماء أشهر توزيعات لينكس: distros=("Ubuntu" "Red Hat" "Fedora") تحتوي المصفوفة الحالية على ثلاثة عناصر، ويمكنك إضافة عناصر أخرى إلى نهايتها باستخدام المعامل =+، دعنا نضيف مثلًا توزيعة Kali بكتابة: distros+=("Kali") تحتوي المصفوفة الآن أربعة عناصر، وتبين الصورة أدناه السكربت بعد إضافة العنصر الأخير: حذف عناصر من مصفوفة باش لننشئ مصفوفة تتضمن الأعداد من 1 إلى 5: num=(1 2 3 4 5) يمكنك إظهار كافة عناصر المصفوفة كما يلي: echo ${num[*]} 1 2 3 4 5 لنفترض أننا نرغب بحذف العنصر الثالث منها، فسنستخدم الأمر unset وفق التالي: unset num[2] أظهر الآن كافة عناصر المصفوفة كما يلي: echo ${num[*]} 1 2 4 5 ولاحظ حذف العنصر الثالث. يمكنك أيضًا حذف المصفوفة بالطريقة نفسها بكتابة الأمر أدناه: unset num تبين الصورة أدناه تنفيذ سكربت يتضمن كل ما تعلمناه في هذه الفقرة: إنشاء مصفوفة هجينة بأنواع مختلفة من البيانات تتميز باش عن الكثير من لغات البرمجة بقدرتها على إنشاء مصفوفات هجينة hybrid arrays تحتوي أنواعًا مختلفة من البيانات، مثلًا أعداد صحيحة وسلاسل نصية وغيرها كما في سكربت باش التالي باسم user.sh: #!/bin/bash user=("john" 122 "sudo,developers" "bash") echo "User Name: ${user[0]}" echo "User ID: ${user[1]}" echo "User Groups: ${user[2]}" echo "User Shell: ${user[3]}" لاحظ أن مصفوفة المستخدمين السابقة تتضمن أربع عناصر هي: العنصر "john" نوعه سلسلة نصية String العنصر 122 نوعه عدد صحيح Integer العنصر "sudo,developers" نوعه سلسلة نصية String العنصر "bash" نوعه سلسلة نصية String سيكون خرج السكربت على النحو التالي: الخلاصة نصل بذلك لنهاية مقال المصفوفات في لغة باش Bash الذي تعرفنا فيه على المصفوفات والوصول لعناصرها وعكس ترتيبها وتعديلها وإضافة وحذف عناصرها، كما تعرفنا على طريقة إلى إنشاء مصفوفات هجينة تحتوي على أنواع بيانات مختلفة، تابع المقال التالي حيث سنتعرف فيه على طريقة التعامل مع المعاملات الحسابية بكفاءة ضمن سكربتات باش Bash. ترجمة -وبتصرف- للمقال Using Arrays in Bash. المقال السابق: تمرير الوسطاء إلى سكربت باش Bash طريقة التعامل مع المتغيرات وتمرير الوسطاء لسكربت باش مدخل إلى صدفة باش Bash الحصول على مدخلات من لوحة المفاتيح وإجراء العمليات الحسابية في سكربتات الصدفة الأخطاء الشائعة التي تحدث عند كتابة سكربتات الصدفة
  7. يعرض المقال الثالث من سلسلة باش كيفية تمرير الوسطاء arguments إلى سكربتات الصدفة باش، وإضافةً للوسطاء سنتعرف على بعض المتغيرات الخاصة في صدفة باش. تعلمنا في المقال السابق كيف نستخدم المتغيرات لكتابة سكربتات باش عامة وديناميكية تتجاوب مع أنواع مختلفة من البيانات ومدخلات المستخدم، وسنتعلم هنا تمرير الوسطاء إلى سكربتات باش ضمن سطر الأوامر. تمرير وسيط إلى سكربت باش يحتسب السكربت count_lines.sh التالي عدد الأسطر الموجودة في أي ملف تزوده باسمه: #!/bin/bash echo -n "Please enter a filename: " read filename nlines=$(wc -l < $filename) echo "There are $nlines lines in $filename" يمكنك الرجوع للمقال الأول لتعرف كيف تُنشئ سكربت باش وتحوله لملف تنفيذي. لنفترض أننا نود حساب عدد الأسطر الموجودة في الملف etc/passwd/ فستكون نتيجة تنفيذ السكربت كما في الصورة التالية: يمكننا تسهيل العملية بتمرير اسم الملف للسكربت بصفته وسيط سطر أوامر يكتب معه في نافذة سطر الأوامر عند التشغيل كما يلي: ./count_lines.sh /etc/passwd يتطلب ذلك تعديلًا على السكربت نستخدم فيه المتغير 1$ الذي يشير إلى الوسيط الأول الذي سيتلقاه السكربت من سطر الأوامر (والذي يسمى المُحَدِّد الموضعي). لنستبدل إذًا المتغير filename الخاص باسم الملف بالمتغير 1$ في كامل السكربت count_lines.sh السابق، ليصبح كما يلي: #!/bin/bash nlines=$(wc -l < $1) echo "There are $nlines lines in $1" استغنينا بهذه الطريقة عن الأمر read والأمر echo الأول، فأصبح السكربت أقصر. يمكنك الآن تجربة السكربت على ملفات أخرى كما في المثال التالي: ./count_lines.sh /etc/group There are 73 lines in /etc/group تمرير عدة وسطاء إلى سكربت باش يمكنك تمرير أكثر من وسيط لسكربتات باش، وفق الصيغة التالية: script.sh arg1 arg2 arg3 … يشير المتغير 2$ للوسيط الثاني، والمتغير 3$ للوسيط الثالث وهكذا. أما المتغير 0$ فيشير إلى اسم السكربت، وهو أحد المتغيرات الخاصة في صدفة باش. لنُعدّل الآن السكربت السابق كما يلي ليقبل أكثر من ملف، ويحسب عدد الأسطر في كل واحد منها: #!/bin/bash n1=$(wc -l < $1) n2=$(wc -l < $2) n3=$(wc -l < $3) echo "There are $n1 lines in $1" echo "There are $n2 lines in $2" echo "There are $n3 lines in $3" يمكنك الآن تشغيل السكربت، وتمرير ثلاثة ملفات نصية له، لتحصل على أعداد الأسطر فيها كما يلي: إذا فقد أعطانا السكربت عدد الأسطر في كل ملف من الملفات الثلاثة، وبالترتيب نفسه المكتوبة به، فترتيب تمرير الوسطاء للسكربت مهم لضمان دقة التنفيذ. أبدِع في استخدام وسطاء باش يساعدك استخدام وسطاء باش على تبسيط أوامر لينكس الطويلة أو المعقدة التي تحتاج لضبط الكثير من الخيارات، إذ يمكنك تحويلها لسكربتات باش بسيطة، وتشغيلها بعد تزويدها بالوسطاء. ألقِ نظرة على سكربت باش find.sh التالي لتوضيح الأمر: #!/bin/bash find / -iname $1 2> /dev/null يساعدك هذا السكربت في العثور على الملفات، وستجد استخدامه أسهل من كتابة أمر البحث الطويل في كل مرة تحتاج فيها لإيجاد ملف، فقط مرر اسم الملف الذي تبحث عنه بصفته وسيطًا للسكربت وسيعرض لك موقعه. وبالطريقة نفسها يمكنك تحويل أي أمر طويل ومعقد من أوامر لينكس إلى سكربت باش سهل الاستخدام. أما التعليمة: ‏‎2> /dev/null الواردة في السكربت فتحجب رسائل الخطأ مثل (لا يمكن الوصول للملف أو غيرها) من الظهور على الشاشة. أشهر المتغيرات الخاصة في باش توفر لك صدفة باش مجموعة من المتغيرات الخاصة المُضمنة فيها، وتُعدّ مفيدة جدًا في أي سكربت. يتضمن الجدول أشهرها: المتغير الخاص الوصف $0 اسم السكربت $1, $2…$n وسطاء سطر الأوامر $$ مُعرّف العملية process id للصدفة shell الحالية #$ العدد الكلي للوسطاء المُمَرَّة إلى السكربت @$ قيم جميع الوسطاء المُمَرَّة إلى السكربت ?$ حالة الخروج لآخر أمر مُنَفذ !$ مُعرّف العملية لآخر أمر مُنَفذ يعطيك السكربت Variables.sh التالي مثالًا عمليًّا بسيطًا عن المتغيرات الخاصة: #!/bin/bash echo "Name of the script: $0" echo "Total number of arguments: $#" echo "Values of all the arguments: $@" مرر عدد من الوسطاء التجريبية، ثم شغل السكربت، ولاحظ النتائج: وفي الختام ننصحك بالتدرب أكثر على استخدام وسطاء باش حتى تتقن استخدامها بشكل جيد، وندعوك لمتابعةبقية المقالات في هذه السلسلة للتعرف أكثر على لغة باش واحترافها. ترجمة -وبتصرف- للمقال Passing Arguments to Bash Scripts لصاحبه Kabary. اقرأ أيضًا المقال السابق: المتغيرات في سكربتات الصدفة باش مفهوم واصفات الملفات File Descriptors وارتباطها بعملية التجريد في أنظمة التشغيل أنشئ برنامجك النصي الأول على صدفة باش Bash احترف الأمر ls في لينكس
  8. المتغيرات Variables جزءٌ أساسي من أي مشروع برمجي، لا بدّ أنك تعاملت معها من قبل، وإن كنت لا تملك معرفةً مسبقة بها، فيمكنك تشبيهها بحاويات التخزين فهي تُخَزِّن أجزاءً من المعلومات قد تتغير قيمها مع الزمن. ويتناول مقالنا الثاني من سلسلة باش Bash للمبتدئين طريقة استخدام المتغيرات في كتابة سكربتات الصدفة باش bash shell scripts، تابع معنا أمثلة المقال لتتعلم استعمال المتغيرات لكتابة سكربتات باش. استخدام المتغيرات في سكربتات الصدفة باش تعلمنا في المقال السابق كيفية إنشاء سكربت باش بسيط يعرض عبارة " hello world"، اسمه "hello.sh" ويتضمن المحتوى التالي: #! /bin/bash echo 'Hello, World!' لنحاول تطوير هذا السكربت البسيط ليتظهر اسم المستخدم في عبارة الترحيب، سنستخدم لذلك المتغيرات والأمر read القادر على استلام المدخلات من المستخدمين، يمكنك مطالعة هذا المقال للحصول على معلومات أكثر عن read، والآن افتح الملف "hello.sh" وعدّل محتواه ليصبح كما يلي: #! /bin/bash echo "What's your name, stranger?" read name echo "Hello, $name" إذا شغلت السكربت سيُطالبك بإدخال اسمك ثم سيرحب بك بالاسم الذي زودته به، وفق التالي: abhishek@handbook:~/scripts$ ./hello.sh What's your name, stranger? Elliot Hello, Elliot إذًا سيسألك البرنامج عن اسمك، ثم تزوده به، وبعدها سيظهر اسمك في عبارة الترحيب. وهذا ملخص لما نفذناه حتى الآن: الشرح التفصيلي للسكربت السابق لنراجع نص السكربت سطرًا سطرًا مع توضيح دلالة كل سطر. يتضمن السطر الأول رمز التوجيه shebang ليوضح لمُفسر الأوامر أننا سنستخدم الصدفة باش لتنفيذ السكربت. #!/bin/bash وفي السطر الثاني أظهرنا العبارة التالية التي تطلب من المستخدم إدخال اسمه: echo "What's your name, stranger?" ونفذنا ذلك باستخدام أمر بسيط هو echo الذي يعرض العبارة المكتوبة بعده على شاشة الطرفية. ثم السطر الثالث، وهو الجزء الأهم الذي أحدث تطورًا في السكربت: read name استخدمنا فيه الأمر read لنقل التحكم من السكربت إلى المستخدم ليستطيع إدخال اسمه وتخزينه في متغير يدعى name. وفي السطر الأخير يستخدم السكربت المتغير name ويرحب بالمستخدم باسمه: echo “Hello, $name” تُكتب إشارة "$" قبل اسم المتغير للحصول على القيمة المخزنة فيه، أو لو كتبت name فقط في السطر السابق بدلًا من name$ فتظهر العبارة "Hello, name" عوضًا عن الترحيب بالمستخدم باسمه (الذي هو قيمة المتغير). ملاحظة: تعرف إشارة "$" في سكربتات باش بأنها معامل تحصيل dereference operator لتحصيل قيمة معينة من موقعها في الذاكرة. إنشاء متغيرات بأنواع بيانات مختلفة يمكن إنشاءمتغيرات بأنواع بيانات مختلفة مثل الأعداد والمحارف والسلاسل النصية، وتستخدم إشارة المساواة "=" لإنشاء المتغيرات وإسناد القيم الافتراضية لها، ففي السطر التالي مثلًا أنشأنا متغيرًا يدعى age وأسندنا له القيمة 27. age=27 يمكنك تغيير قيمة المتغير لاحقًا بقدر ما تريد، فالسطر التالي مثلًا يغيرها من 27 إلى 3: age=3 تحمل المتغيرات أنواعًا مختلفة من البيانات، مثل الأعداد الصحيحة، والمحارف، والسلاسل النصية، وباش لا تحدد الأنواع بشكل صارم كما في بعض لغات البرمجة الأخرى، فلا حاجة لتحديد نوع المتغير مسبقًا ويمكنك وضع أي نوع ضمن المتغير. ألقِ نظرة على الأمثلة التالية: letter=’c’ color=’blue’ year=2020 المتغيرات الثابتة في سكربت باش المتغير الثابت constant variable هو متغير ذو قيمة ثابتة لا تتغير أبدًا، تُنشِئه بواسطة الأمر readonly كما يلي: readonly PI=3.14159 أنشأ الأمر السابق متغيرًا ثابتًا يدعى PI يحمل القيمة 3.14159، وإذا حاولت تغيير قيمته فلن تتمكن من ذلك وستحصل على الخطأ التالي: bash: PI: readonly variable إذًا المتغيرات الثابتة هي متغيرات للقراءة فقط، يمكنك قراءة قيمتها فقط، ولا تستطيع تغييرها أبدًا بعد إنشائها. تعويض الأوامر Command substitutions تعويض الأوامر Command substitutions هو تخزين نتيجة أمر في متغير، ويُعدّ من أبرز مميزات البرمجة النصية باستخدام صدفة باش. والأمر date الخاص بإظهار التاريخ الحالي من أشهر الأمثلة على تعويض الأوامر، ألقِ نظرة على السطر التالي: TODAY=$(date) حسب السطر السابق يُخَزَّن خرج الأمر date في المتغير TODAY، ولاحظ أن الأمر المستخدم لتعويض الأوامر يُكتب بين قوسين هلاليين ويُسبَق بإشارة الدولار "$" على يساره. تبين الصورة أدناه كيف أخذ المتغير TODAY قيمة خرج الأمر date: يمكنك أيضًا كتابة تعويض الأوامر بوضع الأمر بين علامتي اقتباس مائلة للخلف back quotes وفق التالي، بدلًا من وضعه بين قوسين مع إشارة الدولار: TODAY=`date` لكننا ننصحك بعدم استخدام هذه الطريقة في كتابة تعويض الأوامر لأنها قديمة ولم تعد مستخدمة، احرص دائمًا على استخدام الطريقة الحديثة ذات الصيغة التالية: variable=$(command) مثال عملي على تعويض الأوامر في آخر تحديث أجريناه على السكربت "hello.sh" كنا نطلب من المستخدم إدخال اسمه ليستخدمه البرنامج في رسالة الترحيب. أما الآن -وبالاعتماد على تعويض الأوامر- لن نسأل المستخدم عن اسمه بل سنستعين بأمر خاص يدعى whoami يعطينا اسم المستخدم الحالي. عدّل محتوى الملف "hello.sh" ليصبح كما يلي: #! /bin/bash echo "Hello, $(whoami)" لاحظ الاختصار الذي طرأ على حجم السكربت فقد أصبح يقتصر على سطرين فقط، شغّل السكربت الآن: ./hello.sh سيؤكد لك الخرج نجاح العملية، فسيظهر اسم المستخدم الحالي في رسالة الترحيب، وتلخص هذه الصورة ما طبقناه هنا: وصلنا إلى نهاية المقال نأمل أنه كان مفيدًا ووضح لك طريقة استخدام المتغيرات في سكربتات باش، حاول تطبيق أمثلة أخرى لتزيد مهاراتك في العمل مع المتغيرات، وتابع مقالنا التالي لتتعرف على كيفية تمرير الوسطاء لسكربت باش. ترجمة -وبتصرف- للمقال Understanding Variables in Bash Shell Scripting. اقرأ أيضًا المقال السابق: أنشئ برنامجك النصي الأول على صدفة باش Bash مدخل إلى صدفة باش Bash دليل ميَسَّر لكتابة سكربتات Shell مدخل إلى كتابة سكربتات الصدفة الحصول على مدخلات من لوحة المفاتيح وإجراء العمليات الحسابية في سكربتات الصدفة (Shell Scripts)
  9. كتابة سكربتات باش Bash Scripting مهارة أساسية لا غنى عنها لكل مدير نظام ومهندس DevOps، فإذا كنت ترغب بتطوير مهاراتك في هذا المجال سواءً كنت مبتدئًا أو متمرسًا في نظام لينكس فإن هذه السلسلة التي تشرح Bash للمبتدئين ستلبي طلبك، بما تقدمه من أمثلة وتطبيقات عملية على أساسيات باش بدايةً من إنشاء السكريبت وحتى أتمتة تنفيذه على الخادم، وتتضمن هذه السلسلة المقالات التالية: أنشئ برنامجك النصي الأول على صدفة باش Bash المتغيرات في سكربتات الصدفة باش Bash تمرير الوسطاء إلى سكريبت باش Bash استخدام المصفوفات في باش Bash استخدام المعاملات الحسابية في سكربتات باش Bash عمليات السلاسل النصية في باش Bash الجمل الشرطية في باش Bash الحلقات في باش Bash استخدام الدوال في باش Bash أتمتة المهام باستخدام باش Bash هذا هو المقال الأول في هذه السلسلة، إذ ستتعرف فيه على كيفية إنشاء سكريبت باش bash script يفيدك في أتمتة المهام الروتينية على الخادم، إذ كثيرًا ما نجد أنفسنا ننفذ المهام نفسها مرارًا وتكرارًا، بداية من النسخ الاحتياطي للمجلدات، وتنظيف الملفات المؤقتة، وحتى استنساخ cloning قواعد البيانات. سننشئ معًا سكريبت باش بسيط ونقوم بتشغيله، ونستعرض بعض الأساسيات التي ينبغي لك معرفتها عن كتابة سكربتات الصدفة Shell عمومًا. إنشاء سكريبت Shell وتشغيله أنشئ في البداية مجلدًا جديدًا اسمه "scripts" سنُخَزِّن فيه جميع السكربتات التي سننشئها في أثناء تطبيق أمثلة المقال، ثم انتقل للعمل ضمنه، بكتابة التالي: mkdir scripts cd scripts أنشئ ضمن المجلد السابق ملفًا نصيًّا باسم hello.sh باستخدام الأمر cat وفق التالي، أو أنشئه بأي طريقة أخرى تفضلها: cat > hello.sh يمكنك الآن الكتابة ضمن الملف من الطرفية terminal مباشرةً فاكتب السطر التالي: echo 'Hello, World!' ثم اضغط على Ctrl+D لحفظ التغييرات على الملف، والخروج من الأمر cat. تستطيع الكتابة ضمن الملف بالطريقة التي تناسبك باستخدام محررات النصوص العاملة في الطرفية مثلًا وأبرزها Vim و Emacs و Nano، أو محررات النصوص ذات الواجهة الرسومية نحو Gedit إذا كنت تستخدم إحدى بيئات سطح المكتب لنظام لينكس. يعرض الأمر echo العبارة "Hello World" المكتوبة بعده على الشاشة، وهدفنا هنا تشغيل echo على أنه سكريبت shell بدلًا من تشغيله بالطريقة العادية أي بكتابته ضمن الطرفية. بعد إنشاء الملف "hello.sh" سنحوله إلى ملف تنفيذي باستخدام الأمر chmod، كما يلي: chmod u+x hello.sh يمكنك معرفة المزيد عن chmod وغيره من أوامر لينكس الشهيرة بمطالعة المقال مرجع إلى أشهر أوامر لينكس. والآن لنشغّل السكريبت بكتابة الأمر "bash" قبل اسم الملف "hello.sh"، وفق التالي: bash hello.sh ستظهر العبارة !Hello, World أمامك على الشاشة مشيرةً لنجاح تنفيذ السكربت. ألقِ نظرة على الصورة أدناه فهي تتضمن ملخصًا للأوامر التي نفذناها حتى الآن. تحويل سكريبت Shell إلى سكريبت Bash يخلط البعض بين shell و bash، وهما مرتبطان بالفعل، لكن Shell أعَمّ من باش. فكلمة باش Bash اختصار للعبارة الإنجليزية "Bourne-Again shell"، وهي واحدة من أشهر أنواع الصدفات Shells المتاحة في لينكس. أما الصدفة shell فهي مُفَسِّر interpreter لسطر الأوامر يستقبل الأوامر المدخلة من المستخدم ويُشغلها، وله عدة أنواع. فأنت إذًا تستخدم الصدفة shell في كل مرة تكتب فيها أوامر لينكس، وعندما تفتح الطرفية على حاسوبك فأنت فعليَّا تشغل الصدفة الافتراضية لنظام لينكس الذي تستعمله. وباش هو الصدفة الافتراضية لمعظم توزيعات لينكس، لذا يستخدم في معظم الأحيان مرادفًا للصدفة shell. يوجد تشابه كبير في قواعد كتابة السكربتات بين أنواع الصدفات المختلفة، ولكنها مع ذلك تتباين في بعض الأحيان، فعلى سبيل المثال تبدأ فهرسة المصفوفات من "1" في صدفة Zsh بينما تبدأ من "0" في صدفة باش، وبالتالي فأي سكريبت مكتوب لصدفة Zsh ويتضمن مصفوفات، لن يعمل بطريقة صحيحة في صدفة باش. وهنا يأتي دور شيبانج shebang وهو السطر الذي تبدأ به كل سكربتات باش، فهو يوضح للمُفَسِّر أن السكريبت مكتوب للصدفة باش وليس لغيرها. السطر Shebang في بداية كل سكريبت يُقصد بسطر shebang العبارة bin/bash/ !# التي تكتب في السطر الأول من كل سكريبت باش، ويدعوه البعض hashbang لأنه يبدأ بالمحرفين هاش "#" hash وبان "!" ban. لاحظ كيف سيبدو السكريبت الذي أنشأناه قبل قليل بعد إضافة هذا السطر: #! /bin/bash echo 'Hello, World!' إذًا يخبر السطر bin/bash/ !# نظام التشغيل بنوع الصدفة أو المُفَسِّر الذي تود أن تستخدمه لتشغيل السكربت، فبعد إضافة هذا السطر إلى ملفنا السابق "hello.sh" سيعمل مباشرة بواسطة باش دون الحاجة لكتابة كلمة "bash'' قبل اسم الملف عند استدعائه كما فعلنا سابقًا. انظر الصورة أدناه: تشغيل السكريبت من أي مجلد بإضافة مساره للمتغير PATH إذا دققت في الصورة السابقة ستجد أننا استخدمنا البادئة /. قبل اسم السكريبت المُراد تشغيله للدلالة على مساره (فهو موجود في مجلد العمل الحالي)، وفي حال حذفت البادئة فستحصل على خطأ مثل التالي: abhishek@handbook:~/scripts$ hello.sh hello.sh: command not found فقد بَدَا اسم الملف للصدفة باش على أنه أمر برمجي يدعى hello.sh، وبدأ باش يبحث عن مساره بين المسارات المحددة في المتغير PATH، فمسارات حفظ جميع الأوامر التي تُشغلها الصدفات تخزن في هذا المتغير. يمكنك استعراض محتويات المتغير PATH باستخدام الأمر echo وفق ما يلي: echo $PATH /home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin تفصل النقطتان الرأسيتان ":" بين المسارات الموجودة ضمن PATH والتي تفحصها صدفات shell عند تنفيذ أي أمر. يمكنك تشغيل أوامر لينكس مثل: echo و cat وغيرها من أي مجلد على الخادم لأن أماكن وجود ملفاتها التنفيذية معروفة للنظام فهي مُخَزَّنِة ضمن مجلدات bin، وجميع مجلدات bin مذكورة في المتغير PATH كما رأينا في خرج التعليمة السابقة، والمسارات الموجودة في PATH هي الأماكن التي يبحث فيها النظام عن الملف التنفيذي لأي أمر تطلب تشغيله. خلاصة القول إذا أردت تشغيل سكريبت باش الخاص بك من أي مجلد في نظام التشغيل كما لو أنه أمرٌ أساسي من أوامر النظام فأضف مسار وجوده إلى المتغير PATH، وفق الخطوات التالية. أولًا حدد مسار حفظ السكريبت بدقة، يمكنك استخدام الأمر pwd إذا كان السكريبت موجود في مجلد عملك الحالي: pwd بعد أن تحصل على المسار (وهو المجلد "scripts" في مثالنا)، استخدم الأمر export لإضافته إلى المتغير PATH كما يلي: export PATH=$PATH:/home/user/scripts ملاحظة: بعد إضافة المجلد scripts إلى نهاية متغير PATH، فهذا يعني أن النظام سيبحث في المجلدات القياسية أولاً قبل أن يبحث في المجلد scripts. إذا كان لديك نسخ من نفس البرنامج في عدة دلائل، فإن هذا الترتيب يضمن أن النسخة الموجودة في المجلدات القياسية، بمعنى سيفحص نظام التشغيل المجلدات التي تتواجد مساراتها في المتغير PATH بالترتيب، وبالتالي فهو يبحث أولًا في المجلدات القياسية لحفظ السكربتات، ثم يأتي إلى المجلدات المخصصة التي أضافها المستخدم. شغّل الآن السكريبت بكتابة اسمه مباشرةً في الطرفية مثل أي أمر من أوامر لينكس العادية ولاحظ النتيجة، وفق التالي: abhishek@handbook:~/scripts$ hello.sh Hello, World! وهذا ملخص للأوامر التي نفذناها هنا: تهانينا، لقد أنجزت السكريبت الأول لك في باش، تابع معنا بقية مقالات السلسلة لنتعلم أكثر عن متغيرات الصدفة، ونجرب معًا أمثلة متنوعة أخرى عن باش bash وطريقة التعامل معها بكفاءة. ترجمة -وبتصرف- للمقال Create and Run Your First Bash Shell Script. اقرأ أيضًا مدخل إلى صدفة باش Bash دليل ميَسَّر لكتابة سكربتات Shell الأخطاء الشائعة التي تحدث عند كتابة سكربتات الصدفة (Shell Scripts) تعديل سكربتات الصدفة (Shell Scripts) الموجودة على حاسوبك
×
×
  • أضف...