-
المساهمات
24 -
تاريخ الانضمام
-
تاريخ آخر زيارة
المعلومات الشخصية
-
النبذة الشخصية
مهندس اتصالات من سوريا
آخر الزوار
1741 زيارة للملف الشخصي
إنجازات رشا سعد

عضو نشيط (3/3)
11
السمعة بالموقع
-
تُعدّ أتمتة المهام المتكررة هدفًا ضمنيًا لكل مستخدم يتعلم أساسيات باش، فهي في الغالب الغاية الأساسية من كل سكربت نكتبه، وسنعرض في هذا المقال مجموعة سكربتات مفيدة يمكنك الاستناد عليها لتتعلم أتمتة أي مهمة تريدها على خوادم لينكس، سنستخدم هنا جميع المهارات التي تعلمناها خلال السلسلة بدايةً من المصفوفات والجمل الشرطية وكذلك الحلقات والمفاهيم الأخرى. إنشاء سكربت باش لإدارة المستخدمين تُعدّ عملية إنشاء مستخدم على خوادم متعددة مهمة تقليدية لأي مدير نظام، لكنها مع التكرار تصبح مملة وشاقة، سننشئ معًا سكربت باش يؤتمت هذه العملية ويُنشئ المستخدمين تلقائيًا. سنُجهّز في البداية ملفًا نصيًّا يتضمن الأسماء hostnames أو عناوين IP للخوادم المطلوب إنشاء المستخدم عليها. يبين الملف servers.txt التالي على سبيل المثال أسماء خمسة خوادم: kabary@handbook:~$ cat servers.txt server1 server2 server3 server4 server5 لقد استخدمنا أسماء الخوادم هنا بدلًا من عناوين IP الخاصة بها لأن هذه العناوين مخزنة لدينا في الملف "etc/hosts/" الذي يتضمن الاسم hostname وعنوان IP المقابل له، وتستطيع أيضًا استخدام ملف إعدادات SSH. والآن لنفحص سكربت إنشاء المستخدمين adduser.sh التالي: #!/bin/bash servers=$(cat servers.txt) echo -n "Enter the username: " read name echo -n "Enter the user id: " read uid for i in $servers; do echo $i ssh $i "sudo useradd -m -u $uid $name" if [ $? -eq 0 ]; then echo "User $name added on $i" else echo "Error on $i" fi done عند تنفيذ السكربت سيطلب منا إدخال اسم المستخدم والمُعرِّف الخاص به، ثم سيتصل السكربت بكل خادم من الخوادم المحددة في الملف servers.txt السابق عبر اتصال SSH ويُنشئ عليه المستخدم الذي طلبناه. ننصح بمطالعة المزيد عن تقنية SSH للاتصال بالخوادم البعيدة عبر مشاهدة الفيديو التالي: لنلاحظ الآن طريقة عمل السكربت بعد التنفيذ: بهذا نكون قد نجحنا في إنشاء مستخدم يدعى ansible على الخوادم الخمسة المطلوبة. يوجد نقطتان مهمتان للغاية يتوجب علينا فهمها عند التعامل مع سكربت من هذا النوع: ضرورة استخدم مفاتيح مرور pass phrases فارغة لجلسات ssh، أو استخدم الوكيل ssh-agent لتمرير هويتنا إلى الخادم البعيد حتى لا نضطر لإدخال كلمة المرور في أثناء عمل السكربت الحرص على امتلاك حساب مستخدم فعال وعالي الصلاحيات يتمتع بأذونات الوصول إلى جميع الخوادم المطلوبة بدون متطلبات تتعلق بكلمة المرور تخيل أنك تحتاج لتعرف مستخدمين جدد على مائة خادم مثلًا، فكم ستكون العملية طويلة وشاقة، هنا تكمن أهمية الأتمتة إذ توفر عليك ساعات من العمل المضني. أتمتة عمليات النسخ الاحتياطي النسخ الاحتياطي مهمة أساسية لا غنى عنها في كل منظومة، وكثيرًا ما نستخدم سكربتات باش لأتمتة المهام، يبين السكربت backup.sh التالي مثالًا عليها: #!/bin/bash backup_dirs=("/etc" "/home" "/boot") dest_dir="/backup" dest_server="server1" backup_date=$(date +%b-%d-%y) echo "Starting backup of: ${backup_dirs[@]}" for i in "${backup_dirs[@]}"; do sudo tar -Pczf /tmp/$i-$backup_date.tar.gz $i if [ $? -eq 0 ]; then echo "$i backup succeeded." else echo "$i backup failed." fi scp /tmp/$i-$backup_date.tar.gz $dest_server:$dest_dir if [ $? -eq 0 ]; then echo "$i transfer succeeded." else echo "$i transfer failed." fi done sudo rm /tmp/*.gzecho "Backup is done." لنشرح السكربت أعلاه: أنشأنا في البداية مصفوفة تدعى backup_dirs سنكتب فيها أسماء المجلدات التي نريد أخذ نسخ احتياطية عنها، ثم عرّفنا ثلاثة متغيرات: dest_dir: لتحديد مجلد الوجهة الذي ستُحفظ فيه النسخ الاحتياطية dest_server: لتعيين الخادم الهدف backup_time: لتحديد تاريخ بدء عملية النسخ الاحتياطي وبعدها أنشأنا حلقة for ستمر على المجلدات الموجودة في المصفوفة "backup_dirs" واحدًا واحدًا وتضغط كل مجلد منها باستخدام التعليمة tar وتحتفظ بالنسخة المضغوطة في المجلد المؤقت tmp/، ثم تنسخها إلى الخادم الهدف بواسطة التعليمة scp، وبعد اكتمال النسخ ستُحذف الملفات المضغوطة من المجلد tmp/. يبين الخرج التالي أمثلة على طريقة عمل السكربت: kabary@handbook:~$ ./backup.sh Starting backup of: /etc /home /boot /etc backup succeeded. etc-Aug-30-20.tar.gz 100% 1288KB 460.1KB/s 00:02 /etc transfer succeeded. /home backup succeeded. home-Aug-30-20.tar.gz 100% 2543KB 547.0KB/s 00:04 /home transfer succeeded. /boot backup succeeded. boot-Aug-30-20.tar.gz 100% 105MB 520.2KB/s 03:26 /boot transfer succeeded. Backup is done. يمكننا جدولة السكربت باستخدام مهام cron job لتبدأ أعمال النسخ الاحتياطي عند منتصف الليل مثلًا، وذلك وفق التالي: kabary@handbook:~$ crontab -e 0 0 * * * /home/kabary/scripts/backup.sh يمكن معرفة المزيد عن جدولة المهام بواسطة cron بالاطلاع على الفيديو التالي على قناة أكاديمية حسوب: مراقبة المساحات التخزينية المتوفرة على القرص الصلب المساحات التخزينية على نظام الملفات في تناقص دائم وهذا أمرٌ مفروغٌ منه، وكل ما نستطيع القيام به تجاه هذا الأمر هو المراقبة والتصرف بالوقت المناسب حتى يؤدي التناقص المستمر إلى نفاذ المساحة وتعطل النظام، يساعدنا الأمر df على عرض المساحات المتوفرة على أي نظام ملفات، وهذا مثال على استخدامه: kabary@handbook:~$ df -h / /apps /database Filesystem Size Used Avail Use% Mounted on /dev/sda5 20G 7.9G 11G 44% / /dev/mapper/vg1-applv 4.9G 2.4G 2.3G 52% /apps /dev/mapper/vg1-dblv 4.9G 4.5G 180M 97% /database كما نلاحظ هنا فالمساحة المخصصة لقاعدة البيانات database/ على نظام الملفات هذا تكاد تنفذ فنسبة استخدامها 97%، يمكنك عرض نسبة الاستخدام فقط بدون التفاصيل الأخرى بواسطة الأمر awk. دعونا لنستعمل الآن هذين الأمرين في السكربت disk_space.sh كما يلي: #!/bin/bash filesystems=("/" "/apps" "/database") for i in ${filesystems[@]}; do usage=$(df -h $i | tail -n 1 | awk '{print $5}' | cut -d % -f1) if [ $usage -ge 90 ]; then alert="Running out of space on $i, Usage is: $usage%" echo "Sending out a disk space alert email." echo $alert | mail -s "$i is $usage% full" your_email fi done يبدأ السكربت بإنشاء مصفوفة تدعى filesystems نكتب فيها أسماء مسارات أنظمة الملفات التي نود مراقبتها، ويوجد بعدها حلقة تكرار تُنَفذ عند كل عنصر من عناصر المصفوفة، وتستعلم عن نسبة استخدام المساحة التخزينية المخصصة له فإذا كانت أكبر من 90% سيُرسل لنا السكربت تنبيهًا عبر البريد الإلكتروني يخبرنا بأن المساحة على وشك النفاذ. ملاحظة: لاستخدام السكربت السابق يتوجب استبدال your_email بعنوان بريد إلكتروني حقيقي. سنحصل على هذا الخرج بعد تنفيذ السكربت: kabary@handbook:~$ ./disk_space.sh Sending out a disk space alert email. وستكون رسالة البريد الإلكتروني مشابهة للتالي: لنفترض الآن أننا نرغب بجدولة السكربت disk_space.sh ليعمل كل ست ساعات مرة باستخدام مهام cron، فسنكتب التالي: kabary@handbook:~$ crontab -e 0 */6 * * * /home/kabary/scripts/disk_space.sh الخاتمة وصلنا لنهاية مقالنا الذي عرضنا لكم فيه أمثلة بسيطة توضح أتمتة المهام بواسطة سكربتات باش، إن الإمكانات الفعلية لباش أكبر بكثير، لذا ندعوكم لتجربة تطوير السكربتات الموجودة هنا وتنفيذ أفكار أخرى مختلفة لتقوية مهاراتكم في باش واكتساب القدرة على أتمتة أي عمل تحتاجه على خوادم لينكس، كانت هذه نصيحتنا في ختام سلسلتنا التعليمية عن باش، نذكرك أخيرًا برابط سلسلة تعلم البرمجة باستخدام باش . ترجمة -وبتصرف- للمقال Automation With Bash. اقرأ أيضًا المقال السابق: استخدام الدوال في باش Bash استخدام المعاملات الحسابية في سكربتات باش Bash عمليات السلاسل النصية في باش Bash الجمل الشرطية في باش Bash الحلقات في باش Bash
-
تساعد الدوال البرمجية على تنظيم سكربتات باش وجعلها أسهل في القراءة، وخاصة السكربتات كبيرة الحجم، إذ يمكننا استدعاء الدالة لأداء المهمة نفسها في عدة مواضع داخل السكربت دون الحاجة لتكرار كتابة التعليمات البرمجية الخاصة بهذه المهمة أكثر من مرة. سنتعلم في هذا المقال كيفية إنشاء الدوال البرمجية 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
-
الحلقات 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
-
سنتعلم في هذا المقال كيفية استخدام الجمل والعبارات الشرطية الشائعة مثل 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
-
كثيرًا ما يتردد على مسامعنا مصطلح تعلم الآلة Machine Learning في الآونة الأخيرة، ويزداد الاهتمام به يومًا بعد يوم، فما هو تعلم الآلة بالضبط؟ وما هي أفضل أطر العمل البرمجية والأدوات التي تساعدنا على استثماره وتحقيق أقصى استفادة منه في مشاريعنا؟ هذا ما سنتعرف عليه في مقال اليوم. ما هو تعلم الآلة هناك تعريفات متنوعة لتعلم الآلة تصب جميعها في الفكرة الأساسية التالية: تعلم الآلة Machine Learning أو ML اختصارًا، هو ببساطة جعل الحاسوب يتعلم الأشياء من تلقاء نفسه، وهذا هو الرابط بين تعلم الآلة والذكاء الاصطناعي AI، فالذكاء الاصطناعي يعني جعل الآلة تفكر وتتعلم كما يفعل الإنسان. إذًا كيف ننجح في جعل الحاسوب يتعلم من تلقاء نفسه؟ أسهل طريقة لتحقيق ذلك هي باستخدام أطر عمل الذكاء الاصطناعي AI Frameworks فهي الطريقة المثلى للنجاح، وقبل أن نتعرف على هذه الأطر دعنا نستذكر في البداية معنى إطار العمل في البرمجة. إطار العمل framework في جوهره هو طريقة لتنفيذ العمل، فمن خلالها يمكن تنظيم العمل البرمجي وتهيئة البيئة المناسبة لتحسين عملية التطوير وتسريعها، ولعل الكفاءة والفعالية هي أبرز فوائد استخدام إطار العمل. سنعرض في هذا المقال 11 إطار عمل شهير من أفضل أطر عمل الذكاء الاصطناعي التي يمكننا استخدامها في مشاريع تعلم الآلة، وهي: تنسرفلو TensorFlow تورش Torch ثينو Theano كافيه Caffe كيراس Keras إطار عمل مايكروسوفت CNTK ساي كيت ليرن Scikit-learn أزور Azure ML Studio أكورد دوت نت Accord.NET سبارك Spark MLlib إطار عمل أمازون لتعلم الآلة Amazon Machine Learning دعونا نوضح كل إطار من هذه الأطر وأبرز مميزاته واستخداماته بمزيد من التفصيل 1. تنسرفلو TensorFlow يتمتع إطار العمل تنسرفلو TensorFlow بالعديد من المميزات التي تجعله خيارًا مناسبًا للمطورين الباحثين عن أداة فعالة لمشاريع الذكاء الاصطناعي، ولعل أبرز مميزاته أنه من تطوير شركة جوجل العالمية التي تمنحه دعمًا واسع النطاق وتوفر له تحديثات منتظمة ومستمرة لجعله يواكب آخر مستجدات التعلم الآلي. ولا يخفى على أحد الدعم رفيع المستوى الذي تقدمه شركة بعراقة جوجل لمنتجاتها، فضلًا عن مجتمع المطورين الضخم الذي يستخدم تنسرفلو TensorFlow حول العالم والذي من شأنه توفير عون كبير من خلال مساهماته وإجاباته عن كل التساؤلات، وإضافة لميزات الدعم القوي، يتميز إطار تنسرفلو بالمرونة فهو نظام مقسم لأجزاء أو وحدات modular system، بمعنى يمكننا استخدام كل جزء من هذه الأجزاء بمفرده أو استخدام الأجزاء معًا حسب متطلبات مشروعنا، كما أنه يتمتع بقابلية النقل Portability وهذه ميزة مهمة يفضلها معظم مستخدميه، حتى أن بإمكاننا استعماله على الهاتف الجوال في حال لم يتوفر لنا الوصول إلى حاسوب مكتبي أو محمول لتثبيته. ولمطالعة المزيد من المعلومات حول هذا الإطار واستخدامه عمليًا، ننصح بقراءة مقال بناء شبكة عصبية للتعرف على الأرقام المكتوبة بخط اليد باستخدام مكتبة TensorFlow. 2. تورش Torch أطلق إطار عمل تورش Torch لأول مرة في العام 2002، وهو أقرب إلى المكتبة منه إلى إطار العمل التقليدي، حيث يتكون من مجموعة خوارزميات تستخدم في مجال تعلُّم الآلة، ومن أبرز المميزات التي يوفرها Torch لمستخدميه نذكر: المصفوفات متعددة الأبعاد N-dimensional arrays واجهة خاصة للغة البرمجة C عمليات الجبر الخطي الروتينية دعم سريع وفعال لوحدة معالجة الرسومياتGPU السرعة والمرونة في تطوير المشاريع إلى جانب مجتمع المطورين الكبير الذي يستخدمه والذي من شأنه توفير الدعم المطلوب عند الحاجة، ويُحسَب لمجتمع Torch نشاطه الواسع على GitHub والسعي الدائم لتطوير هذه المكتبة. ملاحظة: تورش هي مكتبة تعلم آلي مفتوحة المصدر تُستخدم لإنشاء الشبكات العصبية العميقة وهي مكتوبة بلغة البرمجة Lua، أما بايتورش PyTorch فهو إطار عمل مفتوح المصدر لتعلم الآلة يعتمد على لغة البرمجة بايثون ومكتبة تورش Torch وننصح بقراءة مقال تعرف على إطار عمل باي تورش PyTorch وأهميته لتطبيقات الذكاء الاصطناعي للتعرف أكثر على هذا الإطار. 3. ثينو Theano تحظى الأداة ثينو Theano بشعبية كبيرة بين أُطر عمل الذكاء الاصطناعي، رغم أنه ليس حديثًا، لكنه يستند إلى لغة بايثون واسعة الانتشار وسهلة التعلُّم والمناسبة تمامًا لمشاريع تعلم الآلة والذكاء الاصطناعي وهذا يعطي ثينو قيمة مضافة. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن يمكن أن نقول أن أداة Theano بمثابة معيار في مجال تعلُّم الآلة والذكاء الاصطناعي فهي قديمة نسبيًا وقد اعتمدت عليها الكثير من الأدوات الأخرى سواء على صعيد البنية أو الوظيفة، وأكثر ما يميزها الاختبار الشامل الذي تنفذه على الشيفرات البرمجية قبل إطلاقها وهي في الواقع رائدة في هذا المجال. كما أنها تسهل التعامل مع التعبيرات الرياضية، وتدعم العمل مع التمايز الرمزي symbolic differentiation ووحدة معالجة الرسوميات GPU التي تسرّع إنجاز العمليات الحسابية بشكل كبير. 4. كافيه Caffe صدر إطار العمل كافيه Caffe في العام 2017 وهو أحد أطر العمل الحديثة، ومكتوب بلغة ++C وهذا يجعله خيارًا مناسبًا للكثير من المبرمجين ومهندسي البرمجيات الذين غالبًا ما يجيدون هذه اللغة والتي ما زالت تستخدم على نطاق واسع. ويُعَدّ Caffe أفضل أطر العمل المستخدمة في بناء الشبكات الالتفافية Convolutional networks وهي نوعٌ خاص من الشبكات العصبية لذا من الجيد اعتماده من البداية إذا كنا ننوي بناء هذا النوع من الشبكات في مشروعنا. ومن مميزاته أيضًا العمل بسلاسة مع وحدة مالجة الرسوميات GPU المناسبة، فقد لا يستغرق Caffe أكثر من يوم واحد لمعالجة عشر ملايين صورة، فإذا كانت السرعة من أولوياتنا فسيكون هذا الإطار خيارًا مثاليًا لنا. 5. كيراس Keras إطار العمل كيراس Keras بسيط وسهل التعلُّم، كما يتمتع Keras بصغر حجمه lightweight وهذا يجعله سريع الأداء لقلة الموارد الحاسوبية التي يحتاجها لإنجاز مهمة معينة مقارنة بغيره من أطر العمل، ويوفر كيراس بالإضافة إلى ما سبق واجهة للعمل مع بايثون، وقد تحدثنا عن أهمية هذه اللغة لمستخدمي الذكاء الاصطناعي، ويُعدّ خيارًا ممتازًا في بناء الشبكات العصبية التكرارية recurrent networks، والشبكات العصبية الالتفافية convolutional networks، على عكس Caffe الذي يتخصص فقط بالشبكات العصبية الالتفافية. وهذه قائمة بالمهام التي يتعامل معها كيراس بطريقة جيدة لتعرف في أي نوع من المشاريع يمكنك استخدامه: التصنيف Classification توليد النص Generating text تلخيص النص Summarizing a text الترجمة Translations التعرف على الكلام Speech recognition ويمكن اعتماده للعديد من المهام المعقدة الأخرى 6. Microsoft CNTK يُعَدّ CNTK من مايكروسوفت منافسًا قويًّا لأُطر عمل الذكاء الاصطناعي شائعة الاستخدام مثل TensorFlow وغيره، فهو يتعامل مع مختلف عمليات التعلُّم الآلي مثل: بناء الشبكات العصبية الالتفافية والتكرارية والشبكات ذات الذّاكرة الطويلة قصيرة المدى LSTMs. وقد جَهِدَت مايكروسوفت منذ إطلاقه لجعل CNTK مرنًا، وفعَّالًا، وعالي الأداء، وقد نجحت مايكروسوفت في مسعاها، فقد حصل CNTK على نتائج جيدة في معظم اختبارات الأداء المعيارية benchmark tests التي خضع لها، فهو يقدم أداءً جيدًا في كل عملية ينفذها ضمن وقت محدد، كما أنه يتعامل بمرونة وفعالية مع جميع أنواع المهام التي تُعطى له، مثل: التعرّف على الكلام، والتعرّف على الصور ومعالجتها، وتوليد النصوص، وتدريب أنظمة الإنتاج. كما أنه يعمل بكفاءة مع نظامي ويندوز و لينكس على حد سواء. 7. ساي كيت ليرن Scikit-learn أكثر ما يميز Scikit-learn أنه منصة مفتوحة المصدر تتمتع بمجتمع نشط للغاية يساندنا في أي مشكلة قد تواجهنا، فالإجابات متوفرة بكثرة في منتديات المنصة، وإن لم نجد نبحث عنه بين المواضيع المنشورة كل ما علينا هو طرح سؤال جديد وترقب الإجابات فالمجتمع متفاعل وسيجيبنا بسرعة، ويمكننا دائمًا الاستعانة بالتوثيقات التي توفرها Scikit-learn. وفضلًا عن الدعم المميز لهذا الإطار فهو سريع الأداء، ويؤمن لمستخدميه واجهة برمجة تطبيقات API واضحة ومنظمة وجاهزة للعمل مع مختلف الاحتياجات. ولمطالعة المزيد حول استخدام ساي كيت ليرن عمليًا ننصح بمقال بناء مصنف بالاعتماد على طرق تعلم الآلة بلغة البايثون باستخدام مكتبة Scikit-Learn. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن 8. Azure ML Studio تختلف Azure ML Studio عن غيرها من أطر عمل الذكاء الاصطناعي بكونها تمتلك نسختين، نسخة مدفوعة وأخرى مجانية، بالإضافة لكونها أداةً تفاعلية وسحابية، وهذا ما سنشرحه تاليًّا. تُنشئ Azure ML Studio التحليلات التنبؤية لنماذج تعلُّم الآلة بطريقة تفاعلية، فتتنبأ بالنتائج وفقًا للبيانات التي تقدمها لها، كما تتيح لنا بناء نماذجنا الخاصة بسهولة بواسطة السحب والإفلات ثم التنبؤ بالنتيجة استنادًا إلى المدخلات، وزيادة في دقة النتائج توفر Azure مكتبة مضمّنة built-in library تحتوي مجموعة واسعة من خوارزميات الذكاء الاصطناعي الكفيلة بتحسين تنبؤاتنا. وأكثر ما يميزها أنها سحابية، فلن نحتاج لتثبيت أي تطبيق على جهازنا، إذ كل ما يتطلبه الأمر حاسوب شخصي أو محمول متصل بالإنترنت. 9. أكورد دوت نت Accord.NET يُستخدم إطار العمل Accord.NET في معالجة الصور وتعلم الآلة، وهو مكتوب بلغة #C المستخدمة بكثرة في بناء البرامج والتطبيقات، ويتضمن مكتبات متنوعة للحوسبة العلمية بما فيها مكتبات تعلُّم الآلة، وهذه أبرز المميزات التي يوفرها: دعم آلات المتجهات Support for vector machines خوارزمية التجميع باستخدام نموذج غاوس المختلط Gaussian Mixture Models خوارزمية k-Means أشجار القرار Decision Trees النماذج البايزية البسيطة Naive Bayesian models لمعرفة المزيد عن هذه الخوارزميات وغيرها ننصح بقراءة مقال أدوات برمجة نماذج تعلم الآلة. ملاحظة: ذكرنا أن Accord.NET مميز في التعامل مع الصور، وبالتالي فهو مناسب للعمل مع كائنات اكتشاف الوجوه ومعالجتها إذ يحوّلها إلى تدفقات من الصور، وبالمثل أيضًا للمهام المتعلقة بالصوتيات audio فهو قادر على معالجة الإشارات الصوتية وتحويلها وفلترتها لتناسب برامج التعلم الآلي والتطبيقات الإحصائية. 10. سبارك Spark MLlib يعمل إطار العمل Spark MLlib كمكتبة لتعلّم الآلة على غرار معظم الأدوات التي عرضناها سابقًا، وهو يتضمن عدة خوارزميات ملائمة للمهام التالية: التصنيف classification لتحديد الصنف الذي ينتمي إليه عنصر ما بناءً على خصائصه التجميع clustering لتقسيم مجموعة من البيانات إلى مجموعات أو عناقيد بحيث تكون العناصر في كل مجموعة متشابهة فيما بينها وتختلف عن العناصر في المجموعات الأخرى الانحدار regression لفهم وتوقع العلاقات بين المتغيرات التصفية التعاونية collaborative filtering لتوقع تفضيلات المستخدم بناءً على معلومات جُمعت من عدة مستخدمين سابقين وغيرها. ومن أبرز مميزات Spark MLlib بساطته وتوافقه مع الأدوات والأطر الأخرى، إذ يتيح لنا هذا التوافق الاهتمام بجوانب معينة من مشروعنا وتنفيذها بالتطبيق المناسب لها طالما أن يتوافق مع إطار العمل، وهو ما يضمن تطويرًا أسرع وأكثر كفاءة. ويتمتع Spark MLlib بمحرك فعّال يتفوق على لغتي البرمجة بايثون و R اللتين لطالما استخدمهما علماء البيانات في التعامل مع مهام التعلم الآلي، إذ يعالج Spark MLlib المشكلات التي لا تستطيع بايثون و R معالجتها بطريقة تفاعلية وعلى نطاق أوسع. ملاحظة: يمكننا اختيار لغة البرمجة التي نريدها للعمل مع Spark MLlib من بين اللغات التالية: بايثون، و R، و Scala، وجافا. 11. Amazon Machine Learning يمكننا إضافة ميزات الذكاء الاصطناعي إلى مختلف أنواع التطبيقات بالاستعانة بأداة تعلّم الآلة من منصة أمازون AWS، ومن هذه الميزات تحليل الكلام، وروبوتات الدردشة chatbot، والرؤية الحاسوبية computer vision. ما يميز AWS إمكانية استخدامها مع أطر عمل الذكاء الاصطناعي الأخرى مثل TensorFlow و Caffe، وهو ما يمنحنا بيئة متقنة وفعّالة لتطبيقات تعلّم الآلة وإمكانية الاستفادة فيها من وظائف TensorFlow و Caffe جنبًا إلى جنب مع وظائف AWS. توفر AWS أداة مُضَمّنة تدعى Amazon Sagemaker تساعدنا على بناء نماذجنا الخاصة للتعلُّم الآلي ونشرها بسهولة وكفاءة، وتفيدنا بشكل كبير إذا كنا نخطط لاستخدام Amazon Machine Learning كإطار عمل في مشروعنا. الخلاصة بهذا نكون قد وصلنا لنهاية مقالنا الذي اكتشفنا فيه أهم أُطر عمل الذكاء الاصطناعي المتخصصة في تعلُّم الآلة، حيث قد عرضنا بعجالة سريعة أحد عشر إطار عمل من أفضل الأُطر المتوفرة حاليًا، ولكل منها مزاياه الخاصة والجوانب التي يتفوق فيها على غيره سواء من ناحية الأداء أو التحديثات أو التوافق مع لغات البرمجة أو التخصص في نوع معين من المعالجة مثل معالجة الصور أو غيرها. يمكننا الآن الانطلاق من هنا واختيار المنتج الذي يناسبنا والبحث عنه أكثر ثم البدء بتعلمه، ترجمة -وبتصرف- لمقال 11 Best AI Framework for Machine Learning لصاحبه Mark Bynum. اقرأ أيضًا تعرف على أهم كتب الذكاء الاصطناعي المجانية برمجة الذكاء الاصطناعي: بناء مستقبل الآلات الذكية أساسيات الذكاء الاصطناعي: دليل المبتدئين مكتبات وأطر عمل الذكاء الاصطناعي: القوة الكامنة خلف الأنظمة الذكية
-
يدرك كل من تعامل مع متغيرات باش عدم وجود أي فرق بين تعريف متغير نوعه عدد صحيح 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
-
تدخل العمليات الحسابية في العديد من سكربتات باش 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 والبيئة في لينكس التوسعات في باش ميزات صدفة باش
-
يسعى الكثير من مطوري الويب إلى تعلم إطار عمل جديد في مرحلة ما من مسارهم المهني، فأطر العمل تساعد على إنشاء تطبيقات أفضل وبسرعة أكبر كما أنها توسع خبرات المطورين وتعزز فرصهم في سوق العمل. وتوفر لغة جافا سكريبت الكثير من أطر العمل القوية والمستخدمة في تطوير مواقع وتطبيقات الويب والتي توفر وظائف مفيدة متنوعة، وكما هو معروف فإن لغة جافا سكريبت من أشهر لغات البرمجة المستخدمة في مجال تطوير الويب وهذا يشجع المطورين أكثر على تعلمها واستخدام أطر عملها. فإذا كنت مهتمًا بتعلم إطار عمل جديد لتطوير تطبيقات الويب الخاصة بك، تابع هذا المقال حيث سنبدأ فيه بشرح سريع لمفهوم إطار العمل في البرمجة، يليه عرض موجز لإثني عشر إطارًا من أفضل أطر العمل المستندة على جافا سكريبت لتختار من بينها ما يناسبك. ما هو إطار العمل ولماذا نحتاجه؟ يشير إطار العمل framework عمومًا إلى طريقة تنفيذ العمل، ويُقصد به في مجال البرمجة بيئة العمل working environment التي تمكننا من تنظيم عملنا، فيساعدنا إطار العمل البرمجي على تنظيم شيفراتنا وبالتالي يُسَهِّل ويُسَرِّع إنجازنا للمشاريع. تقسم أُطر العمل البرمجية إلى نوعين رئيسيين: أطر العمل التي تعمل كمكتبة library وهي تتميز بالمرونة، إذ تستطيع أخذ الأجزاء التي تحتاجها منها والتعديل عليها بما يناسب متطلبات عملك أطر العمل المتكاملة التي تفرض عليك طريقة وإجراءات محددة لكيفية إنشاء مشروعك وإنهائه سنعرض في الفقرات التالية أمثلة عديدة على كلا النوعين ليتضح الفرق بينهما أكثر، لكن دعنا في البداية نجيبك عن السؤال الأهم والذي لا بُدّ أنه تبادر في ذهنك وأذهاننا جميعًا: هل إطار العمل ضروري؟ وهل أحتاجه حقًا كمطور تطبيقات؟ تختلف الإجابة من حالة لأخرى وتتعلق بطبيعة المشروع، لكن الفائدة الكبيرة التي يقدمها إطار العمل على صعيد تنظيم بنية الشيفرة البرمجية وسهولة اختبارها تمنح المطورين سببًا وجيهًا لاستخدام أُطر العمل في مشاريعهم. فعندما تطور تطبيقاتك باستخدام إطار عمل ستكون شيفراتها المصدرية أكثر تنظيمًا وسيكون بنائها أسهل وأسرع مقارنة ببنائها من دون إطار عمل، وهذا يقودنا بالضرورة إلى الجزء الثاني من فائدة إطار العمل وهو سهولة الاختبار فالشيفرة المنظمة يسهل اختبارها وتصحيح أخطائها وهذه ميزة مهمة لا غنى عنها في تطبيقات الويب فأي تطبيق ويب أو موقع ويب ينبغي أن يُختَبَر بدقة قبل إطلاقه للعلن. خلاصة القول يمكنك بالتأكيد بناء تطبيقات ويب ناجحة بلغة جافا سكريبت JavaScript وحدها فقط من دون أي إطار عمل، لكن استخدام أحد أُطر العمل التي سنعرضها هنا سيسهل عملك ويوفر عليك الكثير من الوقت والجهد حتى في فترة الصيانة التي تلي إطلاق المنتج، فضلًا عن كونه مطلوبًا بكثرة في سوق العمل وتعلمه يعزز فرصتك في الحصول على وظيفة مناسبة. وإذا كنت تتقن لغة جافا سكريبت فسيسهل عليك تعلم أي إطار عمل من أُطرها فغالبًا ما يعتمد الإطار على اللغة نفسها، ولن تحتاج لتعلم أكثر من إطار أو إطارين فقط من بين الإثني عشر إطارًا التي سنذكرها تاليًا، وتذكر أن الشركات تفضل تعيين مطوري الويب المتقنين لبعض أطر العمل المعروفة إلى جانب تعلم لغة البرمجة نفسها. والآن إليك قائمتنا من أطر عمل جافا سكريبت التي نُرشحها لك والتي سنعرضها بمزيد من التفصيل: ريآكت React. فيو Vue JS. أنجولار Angular JS. بوليمر Polymer. إمبر Ember. باك بون Backbone. نيتف سكريبت NativeScript. نود جي اس Node JS. ميتيور Meteor. ميثريل Mithril. أوريليا Aurelia. سوكيت Socket. 1. ريآكت React ريآكت React هو مشروع مفتوح المصدر طوره مهندس البرمجيات جوردان ووك من شركة فيسبوك، وهو مكتبة أكثر من كونه إطار عمل متكامل تقليدي لذا يُعَدّ مناسبًا لمشاريع الويب التي تتطلب تخصيصًا عاليًّا. يستعمل ريآكت في بناء واجهة المستخدم UI لتطبيقات الهاتف الجوّال وتطبيقات الويب، فإذا كنت تعمل في هذا المجال سيكون مهارةً ممتازة تضيفها إلى مهاراتك إذ سيُحَسِّن كفاءة مشاريعك مقارنة بغيره من الأدوات، كما أنه جيدٌ في الاختبارات ويتوافق مع أُطر جافا سكريبت الأخرى. كما يُعدّ إطارًا سهل التعلُّم ويستطيع أي مطوّر جافا إتقانه بسرعة والبدء بإنشاء تطبيقاته الجديدة باستخدامه ذلك أن React في جوهره هو جافا سكريبت بسيط أُضيفت له بعض الوظائف الجديدة. وبالإضافة لما سبق يوفر ريآكت React شيفراتٍ برمجية قابلة لإعادة الاستخدام تختصر عليك الوقت فلن تضطر لإعادة اختراع العجلة وكتابة الشيفرات نفسها من الصفر في كل مرة، كما أن مكونات ريآكت معزولة عن بعضها فالتحديثات التي يجريها المطوّر على أحد المكونات لن تؤثر على البقية وهذا يعطيه أريحيةً وكفاءة أكبر في إنجاز العمل. كما يوفر ريآكت العديد من الأدوات التي تسهّل العمل على مشروعك، خاصة في المراحل المتقدمة. من بين هذه الأدوات React Developer Tools، وهو إضافة extension متوفرة لمتصفح جوجل كروم وأيضًا لمتصفح فايرفوكس. تتيح لك هذه الإضافة فحص شجرة DOM الخاصة بتطبيقك وتحريرها مباشرة باستخدام React، مما يمنحك تحكّمًا أكبر ويسهّل عليك اكتشاف الأخطاء وتحسين الكود. 2. فيو Vue JS أُطلِقَ إطار العمل Vue JS في شهر فبراير من العام 2014، وهو من أحدث أُطر عمل جافا سكريبت، ورغم حداثة عهده فقد أصبح بسرعة واحدًا من أكثر الخيارات شعبيةً لمطوّري الويب، وذلك لعدة أسباب، نعرض أبرزها: السبب الأول هو صغر حجمه، وهذه صفةٌ مهمة في أي إطار عمل تنوي استخدامه ومع أي لغة برمجة، فأُطر العمل كبيرة الحجم التي تستهلك مساحةً كبيرة في الذاكرة تعمل بكفاءة أقل وتستغرق وقتًا أطول لتحميل التطبيقات وتشغيلها، أما مع إطار عمل صغير الحجم مثل Vue.js الذي يتراوح حجمه بين 20 و 25 كيلو بايت فقط سيكون أفضل أداء ويمكن تحميله بسرعة ثم البدء باستخدامه مباشرة. أما السبب الثاني والمميز حقًا أنك تستطيع استخدام Vue JS مع تطبيقاتك الحالية المبنية بلغة جافا سكريبت فقد صُمم هذا الإطار أساسًا ليُدمَج بسهولة مع التطبيقات الجاهزة وتعزيزها بميزات جديدة، على سبيل المثال إذا احتجت لإضافة وظيفة معينة إلى تطبيقك وكان Vue.js يحققها فيمكنك استخدامه بأريحية، كما أنه يتضمن العديد من المكونات القادرة على التكامل بسهولة مع أي تطبيق تقريبًا. وأخيرًا من الضروي التنويه لميزة البساطة التي يتمتع بها Vue JS فتعابيره البرمجية بسيطة وسهلة الفهم، ويمكنك تعلُّمه بسرعة وبأي وقت خصوصًا إذا كنت تتقن إطار Angular أو React، وفي هذا المجال ننصحك بتحميل كتاب أساسيات إطار العمل Vue.js 1.0.0 الذي توفره أكاديمية حسوب مجانًا وباللغة العربية. 3. أنجولار Angular JS أطلقت جوجل إطار العمل أنجولار Angular عام 2012 وقد استغرق هذا الإطار بعض الوقت لينال شعبية بين المطورين وهو اليوم واحد من أكثر أُطر العمل شهرة ويستعمل في عدد كبير من مواقع الويب حول العالم، فما السر وراء انتشاره؟ وما الميزات التي يقدمها؟ سنجيبك عن هذا السؤال بخمس نقاط مختصرة: يلائم Angular منصات متعددة cross-platform، فيمكنك استخدامه لتطوير تطبيقات سطح المكتب، وتطبيقات الهاتف الجوال، وتطبيقات الويب، وهذه من أفضل مميزاته. إطار عمل مفتوح المصدر ويمكن تعديل شيفرته المصدرية حسب متطلبات العمل، وهذا يفيدنا في المشاريع المعقدة التي تحتاج متطلبات خاصة وجود مجتمع كبير من المطورين الداعمين له والساعين لتحسينه باستمرار يتلقى Angular دعمًا مستمرًا من جوجل وتحديثات منتظمة إلى جانب الدعم الذي يتلقاه من مجتمع المطورين إطار سهل الاستخدام وهذه ميزة مهمة للمبتدئين خاصة فلن يحتاجوا وقتًا طويلًا لتعلم Angular وإتقانه مقارنة بأُطر العمل الأخرى. كانت هذه بعض من مزايا Angular التي تجعله بدايةً جيدة لأي مطوّر يرغب باستخدام أطر عمل جافا سكريبت، علمًا أنه يتمتع بمزايا أخرى عديدة ستتعرف عندما تتعامل معه، ويمكنك البدء برحلة برحلة استكشافه بقراءة مقالات قسم Angular على أكاديمية حسوب. 4. بوليمر Polymer أنُشِئ إطار العمل Polymer من قبل مجموعة من مطوري شركة جوجل على غرار Angular، وهو أيضًا مفتوح المصدر لكنه أحدث عهدًا منه، ومستودعه على GitHub متاح لكل من يحب المساهمة في المشاريع مفتوحة المصدر. يُعَدّ Polymer أقرب للمكتبة منه لإطار العمل المتكامل التقليدي لذا فهو يمنحك أريحية كبيرة في التحكم بطريقة تنظيم بيئة العمل لمشروعك، ويتمتع بمزايا أخرى عديدة أبرزها سهولة الاستخدام، فعلى سبيل المثال يكفيك ملف HTML واحد فقط لبناء عدة عناصر ويب في تطبيقات Polymer وتخصيصها، وهذا يجعله سهل التعلم إذا ما قارناه بأطر عمل أخرى مثل Angular الذي ستحتاج فيه عدة ملفات HTML لفهم وتطوير عنصر واحد فقط. كما يتميز Polymer بسهولة التعامل مع متغيرات CSS ومخاليط mixin قابلة لإعادة الاستخدام، مما يزيد توافقيته مع CSS3 ويمنحك القدرة على استثمار كل ميزة جديدة تقدمها، وهذا ينعكس على جودة وجاذبية وتنوع تصميمات مواقع الويب التي تبنهيها يهذا الإطار. ونذكر من مميزاته أيضًا التوافق مع المكتبات والأدوات الأخرى المستخدمة في عملية التطوير، إذ يمكنه تبادل البيانات معها بسهولة ومباشرة من دون المرور بأي طبقة إضافية، فضلًا عمّا يوفره من توثيقات حديثة وغنية بالتفاصيل تساعدك على تعلم كافة جوانبه بسرعة وبإتقان، دون أن ننسى مجتمع المطورين الذين يستخدمون Polymer حول العالم وما يمكن أن يقدموه لك من مساعدة في إيجاد الحل لأي مشكلة تعترضك. 5. إمبر Ember JS يستخدم إطار العمل إمبر Ember لتطوير تطبيقات الويب المعقدة والغنية بالميزات، وهو إطار عمل متكامل بالمعنى التقليدي للكلمة إذ يتضمن عددًا كبيرًا من الواجهات البرمجية APIs، ولديه طريقة محددة لإنجاز عمل، فجميع المكونات التي قد تحتاج مكتوبة وجاهزة للنشر وتستطيع الاعتماد عليها من دون كتابتها من الصفر، يُعرف هذا الأسلوب بالاتفاقيات أو التقاليد conventions وهو يتضمن الآلية المثلى لإنجاز أعمال المشروع وسيزيد إنتاجيتك في العمل، لأنك لن تضيع وقتك في إعادة برمجة المكونات الجاهزة بل ستستفيد منه للتركيز على وظائف التطبيق. وفي هذا المجال يساعدك موقع Ember الرسمي EmberAddons.com في التعرف على جميع أنواع الإضافات plugins الجاهزة للاستخدام فهو مثل مستودع تعاوني للإضافات يساهم فيه مطورو Ember، فإذا كنت تبحث عن الشيفرة البرمجية الكاملة لإضافة معينة أو عن جزء من شيفرة برمجية معينة، يمكنك البحث في هذا المستودع وأخذ ما تحتاجه لتطبيقك، وهذا بدوره يرفع إنتاجيتك ويُسَرِّع وتيرة عملك فالإنتاجية العالية هي الميزة الأهم للإطار Ember. كما أن التوافقية مع الإصدارات السابقة ميزة أخرى مهمة في الإطار، فإذا كان تطبيقك يعمل باستقرار على إصدار معين من Ember لأنه يتوافق مع ميزات محددة فيه، وظهر تحديث جديد للإطار فلن تحتاج عندها لإيقاف تطبيقك وإجراء تغييرات جوهرية فيه أو حتى إعادة النظر في طريقة بنائه كما تفعل عادة مع الكثير من الأدوات البرمجية فإصدارات Ember الجديدة تعمل دائمًا بسلاسة مع التطبيقات التي ما زالت تستخدم إصدارات أقدم، وكل ما عليك الاهتمام هو إجراء بعض التغييرات لتستفيد من ميزات الإصدار الجديد حتى تُحسِّن عمل تطبيقك. 6. باك بون Backbone صدر إطار العمل باك بون Backbone عام 2016 وهو الأحدث في قائمتنا المعروضة ضمن المقال، ورغم حداثته فقد اكتسب انتشارًا واسعًا بين المطورين لما يتمتع به من ميزات أبرزها تعدد المنصات cross-platform، فيمكنك استخدامه مثلًا لبناء تطبيق يعمل على الجوال وعلى الويب في آن واحد، مما يوفر زمن التطوير والاختبار فلن تضطر لإعادة برمجة التطبيق مرتين. يساعد إطار العمل Backbone في تطوير الواجهة الخلفية back-end للتطبيق ويمكنه التفاعل بسلاسة مع الواجهة الخلفية لتطبيقك أو موقعك الحالي، كما يستطيع التفاعل مع واجهات برمجة التطبيقات APIs لتنفيذ مهام القراءة والكتابة والحذف. ويتضمن Backbone العديد من الاتفاقيات conventions التي تناسب معظم الأغراض وإذا التزمت بها ستوفر عليك الكثير من الوقت اللازم لكتابة التعليمات البرمجية من الصفر، وستمنحك شيفرة مصدرية نظيفة وسهلة الفهم والصيانة حتى على المطورين الآخرين. 7. نيتف سكريبت NativeScript يستخدم إطار العمل نيتف سكريبت NativeScript لتطوير تطبيقات جوال أصيلة Native لنظامي تشغيل أندرويد و IOS باستخدام جافا سكريبت، وهذه في الواقع هي ميزته الكبرى، فتطبيقات نيتف سكريبت NativeScript متعددة المنصات ستعمل على كلا نظامي التشغيل أندرويد و IOS في وقت واحد وبالتالي تحتاج لكتابة كود تطبيقك مرة واحدة فقط وسيعمل مباشرة على كلا النظامين بكل سلاسة. والنقطة المهمة الأخرى التي تحتسب لصالح نيتف سكريبت أنه مفتوح المصدر، وهو ما يُسهِّل الاستفادة من تجارب الآخرين وإيجاد الحلول لمعظم المشكلات التي قد تواجهك، أضف إلى ذلك أن المصدر المفتوح يمنح نيتف سكريبت مجتمعًا نشطًا من المطورين حول العالم يضيفون إليه ميزاتٍ جديدة باستمرار، ويتيح أمامك العديد من الإضافات الجاهزة لتستخدمها في تطبيقك تمامًا كما هي من دون أي مجهود إضافي. 8. نود جي اس Node JS يُعَدّ نود جي اس Node JS إطار العمل المفضل والأكثر شيوعًا لدى مطوري جافا سكريبت، فمنذ انطلاقته الأولى في العام 2009 أصبح واحدًا من الأدوات الرائدة في مجال إنشاء تطبيقات الويب من طرف الخادم وتشغيلها. وتعود شعبيته الكبيرة لأسباب متعددة في مقدمتها اعتماد الكثير من الشركات عليه، فكل شركة تقريبًا تستخدم Node.js في أحد جوانب عملها نحو أدوات الدردشة المباشرة live chat التي تجدها في معظم مواقع الويب اليوم والتي لا بدّ ستصادفها مستقبلًا في عملك ومعرفتك بالأداة لإطار Node JS ستعينك على التعامل بكفاءة مع هذا النوع من تطبيقات الاتصال، وهناك قائمة طويلة من التطبيقات الشهيرة التي تعتمد Node.js مثل: PayPal و LinkedIn و Yahoo و Uber و eBay، وقد دفع هذا الانتشار الواسع المطورين لتعلمه والإقبال على استخدامه. الدور الأساسي لإطار العمل Node.js هو تمكين التطوير من جانب الخادم server-side كما ذكرنا، لكنه في واقع الأمر يعمل بكفاءة مع طرف العميل client-side أيضًا ويسهل تبادل البيانات بين الطرفين والتنسيق بينهما ليكونا متزامنين، فأي تغيير تنفذه سينعكس مباشرة على التطبيق أو صفحة الويب، ولذا يُعَرّف Node.js بأنه بيئة تشغيل لجافا سكريبت JavaScript runtime environment أكثر من كونه إطار عمل بالمعنى الدقيق بسبب قدرته على التعامل مع هذه الاتصالات المتزامنة بين الطرفين والسرعة التي يوفرها لعملية التطوير. بالإضافة لكل الإيجابيات السابقة يطرح نود جي اس خيارات وميزات جديدة دوريًا ليواكب اتجاهات الويب الحديثة، ويتمتع بمجتمع كبير يدعمه ويساهم في تحسينه وتطوير العديد من وحداته modules وميزاته الجديدة، وستكون منتدايات هذا المجتمع مصدرًا جيدًا لإيجاد أي معلومة تبحث عنها ولحل أي مشكلة تواجهها، كما يمكنك المساهمة بدورك في تطوير هذا المشروع مفتوح المصدر بما يحقق الفائدة لجميع المستخدمين. ننصحك في ختام هذه الفقرة بمراجعة مقالات Node.js أو بتحميل كتاب دليلك إلى Node.js مجانًا من أكاديمية حسوب. 9. ميتيور Meteor حظيت أداة ميتيور Meteor بشعبية كبيرة رغم حداثتها، وتكمن قوتها الأساسية بأنها لا تقتصر على تطوير تطبيقات الويب بل يمكن استخدامها لتطوير التطبيقات لمختلف أنواع المنصات مثل التطبيقات التي تعمل على الويب والهاتف الجوال بذات الوقت فتوفر بذلك وقتك وجهدك. ومن مميزاتها أيضًا أنها تعمل في الزمن الحقيقي real-time وهذه ميزة يفضلها الكثير من المطوّرين خصوصًا في الآونة الأخيرة لأن أي تعديل تجريه على الشيفرة البرمجية ستظهر نتائجه تلقائيًا في خرج التطبيق في الزمن الحقيقي، وهذا يسهل عليك عمليات الاختبار وخاصةً تلك التي تقتصر على أجزاء معينة من التطبيق. تشبه Meteor إطار العمل Node.js في قدرتها على التعامل مع طرفي الخادم والعميل في عملية تطوير الويب، وتنفذ ذلك باستخدام شيفرات جافا سكريبت فقط من دون الحاجة لأي لغة برمجة أخرى، وهذا يجعلها سهلة التعلم فطالما أنك تتقن جافا سكريبت يمكنك تعلم Meteor بسرعة وسهولة. 10. ميثريل Mithril يتميز إطار العمل ميثريل Mithril بحجمه الصغير فهو يبلغ حوالي 9 كيلو بايت فقط، حتى أنه أصغر من Vue.js وهذا يجعله سريعًا مقارنة بغيره من الأطر، وهو يستخدم أساسًا لتطوير تطبيقات الويب ذات الصفحة الواحدة single-page web applications لأنه على عكس Node.js و Meteor لا يستطيع التعامل مع طرفي العميل والخادم في أثناء التطوير إنما يتخصص بتطوير طرف العميل client-side فقط. وإطار Mithril سهل التعلم ويناسب المطورين المبتدئين الراغبين بإتقان إطار عمل جديد بسرعة، إذ يمكنك البدء باستخدامه مباشرة بمجرد تعلم بعض التوابع methods الأساسية التي يوفرها، كما أنه يتصف بسرعة الأداء مقارنة بأطر العمل الأخرى مثل ريآكت React فقد يستغرق تحميل التطبيق في Mithril نصف الزمن الذي يستغرقه في ريآكت أو غيره. وعندما نتحدث عن السرعة سنتسأل بالتأكيد كيف سيتعامل إطار يعمل في الزمن الحقيقي مثل Mithril مع التحديثات الدورية updates التي ينبغي تطبيقها في الزمن الحقيقي؟ وهل يستطيع الحفاظ على جودة أدائه أثناء ذلك؟ بالرغم من صعوبة الأمر لكن Mithril يتعامل جيدًا مع التحديثات ويحافظ على سرعة أدائه معها. 11. أوريليا Aurelia يستخدم إطار العمل أوريليا Aurelia للتطوير من جانب العميل client-side، وهو سهل التعلم ويناسب المطورين المبتدئين إذ لن تحتاج لتعلمه سوى لتعلم أساسيات جافا سكريبت وتعلم لغة HTML الحديثة وهذه المعلومات متوفرة لدى جميع مطوري جافاسكريبت. يعتمد أوريليا مبدأ الاتفاقيات بدلاً من الإعدادات Conventions Over Configuration يعني ذلك أنه يوفر للمطور عدد من الاتفاقيات الثابتة التي سيعتمدها الإطار تلقائيًّا دون أن يكلف المطور عناء برمجة وكتابة الإعدادات لعناصر تقليدية توجد وتستخدم بكثرة في معظم التطبيقات، وهذا يجعله أسرع وأكثر كفاءة في التطوير ويمنحك شيفرة مصدرية نظيفة وفعالة. لا يقارن حجم المجتمع الذي يستخدم Aurelia بحجم المجتمع الذي يستخدم الأطر الأخرى مثل رياكت أو أنجولار مثلًا، لكنه مع ذلك يُعدّ مجتمعًا نشيطًا ويسعى لتطوير هذا الإطار وسيساعدك في حل مشكلاتك في التعامل معه. 12. سوكيت Socket.io صُممت Socket.io للعمل مع طرفي العميل والخادم، وهي مكتبة حديثة من مكتبات جافا سكريبت اكتسبت شهرة وشعبية واسعة لأنها في المقام الأول تعمل في الزمن الحقيقي وهي ميزة مفضلة للكثير من المطورين الراغبين بتطوير هذا النوع من التطبيقات، وتتصف تطبيقات الزمن الحقيقي بأن التعديلات التي تنفذ على شيفرتها المصدرية تنعكس مباشرةً على التطبيق في اللحظة نفسها. ورغم العديد من الآراء التي تنادي بعدم الحاجة إلى Socket.io اليوك بسبب وجود بدائل أخرى يمكنها الحلول مكانها، لكن انتشار هذه المكتبة ما زال مستمرًا ومازالت تحظى بشعبية وبمستخدمين جدد. وتتميز Socket.io بسهولة تعلُّمها وتنفيذها في المشاريع، فإذا كنت ترغب بإضافة مهارة جديدة إلى قائمة مهاراتك قد تفيدك في مسيرتك المهنية مستقبلًا فهذه الأداة تُعدّ خيارًا جيدًا. الخلاصة إلى هنا نكون قد وصلنا لنهاية مقالنا الذي تعرفنا فيه على أشهر أُطر عمل جافا سكريبت وأهم مميزات كل إطار، لتكون قادرًا على اختيار ما يناسب احتياجات عملك، فعلى سبيل المثال إذا كان تخصصك هو تطوير تطبيقات الجوال فقط فيمكنك اختيار NativeScript، وإذا كنت ترغب بتطوير تطبيقات متعددة المنصات تستطيع الاتجاه نحو Meteor، وإذا كانت غايتك الأولى هي السرعة فستبحث عن الإطار ذي الحجم الأصغر وما إلى ذلك، فكر في احتياجاتك ومتطلباتك أولًا ثم اتخذ قرارك. ترجمة -وبتصرف- لمقال 12 Best JavaScript Frameworks لصاحبه Mark Bynum. اقرأ أيضًا تعلم جافا سكريبت مدخل إلى إطار عمل الويب Express وبيئة Node تعرف على مفهوم إطار العمل Framework وأهميته في البرمجة متى نستعمل إطار عمل للتطوير باستخدام JavaScript التوثيق العربي للغة جافا سكريبت
-
قد تحتاج في سكريتات باش للتعامل مع مئات المتغيرات التي يدخلها المستخدم وفي هذه الحالة لن يكون من المناسب أن تنشئ هذه المتغيرات يدويًا، وهنا يأتي دور المصفوفات 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 الحصول على مدخلات من لوحة المفاتيح وإجراء العمليات الحسابية في سكربتات الصدفة الأخطاء الشائعة التي تحدث عند كتابة سكربتات الصدفة
-
نشرح في هذا المقال نشر تطبيق روبي أون ريلز Ruby on Rails على خادم أوبنتو خطوة بخطوة بدايةً من اختيار خادم الاستضافة وتثبيت الاعتماديات dependencies عليه، ووصولًا إلى إعداد خادم NGINX لاستقبال طلبات التطبيق وبناء قاعدة بيانات التطبيق ونشرها على خادم الاستضافة بمساعدة Capistrano وهي أداة مفتوحة المصدر مخصصة لأتمتة عمليات النشر. أولًا: إعداد خادم الإنتاج سنشرح بداية أبرز معايير اختيار الخادم الافتراضي الخاص VPS الذي سيعمل عليه تطبيق Rails فخيارات الاستضافة كثيرة وعليك أن تعرف الفروقات فيما بينها وتعتمد ما يناسب احتياجات تطبيقك سواء من ناحية الحجم أو المواصفات أو الأمان وغيرها. اختيار مزود الاستضافة هناك العديد من مزودي خدمات الاستضافة ولكل منهم سلبياته وإيجابياته، ويُقصد بمزود خدمة الاستضافة الجهة التي تمتلك خوادم موجودة في مركز بيانات datacenter وتؤجرها للراغبين باستخدامها بمقابل مادي يدفعونه شهريًا. إن استئجار الخوادم الموجودة في مراكز البيانات أمر ضروري عند نشر التطبيقات في بيئة الإنتاج فهو يحميك من المشكلات الطارئة المتعلقة بالتشغيل وأعطال التجهيزات العتادية لأن المزود يؤمن حلولًا لها، كما يوفر لتطبيقك اتصالًا فائق السرعة بالإنترنت وهو أمر مفيد تشغيل التطبيقات المقدمة للعملاء عبر الإنترنت. إذا كنت تحتاج تحكمًا كبيرًا ببيئة تطبيقك فاستبعد مزودي خدمات الاستضافة المُدارة managed hosting providers أي شركات الاستضافة التي تتكفل بإدارة البنية التحتية التي استأجرتها كاملة لأنها لا تمنحك تحكمًا كافيًا ببيئتك وتفتقر عادةً إلى تثبيت آخر التحديثات. كيف أحدد مواصفات الخادم الذي أحتاجه لتطبيق ريلز؟ تحتاج تطبيقات إطار العمل Rails وتطبيقات روبي عمومًا إلى سعة ذاكرة وصول عشوائي RAM كبيرة، فسعة الذاكرة RAM معيار أساسي عليك التركيز عليه عند اختيار الخادم، وتذكر أنك ستحتاج لتثبيت مكونات أخرى على الخادم ستأخذ حصتها من RAM أيضًا، ومنها قاعدة بيانات التطبيق مثل: MongoDB أو PostgreSQL أو Redis التي تعمل في الخلفية. فإذا كنت تنشر تطبيقك الأول فإن خادمًا بذاكرة RAM حجمها 2 جيجابايت مناسب ومقبول التكلفة، وبالرغم من إمكانية البدء بذاكرة 1 جيجابايت لكنها لن تلبي طلبك على الأغلب وسرعان ما ستنفذ عند تجميع الأصول compiling assets وتجهيز الملفات أثناء النشر إلى بيئة الإنتاج. كما ستحتاج لزيادة سعة RAM على الخادم في الحالات التي تستخدم فيها اعتماديات كبيرة مع تطبيقك مثل خدمات البحث أو غيرها حسب ما تتطلبه هذه الاعتماديات إضافةً إلى احتياجات لتطبيقك، فخدمة بحث مثل ElasticSearch على سبيل المثال تحتاج لوحدها إلى 4 جيجابايت، لذا يلجأ البعض لتشغيلها على خادم منفصل عن خادم تطبيقات روبي وريلز لتسهيل توسعة الموارد المحجوزة للخدمتين (أي التطبيق والبحث) بمعزل عن بعضهما. إنشاء الخادم سنعرض هنا كمثال طريقة إنشاء الخادم على منصة الاستضافة DigitalOcean علمًا أن العملية متقاربة في معظم المنصات، افتح المنصة وانتقل إلى صفحة إنشاء قطرة Droplet ثم تابع الخطوات. ملاحظة: Droplet مصطلح خاص بمنصة DigitalOcean يشير إلى وحدة افتراضية تشبه الخادم الافتراضي Virtual Server يمكن للمستخدمين إنشاؤها لتشغيل المواقع والتطبيقات وقواعد بيانات ويمكن تخصيص مواردها المختلفة كالمعالج والذاكرة ومساحة التخزين. الخطوة 1: اختر نظام تشغيل الخادم اخترنا هنا نظام أوبنتو 20.24، وهو نظام تشغيل يتمتع بدعم فني طويل الأمد LTS أي أنه سيتلقى تحديثات أمنية أكثر من المعتاد وعلى مدى سنوات طويلة، وهذا أمر مهم عند نشر التطبيقات في بيئة الإنتاج. توضح الصورة التالية خيار الخادم أوبنتو 20.24 من القائمة المنسدلة. الخطوة 2: حدد حجم الخادم ومواصفاته بعد اختيار نظام التشغيل الخاص بخادم الاستضافة ستظهر أمامك نافذة لتحدد حجم الخادم ومواصفاته، كما توضح الصورة التالية. في حال لم تكن متأكدًا من الحجم المناسب لتطبيقك، يمكنك اختيارحجم RAM لتكون 2 جيجابايت، وتغيير لاحقًا الحجم زيادة أو نقصانًا حسب احتياجات تطبيقك، وهنا تكمن ميزة الخوادم الافتراضية مقارنة بالخوادم الفيزيائية إذ يمكنك تغيير مواصفاتها بسهولة في أي لحظة بزيادة سعة الذاكرة RAM أو إنقاصها وكذلك الأمر بالنسبة لوحدات المعالجة المركزية CPU ووحدات التخزين وغيرها. الخطوة 3: اختر المنطقة الجغرافية الخطوة التالية هي تحديد منطقة الخادم server region أي المكان الجغرافي الذي يتواجد فيه مركز البيانات الذي سيعمل عليه خادمك الافتراضي، اختر المنطقة الأقرب لمكان تواجد مستخدمي تطبيقك أو مكان تواجدك كمدير للتطبيق والخادم. الخطوة 4: ضبط الخيارات الإضافية يوجد عدد من الخيارات الأخرى يمكنك ضبطها حسب احتياجات عملك إذا رغبت بذلك، ومنها: 1. الشبكات الخاصة Private Networking: يفيدك إعداد الشبكات الخاصة إذا كان خادمك يحتاج للتخاطب مع خوادم أخرى، كالحالة التي يكون فيها خادم قاعدة البيانات منفصلًا عن خادم التطبيق. 2. البروتوكول IPv6: بتفعيل هذا الخيار يمكنك إعطاء خادمك عنوان IPv6. 3. المراقبة Monitoring: يعطيك بعض المقاييس التقريبية التي تفيدك في قياس نسب استخدام الخادم. 4. النسخ الاحتياطي Backups: يعني تفعيل هذا الخيار أخذ صورة image أو نسخة كاملة عن خادمك يمكنك استعادته منها عند حدوث أي طارئ، لكن هذه النسخ الكاملة لا تُشَغَّل بفترات متقاربة لذا تُعدّ النسخ الاحتياطية الساعية لقاعدة بيانات التطبيق أو Hourly database backups أفضل منها في معظم الحالات. الخطوة 5: أنشئ خادمك بعد ضبط كافة الخيارات السابقة، اضغط على زر الإنشاء Create وستُنشئ DigitalOcean خادمك الجديد خلال دقيقة تقريبًا. بعدها توجه إلى بريدك الإلكتروني بمجرد إتمام عملية الإنشاء لتستلم كلمة مرور الخادم. يمكنك الآن الاتصال بالخادم من حاسوبك المحلي Local Machine بواسطة عنوان IP الخاص به ومستخدم الجذر root الذي استلمته عبر البريد الإلكتروني، كما في المثال التالي طبعًا مع استبدال 1.2.3.4 بعنوان IP لخادمك: ssh root@1.2.3.4 الخطوة 6: أنشئ مستخدم النشر أنشئ مستخدمًا لعملية النشر باسم deploy مثلًا بأذونات محدودة، واعتمد عليه في تشغيل برمجياتك على الخادم في بيئة الإنتاج بدلًا من تشغيلها من حساب المستخدم الجذر، يقلل ذلك من خطر حصول المخترقين على التحكم الكامل بخادمك في حال نجح باختراقه. إذًا في أثناء دخولك الأول إلى الخادم باستخدام حساب الجذر root أنشئ مستخدمًا جديدًا وامنحه امتيازات sudo كما يلي: root@1.2.3.4 adduser deploy adduser deploy sudo exit أضف بعدها مفتاح SSH إلى الخادم لتسريع الدخول إليه، سنستخدم في ذلك الأداة ssh-copy-id، علمًا أنها لا تتوفر افتراضيًا على أجهزة ماك فإذا كان جهازك المحلي من نوع ماك ثبتها باستخدام homebrew وفق الأمر brew install ssh-copy-id ثم نفذ التالي: ssh-copy-id root@1.2.3.4 ssh-copy-id deploy@1.2.3.4 يمكنك الآن تسجيل الدخول إلى الخادم بحساب المستخدم root أو المستخدم deploy ومن دون الحاجة لكتابة كلمة المرور لأن تفعيل مفتاح SSH يغنيك عنها. لنفتح الآن جلسة اتصال SSH بواسطة مستخدم النشر deploy وهو المستخدم الذي سننفذ بواسطته كافة الخطوات التالية في المقال، علمًا أنك لن تُطالب بإدخال كلمة مروره كما ذكرنا: ssh deploy@1.2.3.4 ثانيًا: تثبيت روبي على الخادم يشبه تثبيت روبي في بيئة الإنتاج تثبيته في بيئة التطوير مع مزيد من التدقيق في تثبيت جميع اعتماديات لينكس الضرورية لضمان تصريف compile روبي بطريقة صحيحة، ويساعدك استخدام مدير إصدارات روبي Ruby version manager على نشر الإصدارات الجديدة بسهولة ومن دون أي تعديل في ملفات الإعداد config files. الخطوة الأولى هي تثبيت الاعتمادات الضرورية لتصريف كل من روبي وإطار العمل ريلز، وأهمها ما يلزم لعمل المكتبة Webpacker مع ريلز لذا سنبدأ بإضافة مستودعات Yarn و Node.js إلى نظامنا لنتمكن من تثبيتها. ثم سنثبت Redis لنستطيع استخدام ActionCable مع مقابس الويب WebSocket في بيئة الإنتاج، كما قد يرغب البعض باستخدام Redis بصفته مخزن تخبئة cashing لخادم الإنتاج. لنطبق ذلك عمليًّا، تأكد أولًا من تسجيل دخولك بالمستخدم deploy ثم اكتب الأوامر التالية: deploy@1.2.3.4 # إضافة مستودع Node.js curl -sL https://deb.nodesource.com/setup_lts.x | sudo -E bash - # إضافة مستودع Yarn curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo add-apt-repository ppa:chris-lea/redis-server # تحديث الحزم من المستودعين المضافين أعلاه sudo apt-get update # تثبيت الاعتماديات المطلوبة لتصريف روبي من المستودعين المضافين sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev dirmngr gnupg apt-transport-https ca-certificates redis-server redis-tools nodejs yarn يمكننا الآن تثبيت روبي على الخادم بعد إتمام تثبيت الاعتماديات وقد استخدمنا في هذا المقال الإصدار 3.3.1 من روبي لكن تستطيع اختيار الإصدار الذي تفضله. كما سبق وذكرنا سنستخدم مدير الإصدارات rbenv لتثبيت روبي، فهو أسهل في التعامل والترقية وأيضًا يوفر لك عددًا من المكونات الإضافية المفيدة لضبط متغيرات بيئة الإنتاج. نَفِّذْ الأوامر التالية: deploy@1.2.3.4 git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc echo 'eval "$(rbenv init -)"' >> ~/.bashrc git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc git clone https://github.com/rbenv/rbenv-vars.git ~/.rbenv/plugins/rbenv-vars exec $SHELL rbenv install 3.3.1 rbenv global 3.3.1 ruby -v # ruby 3.3.1 نثبت الآن مُجَمِّع الوحدات Bundler (وهو أداة تستخدم في مشاريع الويب لتنظيم الوحدات والاعتماديات وتوليد الأصول): deploy@1.2.3.4 # يثبت الأمر التالي الإصدار الأخير من Bundler، والإصدار الأحدث عند إعداد المقال هو 2.x gem install bundler # أو نفذ الأمر التالي إذا رغبت بتثبيت إصدار أقدم مثل 1.x gem install bundler -v 1.17.3 # يعطيك الأمر التالي رقم إصدار Bundler ويساعدك بالنتيجة على التأكد من صحة تثبيته bundle -v # Bundler version 2.0 إذا حصلت على رسالة خطأ مفادها عدم العثور على Bundler، نفذ الأمر rbenv rehash وكرر المحاولة. ثالثًا: إعداد خادم الويب NGINX والوحدة Passenger يتطلب العمل في بيئة الإنتاج وجود خادم ويب مثل NGINX أمام ريلز لاستقبال طلبات HTTP والتعامل مع شهادات SSL وملفات التطبيق الثابتة static files بطريقة أسرع من روبي، وعلى أرض الواقع من غير المنطقي طرح تطبيقك للمستخدمين من دون خادم ويب. اعتمدنا في مثالنا على NGINX والوحدة Passenger، إذ سيستقبل NGINX طلبات HTTP الواردة إلى خادم التطبيق، ويحولها إلى Passenger الذي سيشغل تطبيقك. اكتب الأوامر التالية لديك لإضافة مستودع Passenger وتثبيته على الخادم: deploy@1.2.3.4 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7 sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger $(lsb_release -cs) main > /etc/apt/sources.list.d/passenger.list' sudo apt-get update sudo apt-get install -y nginx-extras libnginx-mod-http-passenger if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi sudo ls /etc/nginx/conf.d/mod-http-passenger.conf ثم افتح ملف إعدادات Passenger باستخدام أي محرر نصوص تفضله مثل nano أو vim كما يلي: deploy@1.2.3.4 # تحرير الملف باستخدام nano sudo nano /etc/nginx/conf.d/mod-http-passenger.conf # تحرير الملف باستخدام vim sudo vim /etc/nginx/conf.d/mod-http-passenger.conf عَدِّل السطر الذي يحتوي القيمة passenger_ruby ضمن الملف ليصبح وفق التالي، وذلك لتوجيه Passenger إلى الإصدار المطلوب من روبي: passenger_ruby /home/deploy/.rbenv/shims/ruby; احفظ التغييرات على الملف وأغلقه. ثم شغل NGINX كما يلي: deploy@1.2.3.4 sudo service nginx start يمكنك التأكد من صحة تشغيل NGINX بفتح عنوان IP العام للخادم في متصفح الإنترنت لديك، وستحصل على رسالة الترحيب التالية "Welcome to NGINX". والآن احذف ملف الإعدادات الافتراضي لخادم NGINX، وأضف ملفًا خاصًا لتطبيقك: deploy@1.2.3.4 sudo rm /etc/nginx/sites-enabled/default # تحرير الملف باستخدام nano sudo nano /etc/nginx/sites-enabled/myapp # تحرير الملف باستخدام VIM sudo vim /etc/nginx/sites-enabled/myapp عدل على الملف ليصبح وفق الآتي، واستبدل myapp باسم تطبيقك، علمًا أننا سنستخدم الملف نفسه لاحقًا لتحديد المجلد deploy_to الخاص بالمكتبة Capistrano: server { listen 80; listen [::]:80; server_name _; root /home/deploy/myapp/current/public; passenger_enabled on; passenger_app_env production; location /cable { passenger_app_group_name myapp_websocket; passenger_force_max_concurrent_requests_per_process 0; } # Allow uploads up to 100MB in size client_max_body_size 100m; location ~ ^/(assets|packs) { expires max; gzip_static on; } } احفظ التغييرات على الملف وأغلقه، ثم أعد تحميل NGINX كما يلي لتطبيق التغييرات: deploy@1.2.3.4 sudo service nginx reload رابعًا: إنشاء قاعدة البيانات سنعرض طريقتين لإنشاء قاعدة بيانات التطبيق، الأولى باستخدام PostgreSQL وهي الخيار الأفضل في بيئة الإنتاج، والثانية باستخدام MySQL، اتبع الأسلوب الذي يناسبك. إنشاء قاعدة بيانات PostgreSQL ثبت في البداية خادم Postgres مع المكتبة libpq التي تسمح بتصريف gem pg وهي مكتبة روبي المخصصة للتعامل مع PostgreSQL. للمزيد يمكنك مشاهدة الفيديو التالي: سينشأ مع التثبيت مستخدم لينكس يدعى postgres يملك الصلاحيات الكاملة على قاعدة البيانات، يمكنك استخدامه لإنشاء مستخدم قاعدة بيانات خاص بتطبيقك، اخترنا له الاسم deploy في مثالنا. ثم أنشئ قاعدة بيانات التطبيق، تدعى في مثالنا myapp، وتأكد أن المستخدم deploy هو مالك قاعدة البيانات، وفق الأوامر التالية: deploy@1.2.3.4 sudo apt-get install postgresql postgresql-contrib libpq-dev sudo su - postgres createuser --pwprompt deploy createdb -O deploy myapp exit والآن يمكنك الاتصال بقاعدة البيانات الجديدة وفق التالي: psql -U deploy -W -h 127.0.0.1 -d myapp استخدم 127.0.0.1 بدلًا من localhost عند الاتصال بقاعدة البيانات. إنشاء قاعدة بيانات MySQL ستحتاج لتثبيت نسختي الخادم server والعميل client من MySQL لإنشاء قاعدة بيانات التطبيق وتصريف روبي gem عبر الواحهة mysql2 (يساعدك الاطلاع على المقال كيفية تثبيت MySQL على أوبونتو 18.04). وبعد التثبيت اكتب الأوامر التالية: deploy@1.2.3.4 sudo apt-get install mysql-server mysql-client libmysqlclient-dev sudo mysql_secure_installation # هذا الأمر مخصص لفتح واجهة سطر الأوامر لنظام MySQL لننشئ المستخدم وقاعدة البيانات mysql -u root -p بعد تنفيذ الأوامر السابقة ستفتح واجهة سطر الأوامر لنظام MySQL وبواسطتها يمكنك إنشاء قاعدة بيانات تطبيقك ومستخدم قاعدة بيانات مخصص لإدارتها ويملك الصلاحيات الكاملة عليها، ويستحسن أن تلتزم بإنشاء مستخدم قاعدة بيانات خاص للتطبيق فهذا الإجراء يُعدّ أكثر آمانًا. عندما تقرأ الأوامر الموجودة أسفل الفقرة سيتبادر لذهنك أننا ننشئ مستخدمين اثنين على قاعدة البيانات لكن ذلك يرجع لاختلاف طريقة تعامل MySQL مع الاتصالات المحلية localhost والبعيدة التي تجري عبر الشبكة أي عبر عنوان IP، وبالأوامر التي كتبناها هنا قد سمحنا بنوعي الاتصال. وانتبه قبل التنفيذ لضرورة استبدال الأسماء المذكورة بما يناسب تطبيقك كما يلي: استبدل myapp باسم قاعدة بياناتك، وهي تماثل اسم التطبيق عادةً. استبدل omeFancyPassword123 بكلمة مرورك. استبدل deploy باسم مستخدم قاعدة البيانات الذي تختاره. deploy@1.2.3.4 CREATE DATABASE IF NOT EXISTS myapp; CREATE USER IF NOT EXISTS 'deploy'@'localhost' IDENTIFIED BY '$omeFancyPassword123'; CREATE USER IF NOT EXISTS 'deploy'@'%' IDENTIFIED BY '$omeFancyPassword123'; GRANT ALL PRIVILEGES ON myapp.* TO 'deploy'@'localhost'; GRANT ALL PRIVILEGES ON myapp.* TO 'deploy'@'%'; FLUSH PRIVILEGES; \q خامسًا: النشر باستخدام Capistrano بعد إتمام تهيئة الخادم وأدواته حان الوقت لتحميل الشيفرة البرمجية الخاصة بالتطبيق إلى مرحلة الإنتاج. وهنا يأتي دور المكتبة Capistrano التي تساعدك على إنشاء نسخ من مستودع تطبيقك في مرحلة الإنتاج، وعلى إنشاء إصداراته الجديدة لاحقًا بكل سهولة. إعداد Capistrano ثَبِّت Capistrano ضمن تطبيق ريلز على حاسوبك المحلي (أي حيث طورت التطبيق وحيث توجد شيفرته البرمجية). ثم أضف جواهر روبي أو gems التالية إلى الملف Gemfile كما يلي: gem 'capistrano', '~> 3.11' gem 'capistrano-rails', '~> 1.4' gem 'capistrano-passenger', '~> 0.2.0' gem 'capistrano-rbenv', '~> 2.1', '>= 2.1.4' ثم نَفِّذ الأوامر التالية من حاسوبك المحلي بهدف تثبيت gems السابقة وتثبيت ملفات الإعدادات الخاصة بالمكتبة Capistrano: bundle cap install STAGES=production وستنشئ بعدها الملفات التالية: Capfile. config/deploy.rb. config/deploy/production.rb. افتح في البداية الملف Capfile وأضِف إليه الأسطر التالية: require 'capistrano/rails' require 'capistrano/passenger' require 'capistrano/rbenv' set :rbenv_type, :user set :rbenv_ruby, '3.3.1' ثم افتح الملف config/deploy.rb لتُعرِّف تطبيقك ضمنه، وتحصل على التفاصيل الخاصة بمستودع التطبيق: set :application, "myapp" set :repo_url, "git@github.com:username/myapp.git" # Deploy to the user's home directory set :deploy_to, "/home/deploy/#{fetch :application}" append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads' # Only keep the last 5 releases to save disk space set :keep_releases, 5 # Optionally, you can symlink your database.yml and/or secrets.yml file from the shared directory during deploy # This is useful if you don't want to use ENV variables # append :linked_files, 'config/database.yml', 'config/secrets.yml' وأخيرًا عَدِّل على الملف config/deploy/production.rb لإضافة عنوان IP العام للخادم إلى عمليات النشر، وذلك وفق التالي، ولا تنسَ استبدال 1.2.3.4 بعنوان خادمك: server '1.2.3.4', user: 'deploy', roles: %w{app db web} يتبقى لنا الخطوة الأخيرة قبل النشر وهي إضافة متغيرات البيئة إلى خادم الإنتاج، لذا افتح جلسة اتصال SSH مع الخادم من حاسوبك المحلي: ssh deploy@1.2.3.4 ونفذ التالي: mkdir /home/deploy/myapp nano /home/deploy/myapp/.rbenv-vars ثم أضف متغيرات البيئة المناسبة لحالتك من بين التالي إلى هذا الملف: # For Postgres DATABASE_URL=postgresql://deploy:PASSWORD@127.0.0.1/myapp # For MySQL DATABASE_URL=mysql2://deploy:$omeFancyPassword123@localhost/myapp RAILS_MASTER_KEY=ohai SECRET_KEY_BASE=1234567890 STRIPE_PUBLIC_KEY=x STRIPE_PRIVATE_KEY=y # etc... احفظ التغييرات على الملف، وستُحَمَّل متغيرات البيئة المذكورة هنا تلقائيًا إلى الخادم في كل مرة تُشَغِّل فيها أوامر روبي داخل مجلد التطبيق على الخادم. يفيدك هذا الأسلوب في تخصيص متغيرات بيئة مستقلة لكل تطبيق تنشره على الخادم. يمكنك الآن نشر التطبيق على خادم الإنتاج، بتنفيذ الأمر التالي من حاسوبك المحلي: cap production deploy اكتب عنوان IP الخادم في متصفح الإنترنت وإذا كانت كافة إعداداتك صحيحة فستظهر أمامك واجهة تطبيق ريلز Rails الذي نشرته. وإذا لم تحصل على واجهة ريلز، فيمكنك تتبع الخطأ بمراجعة ملفات تسجيل الأحداث logs من جلسة اتصال SSH مع الخادم كما يلي: deploy@1.2.3.4 # لعرض ملفات تسجيل الأحداث الخاصة بريلز less /home/deploy/myapp/current/log/production.log # لعرض ملفات تسجيل الأحداث الخاصة بخادم NGINX و Passenger sudo less /var/log/nginx/error.log تنجم أغلب الأخطاء عن وجود خلل في أحد متغيرات البيئة أو ملفات الإعدادات التي جهزناها لمرحلة الإنتاج، وبمجرد وصولك للخطأ وتصحيحه يمكنك إعادة تشغيل تطبيقك أو إعادة نشره ثم التحقق مجددًا من المتصفح لمعرفة النتيجة. سادسًا: توصيات إضافية إلى جانب جودة التطبيق الذي طورته بواسطة روبي أو غيرها وصحة نشره على الخادم، فإن متطلبات العمل في البيئة الحقيقية تفرض عليك الاهتمام بجوانب أخرى مثل: تركيب شهادة SSL على الخادم من خدمة مجانية مثل LetsEncrypt أو غيرها لحماية البيانات المتبادلة مع التطبيق، يساعدك في ذلك مقال تنصيب شهادة SSL مجانية عبر خدمة Let's encrypt على خادوم لينكس على أكاديمية حسوب. تفعيل النسخ الاحتياطي الساعي Hourly Backups أو النسخ الاحتياطي الدوري عمومًا الذي ينسخ بياناتك إلى وحدة تخزين خارجية مثل S3، فهو يخفف من مخاطر ضياع البيانات ويساعدك على استعادتها في حال تعرض خادمك أو تطبيقك لأي عطل أو حادث طارئ. اتباع خطة لتدوير ملفات تسجيل الأحداث logs حتى لا تملأ مساحة التخزين على الخادم دون أن تنتبه لها. اتخاذ التدابير الأمنية الضرورية لحماية الخادم من الهجمات السيبرانية، يفيدك في ذلك مقال 7 تدابير أمنية لحماية خواديمك والمقالات الأخرى الموجودة في قسم حماية على أكاديمية حسوب. ترجمة -وبتصرف- لمقال Deploy Ruby On Rails:Ubuntu 24.04 Noble Numbat in 2024 من موقع Go Rails. اقرأ أيضًا كيفية نشر تطبيق Express وتوسيعه باستخدام إضافة MemCachier من منصة تطبيقات DigitalOcean نشر تطبيقات Flask باستخدام PythonAnywhere نشر التطبيقات وتوزيعها وفق نهج التسليم المستمر فيديو: نشر تطبيق React.js ذو واجهات خلفية Node.js على منصة Heroku
-
يعرض المقال الثالث من سلسلة باش كيفية تمرير الوسطاء 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 في لينكس
-
المتغيرات 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)
-
تعلمنا في المقالات السابقة من سلسلة Pygame التي تشرح طريقة بناء لعبة من الصفر بلغة بايثون3 ووحدة الألعاب Pygame، وكيف نضيف إليها الشخصيات سواء شخصيات الأبطال أو أعداء، ونحركهم بالقفز والركض ورمي المقذوفات مثل الكرات النارية وغيرها، وسنعرض في هذا المقال المتمم للسلسلة طريقة إضافة مؤثرات صوتية تناسب أحداث اللعبة تُشَغَّل في أثناء القتال أو القفز أو جمع الجوائز أو غير ذلك، لكن دعنا في البداية نذكرك بمقالات السلسلة بالترتيب: بناء لعبة نرد بسيطة بلغة بايثون. بناء لعبة رسومية باستخدام بايثون ووحدة الألعاب PyGame. إضافة لاعب إلى اللعبة المطورة باستخدام بايثون و Pygame. تحريك شخصية اللعبة باستخدام PyGame. إضافة شخصية العدو للعبة. إضافة المنصات إلى لعبة بايثون باستخدام الوحدة Pygame محاكاة أثر الجاذبية في لعبة بايثون. إضافة خاصية القفز والركض إلى لعبة بايثون. إضافة الجوائز إلى اللعبة المطورة بلغة بايثون تسجيل نتائج اللعبة المطورة بلغة بايثون وعرضها على الشاشة. إضافة آليات القذف إلى اللعبة المطورة بلغة بايثون. إضافة آليات القذف إلى اللعبة المطورة بلغة بايثون. إضافة المؤثرات الصوتية إلى اللعبة المطورة بلغة بايثون ومكتبة Pygame. توفر المكتبة Pygame طريقةً سهلة لإضافة المؤثرات الصوتية إلى ألعاب الفيديو المطورة بلغة بايثون، وذلك اعتمادًا على وحدة خاصة تسمى mixer module تتيح لك تشغيل صوت واحد أو أكثر حسب طلبك، فيمكنك مثلًا تشغيل موسيقى خلفية background music بالتزامن مع صوت بطل اللعبة وهو يقاتل أو يقفز أو يجمع الجوائز. لن يتضمن هذا المقال تعديلات مباشرةً على الشيفرة البرمجية للعبة التي عملنا عليها خلال السلسلة (كما في فعلنا المقالات السابقة) لكننا سنقدم لك أمثلة للتعليمات المتعلقة بالوحدة mixer وسنشرح لك بالتفصيل كيفية الاستفادة منها ودمجها في لعبتك بخطوات متسلسلة. تشغيل الوحدة mixer اكتب في البداية التعليمة الخاصة بتشغيل الوحدة mixer في قسم الإعدادات setup ضمن شيفرة اللعبة، طبعًا يمكنك جمعها مع في كتلة واحدة مع التعليمات المشابهة لها مثل تعليمة تشغيل pygame وتشغيل pygame.font لتصبح كما يلي: pygame.init() pygame.font.init() pygame.mixer.init() # أضف هذا السطر ملاحظة: يمكنك الحصول على شيفرة اللعبة بشكلها النهائي من المقال الثاني عشر من السلسلة إضافة آليات القذف إلى اللعبة المطورة بلغة بايثون. الحصول على الملفات الصوتية اللعبة خطوتك التالية هي تحديد الأصوات التي تود استخدامها في اللعبة وتوفيرها محليًّا على حاسوبك، فاستخدام الأصوات في اللعبة المطورة بلغة بايثون يتطلب وجودها كملفات على الحاسوب المحلي تمامًا مثل الخطوط والرسوم. إذًا بعد تأمين ملفات الصوت عليك وضعها في حزمة واحدة مع ملفات اللعبة حتى يحصل عليها كل من يلعب بلعبتك. لنبدأ بإنشاء مجلد خاص لحفظ ملفات الصوت ضمن المجلد الرئيسي للعبة إلى جانب مجلدي الصور والخطوط، ولنسميه sound كما يلي: s = 'sound' يتوفر العديد من الملفات الصوتية على الإنترنت لكن قد لا يسمح لك باستخدامها جميعًا بسبب حقوق الملكية، لذا ابحث عن الملفات الصوتية مفتوحة المصدر أو المنشورة تحت رخصة المشاع الإبداعي Creative Commons واستخدمها في لعبتك، وهذه بعض المصادر التي تتيح لك تحميل ملفات الصوت مجانًا وبطريقة قانونية: يحتوي Freesound على ملفات لمختلف أنواع المؤثرات الصوتية. يستضيف موقع Incompetech مجموعة واسعة من الموسيقى المناسبة لتكون موسيقى خلفية للألعاب. يوفر Open Game Art ملفاتٍ متنوعة من المؤثرات الصوتية والموسيقى. لكن احرص دائمًا على قراءة شروط الاستخدام قبل تحميل أي ملف صوتي مجاني واعتماده في لعبتك، إذ يشترط بعض المؤلفون الموسيقيون ومصممو الصوت أن تُنسب الملفات الصوتية إليهم ويذكر أنهم أصحاب الفضل في إنشائها عندما يستخدمها الآخرون مجانًا، وبكل الأحوال يُعدّ ذكر اسم صاحب الملف الصوتي تصرفًا جيدًا وأخلاقيًا لمطوري الألعاب، فهم في نهاية الأمر قد تعبوا على ملفاتهم الصوتية بالطريقة نفسها التي تعبت فيها لتطوير لعبة أو تطبيقك. فأين يُذكر اسم صاحب الملف الصوتي إذًا؟ يُنشأ عادةً ملفٌ نصيٌّ خاص في مجلد اللعبة الرئيسي يسمى CREDIT وتُكتب فيه الملفات الصوتية المستخدمة في اللعبة مع مصادرها. قد يرغب البعض بتأليف مؤثراتهم الصوتية الخاصة، فإذا كنت منهم يمكنك استخدام أدوات Linux Multimedia Studio، أو LMMS ، فهو برنامج مجاني ومفتوح المصدر يساعد على لإنتاج وتحرير الموسيقى وتوليد التأثيرات الصوتية، كما أنه سهل الاستخدام ومتوافق مع معظم المنصات الأساسية، ويوفر لك العديد من الأصوات لتبدأ منها، فضلًا عن أنه يسمح لك بتصدير الملفات الصوتية بتنسيق Ogg Vorbis مفتوح المصدر الذي يسمى اختصارًا OGG. يمكنك معرفة المزيد عن المشاريع والبرمجيات مفتوحة المصدر بمشاهدة هذا الفيديو: إضافة الملفات الصوتية إلى Pygame الآن بعد أن وجدت المؤثرات الصوتية المناسبة للعبتك ستُحَمِّلها غالبًا بصيغة ملفات مضغوطة tar أو zip لذا أول ما سنفعله هو فك ضغطها، ونقل الملفات الصوتية الناتجة إلى المجلد sound الموجود ضمن مجلد اللعبة الرئيسي. انظر بعدها إلى أسماء الملفات الصوتية فإذا وجدتها معقدة أو تتضمن العديد من المحارف الخاصة، أَعِدّْ تسميتها واختر لها أسماءً بسيطة يمكنك استخدامها بسهولة ضمن الشيفرة البرمجية. تعتمد معظم ألعاب الفيديو ملفاتٍ صوتية بصيغة OGG لأنها تجمع بين الجودة العالية وصِغَر حجم الملف، فإذا كانت الملفات الصوتية التي اخترتها للعبتك بصيغة MP3 أو WAVE أو FLAC أو غيرها، احرص على تحويلها إلى صيغة OGG باستعمال أدوات مثل fre:ac و Miro لتضمن توافقيةً أعلى وحجمًا أصغر عند تحميل اللعبة. لنفترض على سبيل المثال أن الملف الصوتي الذي حَمَّلته يدعى ouch.ogg. سننشئ متغيرًا خاصًا لتمثيله في قسم الإعدادات setup ضمن شيفرة اللعبة، ليكن مثلًا المتغير ouch كما يلي: ouch = pygame.mixer.Sound(os.path.join(s, 'ouch.ogg')) تشغيل الأصوات ضمن اللعبة الآن كل ما عليك فعله لتشغيل الصوت ضمن اللعبة هو استدعاء المتغير السابق عندما تحتاجه، فعلى سبيل المثال إذا رغبت بتشغيل الصوت OUCH عندما يصطدم بطلك بأحد الأعداء فستكتب الحلقة التالية: for enemy in enemy_hit_list: pygame.mixer.Sound.play(ouch) score -= 1 وبالطريقة نفسها يمكنك إنشاء مؤثرات صوتية لمختلف أنواع الأحداث في اللعبة، مثل: القفز، وجمع الجوائز، ورمي المقذوفات، والاصطدام بالأشياء… إلخ. إضافة موسيقى خلفية للعبة تساعدك الدالة music (إحدى دوال الوحدة mixer في Pygame) على تشغيل موسيقى أو مؤثرات جوية مثل صوت هواء أو غيره في خلفية background اللعبة، وذلك بخطوتين: أولًا تحميل الملف الصوتي بكتابة الأمر التالي في قسم الإعدادات setup من شيفرة اللعبة: music = pygame.mixer.music.load(os.path.join(s, 'music.ogg')) ثم تشغيل الدالة music كما يلي: pygame.mixer.music.play(-1) تعني القيمة 1- أن الدالة ستعمل إلى ما لا نهاية من دون توقف وهذه سمة الموسيقى الخلفية، لكن يمكنك استخدام أي عدد آخر بدءًا من 0 وما فوق لتحديد عدد المرات التي ستعمل فيها الدالة music قبل أن تتوقف. طوّر اللعبة ولا تتوقف هنا لا تتوقف عند ما تعلمناه في هذه السلسلة عن Pygame جرب إضافة المزيد من الأصوات والمراحل والمؤثرات الحركية إلى لعبتك، تعلَّم المزيد عنها فهي تضفي النكهة على لعبتك وتساهم في جعلها مفضلة لدى المستخدمين. ترجمة -وبتصرف- لمقال Add sound to your Python game لصاحبه Seth Kenlon. اقرأ أيضًا المقال السابق: إضافة آليات القذف إلى اللعبة المطورة بلغة بايثون مطور الألعاب: من هو وما هي مهامه تعرف على أشهر لغات برمجة الألعاب الأدوات المستخدمة في بناء الواجهات الرسومية في بايثون البرمجة باستخدام لغة بايثون في تطبيقات راسبيري باي تعرف على مجالات وتطبيقات لغة بايثون
-
كتابة سكربتات باش 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) الموجودة على حاسوبك
-
حسام أحمد3 بدأ بمتابعة رشا سعد
-
كوبرنيتس Kubernetes هو نظام تنسيق حاويات شهير ومفتوح المصدر، يستخدم لأتمتة نشر البرامج وتوسيعها وإدارتها، ويزداد الاعتماد عليه في الشركات والمؤسسات يومًا بعد يوم لتسهيل عمليات التوسعة الأفقية horizontal scaling لموارد الخادم، ويُقصد بها إضافة المزيد من الخوادم حسب الحاجة لزيادة الموارد المتاحة لتطبيقك، مثل: الحجوم التخزينية وقدرة المعالجة وغيرها. يمكنك الحصول على حلول Kubernetes السحابية من مزودي خدمات سحابية متعددين ولكل خدمة مميزات خاصة في الإدارة وغيرها. يتطلب العمل مع كوبرنيتس Kubernetes استخدامًا مكثفًا للموارد الحاسوبية، لأنه يعمل في نظام عنقودي يتكون من عدة خوادم، ويُشكل ذلك عبئًا إضافيًا على المطورين وخصوصًا في مرحلة ما قبل الإنتاج، فسيحتاجون الكثير من الموارد لتطوير مكدس Kubernetes تجريبي واختباره قبل النشر في البيئة الفعلية، لذا أنشأ مطورو Kubernetes مشروعًا مساعدًا مخصص لهذا الغرض يدعى minikube، الذي يعمل مع بيئات تشغيل الحاويات مثل دوكر Docker وغيره، ويستطيع محاكاة عنقود Kubernetes كامل على آلة واحدة فقط هي حاسوبك الشخصي مثلًا. فما هو minikube المحاكي الشهير لنظام Kubernetes؟ وكيف يستخدم لاختبار إعدادات Kubernetes قبل نشرها في بيئة الإنتاج؟ وما هي لوحة معلومات Kubernetes المضمنة فيه؟ سيجيبك المقال عن هذه الأسئلة، ويعطيك طريقة تثبيته على حاسوبك المحلي أو خادمك البعيد، ثم سنعمل معًا على نشر تطبيق تجريبي بسيط، ونحاول الوصول إليه عبر minikube، وفي الختام سنتعرف على طريقة استخدام Minikube مع عناقيد Kubernetes البعيدة بواسطة ملفات تعريف الإعدادات configuration profiles. متطلبات العمل ستحتاج المتطلبات الأولية التالية لتطبيق خطوات العمل المذكورة في المقال: فهم أساسيات Kubernetes، تفيدك مطالعة مقال تعرّف على كوبرنيتس Kubernetes لتكوين فكرة جيدة عن أبرز مفاهيم Kubernetes ومكوناته. تثبيت بيئة تشغيل الحاويات Docker على حاسوبك الذي ستعمل منه، إذ سنُشغل منها minikube. إذا كنت تستخدم نظام تشغيل لينكس، فستساعدك الخطوات الواردة في مقال كيفية تثبيت دوكر واستخدامه على دبيان، ولسهولة العمل احرص على تنفيذ الخطوة المتعلقة بضبط الإعدادات اللازمة لتشغيل Docker بدون الحاجة لكتابة sudo في بداية كل أمر. أما إذا كنت تعتمد نظام تشغيل ويندوز أو ماك فيمكنك الاستعانة بتوثيقات Docker الرسمية لإتمام عملية التثبيت. مدير الحزم Homebrew، يمكنك الاسترشاد بالخطوات الواردة في هذا المقال على DigitalOcean لتثبيته على نظام تشغيل ماك، أو بمقال لتثبيته على لينكس، وفي حال كنت تستخدم نظام ويندوز فتستطيع تثبيته باستخدام WSL نظام ويندوز الفرعي لنظام لينكس . توفير الموارد الحاسوبية اللازمة للبيئة التي ستُثَبِّت فيها Minikube، وهي بالحد الأدنى: وحدتي معالجة مركزية 2CPUs، وذاكرة مخبئية 2GB RAM، ومساحة تخزينية على القرص الصلب بسعة 20GB. الخطوة 1: تثبيت Minikube وتشغيله ثبّت minikube بواسطة مدير الحزم Homebrew كما يلي: $ brew install minikube وستحصل على خرج يشبه التالي، يبين لك نجاح التثبيت: … ==> Installing minikube ==> Pouring minikube--1.25.2.x86_64_linux.bottle.tar.gz ==> Caveats Bash completion has been installed to: /home/sammy/.linuxbrew/etc/bash_completion.d ==> Summary 🍺 /home/sammy/.linuxbrew/Cellar/minikube/1.25.2: 9 files, 70.0MB … ملاحظة: يتطلب تثبيت minikube على نظام ويندوز الانتباه لبعض التفاصيل المهمة: يعمل minikube مع WSL2 (وهي النسخة المتوفرة من WSL لتاريخ نشر المقال)، وينبغي تهيئته ليستخدم Docker واجهةً خلفية backend بدلًا من واجهته الخلفية الافتراضية. لذا بعد تثبيت Docker احرص على تفعيل ميزة دعم WSL2 باتباع إرشادات توثيقات Docker الخاصة بالموضوع ثم ثبت minikube ونفذ الأمر minikube config set driver docker. اكتب الآن الأمر start وفق التالي لبدء تشغيل minikube، وسينشأ بداخله آليًّا عنقود Kubernetes محلي بأحدث إصدار مستقر متوفر، ويتضمن عدة حاويات Docker: $ minikube start سيتطلب التشغيل بعض الوقت، وستحصل في نهايته على الخرج التالي، مع تجهيز الأداة kubectl لتستخدمها للاتصال مع العنقود cluster، كما يوضح السطر الأخير من الخرج: 👍 Starting control plane node minikube in cluster minikube 🚜 Pulling base image ... 💾 Downloading Kubernetes v1.23.1 preload ... > preloaded-images-k8s-v16-v1...: 504.42 MiB / 504.42 MiB 100.00% 81.31 Mi > gcr.io/k8s-minikube/kicbase: 378.98 MiB / 378.98 MiB 100.00% 31.21 MiB p 🔥 Creating docker container (CPUs=2, Memory=1987MB) ... 🐳 Preparing Kubernetes v1.23.1 on Docker 20.10.12 ... ▪ kubelet.housekeeping-interval=5m ▪ Generating certificates and keys ... ▪ Booting up control plane ... ▪ Configuring RBAC rules ... 🔎 Verifying Kubernetes components... ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5 🌟 Enabled addons: default-storageclass, storage-provisioner 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default ملاحظة: يمكنك اختيار إصدار Kubernetes الذي يناسبك لأسباب تتعلق بالتوافقية أو غيرها، بدلًا من الاعتماد على الإصدار الافتراضي الذي يوفره minikube، وذلك بكتابة رقم الإصدار المطلوب بعد الأمر minikube start بهذا الشكل kubernetes-version v.1.2.3--. يسمح لك تثبيت minikube بواسطة مدير الحزم Homebrew بالعمل مباشرةً مع kubectl الأداة الأساسية لإدارة عناقيد Kubernetes باستخدام سطر الأوامر، وبالتالي يمكنك كتابة الأمر kubectl get كما يلي لاستعراض جميع pods العاملة في العنقود بالطريقة نفسها المتبعة مع عناقيد Kubernetes العادية: $ kubectl get pods -A يعرض الوسيط A- كافة pods العاملة في جميع مساحات الأسماء namespaces الموجودة ضمن العنقود، ألقِ نظرة على شكل الخرج للأمر السابق: NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-64897985d-ttwl9 1/1 Running 0 46s kube-system etcd-minikube 1/1 Running 0 57s kube-system kube-apiserver-minikube 1/1 Running 0 61s kube-system kube-controller-manager-minikube 1/1 Running 0 57s kube-system kube-proxy-ddtgd 1/1 Running 0 46s kube-system kube-scheduler-minikube 1/1 Running 0 57s kube-system storage-provisioner 1/1 Running 1 (14s ago) 54s لديك الآن عنقود Kubernetes محلي، تستطيع إدارته باستخدام أدوات Kubernetes المألوفة مثل kubectl، وسنعرض في الفقرات القادمة وظائف إضافية يوفرها لك minikube لمراقبة عناقيد Kubernetes وإدارتها والتعديل عليها. الخطوة 2: الوصول إلى لوحة معلومات Kubernetes يوفر minikube لمستخدميه وصولًا سهلًا للوحة معلومات النظام Kubernetes Dashboard، التي يمكنك استخدامها لمراقبة سلامة العنقود ولنشر التطبيقات يدويًا ولغيرها من أعمال الإدارة. وفور تثبيت minikube محليًا على حاسوبك تستطيع الوصول إلى لوحة معلومات Kubernetes بكتابة الأمر minikube dashboard: $ minikube dashboard سيُشغّل هذا الأمر لوحة المعلومات آليًّا، ويفتح منفذًا port خاصًا داخل Kubernets يوجه حركة البيانات إلى العنقود، ثم يعرض رابط اللوحة الذي يشير إلى رقم المنفذ مباشرةً أمامك في متصفح الويب، كما في الصورة التالية. يؤدي تشغيل لوحة المعلومات إلى تعطيل النافذة الطرفية terminal التي كَتَبّتَ أمر التشغيل فيها، فلا يمكنك كتابة أوامر أخرى ضمنها، لذا يلجأ المستخدمون إلى تشغيل لوحة المعلومات في نافذة طرفية أخرى غير التي يعملون عليها. يمكنك إيقاف هذه العملية المُعطِّلة وغيرها من العمليات المشابهة بالضغط على Ctrl+C. أما إذا كنت تستخدم minikube على خادم بعيد، فأضِف الوسيط url-- إلى الأمر minikube dashboard السابق، وسيعطيك في الخرج رابط URL الخاص بلوحة المعلومات، بدلًا من فتحه مباشرة في المتصفح. ألقِ نظرة على الأمر التالي الخاص بتشغيل اللوحة للخادم البعيد: $ minikube dashboard --url وسيكون الخرج كما يلي: 🤔 Verifying dashboard health ... 🚀 Launching proxy ... 🤔 Verifying proxy health ... http://127.0.0.1:34197/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ يختلف رقم المنفذ الذي يفتحه minikube للوحة المعلومات من نظامٍ إلى آخر، ستلاحظ أن رقمه على حاسوبك مختلفٌ عن رقمه هنا في هذا المثال. تمنع إعدادات الأمان الافتراضية لنظام Kubernetes الوصول إلى عنوان URL هذا من الأجهزة البعيدة لحمايته، لذا ينبغي عليك بدايةً إعداد قناة SSH آمنة مع الخادم قبل فتحه. اكتب إذاً الأمر التالي مع الراية L- لفتح قناة ssh بين الحاسوب المحلي والخادم البعيد، واكتب ضمنه رقم منفذ لوحة المعلومات الظاهر في الخرج السابق، وعنوان IP لخادمك البعيد ليصبح بهذه الصيغة: $ ssh -L 34197:127.0.0.1:34197 sammy@your_server_ip يمكنك بعد ذلك الدخول إلى لوحة المعلومات باستخدام الرابط: http://127.0.0.1:34197/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/. يمكنك معرفة المزيد عن تقنية الاتصال الآمن SSH بمطالعة الفيديو التالي: الآن بعد أن اختبرنا التعامل مع minikube مثل أي عنقود Kubernetes كامل عن طريق لوحة المعلومات، سننتقل للخطوة التالية، ونحاول نشر تطبيق تجريبي بسيط في هذا العنقود لنتأكد من عمله كما هو بالطريقة المرجوة منه. الخطوة 3: نشر تطبيق تجريبي واختباره يمكنك استخدام الأمر kubectl لنشر تطبيق تجريبي في عنقود Minikube. اكتب مثلًا الأمر التالي الذي سيؤدي إلى نشر تطبيق Kubernetes تجريبي متاح للاختبارات من شركة جوجل يدعى hello-app. $ kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0 يُنشئ هذا الأمر عملية نشر deployment داخل العنقود تدعى web، وتُبنى انطلاقًا من صورة بعيدة تسمى hello-app موجودة في سجل حاويات جوجل المسمى gcr.io. سنُعَرِّف الآن عملية النشر web بصفتها خدمة من خدمات Kubernetes، ونحدد منفذًا ثابتًا للاتصال معه بكتابة المحددين port=8080-- و type=NodePort--، وفق التالي: $ kubectl expose deployment web --type=NodePort --port=8080 يمكنك معرفة المزيد عن خدمات Kubernetes وكيفية الاتصال معها بمطالعة مقال تعرّف على كوبرنيتس Kubernetes. لنتحقق فيما إذا كانت الخدمة تعمل أم لا؟ بواسطة الأمر kubectl get service مع كتابة اسم الخدمة بعده، كما يلي: $ kubectl get service web ستحصل على خرج يشبه الخرج التالي، مع اختلاف في أرقام المنافذ لأن NodePort توزع أرقام المنافذ عشوائيًا على خدمات Kubernetes: NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web NodePort 10.109.254.242 <none> 8080:31534/TCP 10s يمكننا الآن استخدام minikube للحصول على عنوان URL المتاح من خارج الحاوية، يسمح لك هذا العنوان بالاتصال مع خدمة التطبيق hello-app العاملة على المنفذ 8080 داخل العنقود. إذا كنت تستخدم Minikube على حاسوبك المحلي، فلست بحاجة لإعادة توجيه حركة البيانات من منفذ لآخر كما سنذكر لاحقًا، فقط نفذ الأمر minikube service web --url التالي، وستحصل على عنوان URL لتطبيقك التجريبي: $ minikube service web --url وسيكون الخرج عنوان URL مثل التالي: http://192.168.49.2:31534 اختبر عنوان URL بواسطة crul، وهو أحد أشهر برامج سطر الأوامر command line المستخدمة لإرسال أنواع مختلفة من طلبات الويب، يستخدم للتحقق من إمكانية عمل عناوين URL ضمن المتصفح في ظروف مناسبة، لذا ننصحك بفحص الروابط باستخدام crul دائمًا قبل تجربتها في المتصفح، وذلك وفق التالي: $ curl http://192.168.49.2:31534 يبين لك الخرج التالي نجاح العملية: Hello, world! Version: 1.0.0 Hostname: web-746c8679d4-j92tb يمكنك الآن استعراض عنوان URL هذا في المتصفح مباشرةً إذا كانت تستخدم minikube محليًا، وستحصل على النص السابق غير المنسق نفسه الذي حصلت عليه بتعليمة crul. أما إذا كنت تعمل على جهاز بعيد، استخدم اتصال SSH كما في الخطوة 2، ثم استعرض العنوان في المتصفح. أصبحت لديك الأساسيات اللازمة لنشر تطبيق عبر minikube فما ينطبق على التطبيق التجريبي البسيط الذي نشرناه يتنطبق نفسه على المشاريع الأكبر حجمًا، والتخصيص الإضافي الذي ستحتاجه فيها يتعلق بنظام Kubernetes وليس بوظائف minikube. سنتعلم في خطوتنا التالية طريقة استخدام بعض أدوات Minikube المدمجة لتغيير بعض الإعدادات الافتراضية للعنقود. الخطوة 4: إدارة نظام ملفات Minikube وموارده يوفر لك minikube عددًا من الأوامر الخاصة بتعديل إعدادات العنقود، فمثلًا يمكنك استخدام الأمر minikube config لتعديل الذاكرة المتوفرة للعنقود وفق التالي، علمًا أن الذاكرة هنا تقدر بالميجابايت MB وبالتالي يقابل الأمر minikube config 4096 توفير ذاكر بسعة 4GB لعنقودك: $ minikube config set memory 4096 ستحصل على الخرج التالي: ❗ These changes will take effect upon a minikube delete and then a minikube start يشير الخرج السابق إلى أن تعديل الذاكرة يتطلب إعادة نشر العنقود ليأخذ مفعوله. ملاحظة: لا تتطلب جميع التعديلات على الموارد إعادة نشر عنقود Kubernetes لتأخذ مفعولها، ففي بيئات الإنتاج يسري تغيير الذاكرة مباشرةً بدون إعادة نشر، لكن مع ذلك حاول أن لا تجري الكثير من التعديلات على عناقيد Kubernetes قيد التشغيل اعتمادًا على ملفات الإعدادات فقط بدون إجراء إعادة نشر، حاول الالتزام بإعادة النشر بعد كل تعديل على الموارد. تتضمن إعادة النشر مرحلتين هما minikube delete و minikube start، اكتب أولًا الأمر: $ minikube delete وستحصل على الخرج التالي: 🔥 Deleting "minikube" in docker ... 🔥 Deleting container "minikube" ... 🔥 Removing /home/sammy/.minikube/machines/minikube ... 💀 Removed all traces of the "minikube" cluster. ثم اكتب الأمر: $ minikube start يتيح لك minikube وصل أي مجلد من نظام ملفاتك المحلي الموجود على حاسوبك إلى داخل العنقود وصلًا مؤقتًا باستخدام الأمر minikube mount. أما كيفية كتابة الأمر mount قواعديًا فهي على الشكل التالي: local_path:minikube_host_path. يرمز local_path إلى مسار المجلد المحلي الذي تريد إيصاله إلى داخل العنقود، ويشير الجزء الآخر أي minikube_host_path إلى الموقع أو المجلد داخل VM أو داخل حاوية Minikube الذي تود أن تصل منه إلى ملفاتك. ألقِ نظرة على الأمر التالي الذي يوصل المجلد الأساسي الخاص بك home directory إلى المجلد host/ داخل عنقود minikube: $ minikube mount $HOME:/host وستحصل على الخرج التالي الذي يؤكد لك نجاح العملية: 📁 Mounting host path /home/sammy into VM as /host ... ▪ Mount type: ▪ User ID: docker ▪ Group ID: docker ▪ Version: 9p2000.L ▪ Message Size: 262144 ▪ Options: map[] ▪ Bind Address: 192.168.49.1:43605 🚀 Userspace file server: ufs starting ✅ Successfully mounted /home/sammy to /host 📌 NOTE: This process must stay alive for the mount to be accessible ... تفيدك هذه الطريقة في الحالات التي تحتاج فيها للحفاظ على مدخلات أو مخرجات ثابتة لعملك مع العنقود، مثل عمليات تسجيل الأحداث logging لعنقود minikube. تعطل هذه العملية نافذة الطرفية فلا يعود بإمكانك كتابة الأوامر فيها، يمكنك الخروج منها بالضغط على Ctrl+C، تمامًا كما فعلنا في حالة فتح المنفذ الخاصة بلوحة المعلومات التي ذكرناها في الخطوة 2. سنتعلم في الخطوة التالية كيف تتنقل بكفاءة بين minikube وعنقود Kubernetes كامل موجود على خادم بعيد. التعامل مع أكثر من عنقود Kubernetes يستطيع minikube التعامل مع عناقيد Kubernetes محلية متعددة في الوقت نفسه، فيُهيئ لكل عنقود ملف تعريف profile خاص به. فقد تحتاج في بعض الحالات للتعامل مع إصدارات مختلفة من عناقيد Kubernetes لإجراء اختبار معين مثلًا، فيمكنك عندها التبديل بين هذه الإصدارات باستخدام الراية p- أو profile--. وإذا كنت ستعمل مع عنقود معين لفترة طويلة أو أكثر من بقية العناقيد، فيمكنك تعيينه ليكون ملف التعريف الافتراضي في minikube بواسطة الأمر minikube profile، بدلًا من تحديده بعد الراية profile-- في كل أمر تنفذه. لنُشغّل الآن Minikube مع ملف تعريفي جديد بتنفيذ الأمر minikube start مع الراية p-، وفق التالي: $ minikube start -p new-profile اضبط الآن هذا الملف التعريفي الجديد ليكون هو الملف الفعال أو الافتراضي في Minikube بكتابة الأمر minikube profile كما يلي: $ minikube profile new-profile سيظهر لك هذا الخرج: ✅ minikube profile was successfully set to new-profile يمكنك معرفة الملف التعريفي الحالي الذي تستخدمه بواسطة الأمر get profile كما يلي: $ minikube config get profile وسيعيد لك الخرج اسم الملف التعريفي الحالي وهو في مثالنا: new-profile يُنشئ minikube ملفات الإعدادات لمنظومتك، ويخزنها هذه الملفات في مكانها الافتراضي المعروف للأداة kubectl ولغيرها من أدوات Kubernetes لتتمكن من الوصول إليها، ذلك سواء كنت تستخدم ملف تعريفي واحد أو عدة ملفات تعريفية، فمثلًا في كل مرة تنفذ فيها الأمر kubectl get nodes لاستعراض بيانات العقد nodes لعنقود minikube ستُحلل kubectl ملفات الإعدادات وتعطيك النتيجة، ألقِ نظرة على الأمر أدناه: $ kubectl get nodes وسيبين الخرج العقد الموجودة وهي عقدة واحدة فقط في حالتنا كما يلي: NAME STATUS ROLES AGE VERSION minikube Ready control-plane,master 3h18m v1.23.1 يمكنك اختيار أي ملف إعدادات تريده وإسناده للمُحَدِد kubeconfig لتقرأه kubectl عند بدء تشغيلها بدلًا من الملف الافتراضي الموجود في المجلد kube/confg. /~، وعندها ستستخدم بيانات اعتماد العنقود المذكورة في هذا الملف عوضًا عن تلك الموجودة في الملف الافتراضي. لنفترض أن لديك ملف إعدادات اسمه remote-kubeconfig.yaml مثلًا لعنقود Kubernetes آخر غير عنقودك في Minikube، وتريد استخراج العقد الموجودة فيه، فستكتب حينئذ الأمر التالي: $ kubectl --kubeconfig=remote-kubeconfig.yaml get nodes وستحصل في الخرج على العقد الموجودة في ذلك العنقود، والتي تعمل عن بعد خارج Minikube الخاص بك، وسيبدو الخرج كما يلي: NAME STATUS ROLES AGE VERSION pool-xr6rvqbox-uha8f Ready <none> 2d2h v1.21.9 pool-xr6rvqbox-uha8m Ready <none> 2d2h v1.21.9 pool-xr6rvqbox-uha8q Ready <none> 2d2h v1.21.9 صُمم Kubernetes في الأساس للعمل مع ملف إعدادات واحد لكل عنقود، يُمَرَر للأوامر مثل kubectl وغيره عند التشغيل، ومع ذلك يمكنك دمج عدة ملفات إعدادات مع بعضها، إلّا أنها ليست الطريقة المفضلة ولا تُعدّ ضرورية إذ سيضعب عليك بعدها تتبع أفضل الممارسات الموصى بها للعمل مع Kubernetes. ننصحك أيضًا بالتَعَرُّف على Krew مدير الحزم الخاص بإضافات Kubectl plugins. الخلاصة وضح هذا المقال كيفية تثبيت Minikube محليًا على الحاسوب الشخصي، واستخدام لوحة معلومات Kubernetes المُضمنة لمراقبة التطبيقات ونشرها، مع الإضاءة على الفكرة الأهم، وهي إمكانية العمل على نشر مثيل instance تجريبي للتطبيق واختباره محليًا ضمن minikube بالتزامن مع وجود مثيل Kubernetes بعيد نصل إليه بواسطة ملفات تعريف Minikube والراية kubectl --kubeconfig. خلاصة القول: يساعدك minikube على اختبار إعدادات Kubernetes وتقييمها محليًا قبل نشرها الفعلي، لتحدد كيف ومتى تصبح جاهزًا لنشر Kubernetes في بيئة الإنتاج. ترجمة -وبتصرف- للمقال How To Use minikube for Local Kubernetes Development and Testing لصاحبه Alex Garnett. اقرأ أيضًا تعلم أساسيات Kubernetes نشر التطبيقات وتوزيعها وفق نهج التسليم المستمر نظام كوبيرنتس Kubernetes وكيفية عمله أبرز المفاهيم التي يجب عليك الإلمام بها عن الحاويات