-
المساهمات
25 -
تاريخ الانضمام
-
تاريخ آخر زيارة
إنجازات زينب الزعيم
عضو مساهم (2/3)
6
السمعة بالموقع
-
Ail Ahmed بدأ بمتابعة زينب الزعيم
-
يجب التصريح عن نوع كل متغير في اللغة التي يحدَّد فيها نوع المتغير typed language مثل اللغة C، إذ يُعلِم النوع المصرِّف مالذي يتوقع تخزينه في المتغير، وبالتالي يستطيع المصرّف تخصيص مساحة كافية لهذا الاستخدام، والتحقق من أن المبرمج لا ينتهك قيود النوع المحدَّد معايير اللغة C من الضروري الاطلاع قليلًا على تاريخ اللغة البرمجية C على الرغم من الاختلاف الطفيف بينها وبين بقية اللغات، إذ تُعَدّ C بأنها اللغة السائدة في عالم برمجة الأنظمة، فكل نظام تشغيل ومكتباته المرتبطة به التي يشيع استخدامها مكتوبة باللغة C، كما يوفِّر كل نظام مصرِّفًا compiler للغة C، وقد وضِع معيار صارم لهذه اللغة للحد من اختلافها بين هذه الأنظمة والتي من المؤكد أنّ كل منها سيجري العديد من التغييرات التي لن تتوافق مع بعضها. يُعرَف هذا المعيار رسميًا باسم ISO/IEC 9899:1999(E)، لكن يشار إليه عادةً بالاختصار C99، إذ تشرف عليه منظمة المعايير الدولية ISO، كما أتيح شراء المعيار كاملًا على الإنترنت، ولم تَعُد الإصدارات القديمة من هذا المعيار مثل الإصدار C89 -الذي سبق C99 وأصدِر في عام 1989- و ANSI C شائعة الاستخدام، وأصبحت جزءًا من أحدث معيار، كما أنّ توثيق المعيار تقني بحت ويذكر بالتفصيل تقريبًا جميع نواحي اللغة، إذ يشرح مثلًا بنيتها بصيغة باكوس نور Backus Naur وقيم define# المعيارية والآلية التي يجب أن تعمل وفقها العمليات. من الضروري أيضًا ملاحظة ما الذي لا تحدده معايير اللغة C، والأهم من ذلك أنه يجب أن يكون المعيار ملائمًا لكل معمارية حاسوبية حالية ومستقبلية، وبالتالي يحرص على عدم تحديد المجالات التي تعتمد على المعمارية، كما يُعَدّ الرابط بين معيار اللغة C والمعمارية الأساسية هو واجهة التطبيق الثنائية Application Binary Interface -أو ABI اختصارًا- التي سنتحدث عنها لاحقًا، كما سيذكر المعيار في عدة مواضع أن أية عملية أو بنية معيّنة سيكون لها نتيجة غير محددة أو نتيجة تعتمد على التنفيذ، ومن البديهي أن المبرمج لا يمكنه الاعتماد على هذه النتائج إذا كان يريد كتابة شيفرة برمجية محمولة portable. جنو سي GNU C ينفِّذ مصرِّف GNU C -والذي يشار إليه عادةً بالاختصار gcc- معيار C99 بالكامل تقريبًا، ويطبِّق أيضًا مجموعة إضافات للمعيار سيستخدمها المبرمجون غالبًا للحصول على خصائص وظيفية إضافية على حساب قابلية النقل إلى مصرِّف آخر، إذ ترتبط هذه الإضافات عادةً بالشيفرة البرمجية ذات المستوى المنخفض low level code وهي أكثر شيوعًا في مجال برمجة النظم؛ أما أكثر إضافة يشيع استخدامها في هذا المجال، فهي شيفرة التجميع المُضمّن inline assembly، كما يجب على المبرمجين قراءة توثيق مصرِّف GNU C وفهم متى قد يستخدِمون الخصائص الإضافية على المعيار. يمكن توجيه مصرِّف GNU C للالتزام بدقة بالمعيار مثل راية std = c99- والتحذير أو توليد خطأ عند تنفيذ أمور معينة لا تتوافق مع المعيار. وهذا طبعًا يناسبك عندما تكون بحاجة إلى ضمان إمكانية نقل شيفرتك البرمجية بسهولة إلى مصرِّف آخر. الأنواع نحن المبرمجون معتادون على استخدام المتغيرات لتمثيل مساحة من الذاكرة لتحمل قيمةً، إذ يجب التصريح عن نوع كل متغير في اللغة التي يُحدَّد فيها نوع المتغير typed language مثل اللغة C، كما يخبر النوع المصرِّف مالذي يتوقع تخزينه في المتغير، وبالتالي سيستطيع المصرِّف تخصيص مساحة كافية لهذا الاستخدام والتحقق من أنّ المبرمج لا ينتهك قيود النوع المحدَّد، وسنجد في الصورة التالية مثالًا على المساحة المخصصة لبعض الأنواع الشائعة من المتغيرات. (الأنواع) يذكر معيار C99 أصغر حجم ممكن لكل نوع من أنواع المتغيرات المعرَّفة في اللغة C فقط، وذلك لأنّ الحجم الأمثل للأنواع يختلف اختلافًا كبيرًا بين مختلف معماريات المعالجات وأنظمة التشغيل، ولكي تكون العملية صحيحةً تمامًا يجب ألا يفترض المبرمجون أبدًا حجم أيّ من متغيراتهم، لكن يحتاج نظام التشغيل الفعال بطبيعة الحال إلى اتفاقات حول الأحجام التي ستحجزها أنواع المتغيرات في النظام، كما تتقيد كل معمارية ونظام تشغيل بواجهة التطبيق الثنائية Application Binary Interface -أو ABI اختصارًا-، إذ تملأ واجهة التطبيق الثنائية لنظام ما التفاصيل التي تربط بين معيار اللغة C ومتطلبات العتاد الصلب الأساسي ونظام التشغيل، كما تُكتَب واجهة التطبيق الثنائية لمجموعة محدَّدة من المعالج ونظام التشغيل. table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } النوع الحجم الأدنى وفق معيار C99 بواحدة البِتّ الحجم الشائع أي معمارية 32 بِتّ char 8 8 short 16 16 int 16 32 long 32 32 long long 64 64 المؤشرات Pointers حسب التنفيذ 32 نلاحظ في مثالنا السابق أنّ الاختلاف الوحيد عن المعيار C99 هو أن حجم المتغير من نوع int هو 32 بِتّ عادةً، وهو ضعف الحد الأدنى الصارم لحجم 16 بت الذي يتطلبه المعيار C99، كما أنّ المؤشرات Pointers هي فعليًا عنوان فقط، أي أنّ قيمتها تكون عنوانًا وبالتالي "تشير" إلى موقع آخر في الذاكرة، لذا يجب تخصيص حجم كافٍ للمؤشر حتى يتمكن من عنونة أيّ موقع في ذاكرة النظام. 64 بت إحدى النواحي المربِكة هي إدراج حوسبة 64 بت، إذ يعني هذا أنّ المعالج يمكنه معالجة العناوين التي تخزَّن على 64 بت وتحديدًا تكون سعة السجلات 64 بِتّ، وهو موضوع سنتناوله في مقال لاحق من هذه السلسلة. يعني هذا أولًا أنّ جميع المؤشرات يجب أن تكون بحجم 64 بِتّ حتى تتمكن من تمثيل أيّ عنوان محتمل في النظام، لكن عندها يجب على منفّذِي النظام system implementers تحديد حجم الأنواع الأخرى، في حين ينتشر استخدام نموذجَين شائعَين على نطاق واسع كما هو موضح في الجدول التالي: النوع الحجم الأدنى وفق معيار C99 بواحدة البِتّ الحجم الشائع LP64 الحجم الشائع في نظام التشغيل ويندوز char 8 8 8 short 16 16 16 int 16 32 32 long 32 64 32 long long 64 64 64 المؤشرات Pointers حسب التنفيذ 64 64 يمكنك ملاحظة أنه في نموذج long pointer 64 أي المؤشرالطويل 64 -أو LP64 اختصارًا- يحدَّد حجم قيم المتغير من نوع Long بـ 64 بِتّ، وهذا يختلف عن نموذج 32 بِتّ الذي عرضناه سابقًا، إذ يستخدَم نموذج LP64 في أنظمة UNIX على نطاق واسع؛ أما في النموذج الآخر، فيبقى حجم المتغير من نوع long بقيمة 32 بت، وهذا يحافظ على أقصى قدر ممكن من التوافق مع الشيفرة البرمجية بنظام 32، إذ يُستخدَم هذا النموذج في نظام ويندوز الذي يدعم 64 بِتّ. تكمن أسباب وجيهة خلف عدم زيادة حجم المتغير من نوع int إلى 64 بِتّ في أيّ من النموذجين، فإذا زاد حجم هذا المتغير إلى 64 بِتّ، فلن تترك للمبرمجين أيّ طريقة للحصول على متغير بحجم 32 بِتّ، وستكون الطريقة الوحيدة هي إعادة تعريف المتغيرات من نوع short لتكون من نوع 32 بِتّ الأكبر. يُعَدّ المتغير بحجم 64 بِتّ كبيرًا جدًا لدرجة أنه ليس مطلوبًا عمومًا لتمثيل العديد من المتغيرات، فنادرًا ما تتكرر الحلقات loops مثلًا عدد مرات أكبر من أن يتسع في متغير حجمه 32 بِتّ الذي يتسع لـ 4294967296 مرة، وعادةً ما تمثَّل الصور بثمانية بِتّات لكل من قيم الأحمر والأخضر والأزرق وثمانية بِتّات إضافية مخصصة للمعلومات الإضافية (قناة ألفا) ما مجموعه 32 بِتّ، وبالتالي سيؤدي استخدام متغير بحجم 64 بِتّ في كثير من الحالات إلى إهدار أول 32 بِتّ على الأقل إذا لم يُهدَر أكثر من ذلك، وليس هذا فحسب، وإنما حجم مصفوفة عدد صحيح integer يتضاعف بذلك أيضًا. يعني هذا أنّ البرامج ستستهلك حجمًا أكبر من ذاكرة النظام دون أيّ تحسن يذكر في أدائه، وبالتالي حجمًا أكبر من ذاكرة التخزين المؤقت cache التي سنتحدث عنها بالتفصيل في مقال لاحق من هذه السلسلة، ولهذا السبب اختار نظام ويندوز الاحتفاظ بتخزين قيم المتغيرات من نوع long في 32 بت، فبما أنّ الكثير من واجهات API على نظام ويندوز قد كُتبَت في الأصل لاستخدام متغيرات من نوع long مخزَّنة على نظام 32 بِتّ، لذا لا تحتاج إلى بِتّات إضافية، مما سيوفر ذلك مساحةً مهدورةً كبيرةً في النظام دون الحاجة إلى إعادة كتابة كامل واجهة API. إذا جربنا البديل المقترَح المتمثل في إعادة تعريف المتغير من نوع short ليكون متغيرًا يخزَّن على 32 بِتّ، فسيستطيع المبرمجون الذين يعملون على نظام 64 بِتّ تحديد هذا النوع للمتغيرات التي يعلمون أنها مرتبطة بقيم أصغر، ولكن عند العودة إلى نظام 32 بِتّ، فسيكون متغير short نفسه الذي حددوه الآن بحجم 16 بِتّ فقط، وهي قيمة تجاوزوها بمراحل كبيرة عمليًا، أي 210 = 65536. سيحقق جعل المبرمج يطلب متغيرات أكبر حجمًا عندما يعلم أنه سيحتاج إليها توازنًا فيما يتعلق بمخاوف قابلية النقل وإهدار المساحة في الأنظمة الثنائية. مؤهلات الأنواع يتحدث معيار اللغة C أيضًا عن بعض المؤهلات qualifiers لأنواع المتغيرات، إذ يشير المؤهل const مثلًا إلى أنّ المتغير لن تُعدَّل قيمته الأصلية أبدًا، والمؤهل volatile يقترح على المصرِّف بأنّ قيمة المتغير قد تتغير بعيدًا عن تدفق تنفيذ البرنامج، لذا يجب أن يحرص المصرِّف على عدم إعادة ترتيب الوصول إليه بأيّ شكل من الأشكال، كما يُعَدّ كل من مؤهل المؤشَّر signed ومؤهل غير المؤشَّر unsigned أنهما المؤهلَين الأهم على الأرجح، فهما يحدِّدان فيما إذا كان يُسمَح للمتغير بأن يأخذ قيمةً سالبةً أم لا، وسنتناول هذا بالتفصيل لاحقًا. الغرض من جميع المؤهلات هو تمرير معلومات إضافية للمصرِّف حول كيفية استخدامِه للمتغير، ويعني هذا أمرَين وهما أنّ المصرِّف قادر على التحقق مما إذا انتهكت القواعد التي وضعتها بنفسك مثل الكتابة في متغير قيمته ثابتة const، وقادر على إجراء تحسينات بناءً على المعلومات الإضافية، وسندرس هذا في مقالات لاحقة من هذه السلسلة. الأنواع المعيارية يدرك واضعو معيار C99 أنّ كل هذه القواعد والأحجام ومخاوف توفر قابلية للنقل قد تصبح مربكةً جدًا، ولتسهيل الأمر فقد قدموا في المعيار سلسلةً من الأنواع الخاصة التي تحدِّد الخصائص المضبوطة للمتغير، وتُحدَّد في الترويسة <stdint.h> وصيغتها qtypes_t، إذ يرمز المحرف q إلى المؤهل ويرمز type إلى النوع الأساسي، في حين يرمز المحرف s إلى الحجم بواحدة البِتّ وt- هو امتداد يشير إلى أنك تستخدِم الأنواع المعرَّفة في معيار C99. تشير الصيغة uint8_t مثلًا إلى عدد صحيح غير مؤشَّر يخزَّن على 8 بِتّات بالضبط، وقد عُرِّفَت العديد من الأنواع الأخرى، إذ يمكنك الاطلاع على القائمة الكاملة المفصَّلة في مقطع المكتبة المعيارية 17.8 لمعيار C99 أو في ملف الترويسة الموجود بصورة مشفَّرة، كما إنّ توفير هذه الأنواع هي مهمة النظام الذي يطبق معيار C99 بأن يحدِّد لها الأنواع ذات الحجم الملائم على النظام المستهدَف، فمثلًا توفِّر مكتبات النظام هذه الترويسات في نظام التشغيل لينكس. لاحظ أنّ معيار C99 فيه عوامل مساعدة لتحقيق قابلية النقل لـ printf، إذ يمكن استخدام وحدات ماكرو PRI macros في <inttypes.h> على أساس عوامل محددة للأنواع التي حُدِّدت أحجامها، وكما ذكرنا يمكنك الاطلاع على المعلومات كاملةً في المعيار أو باستخراج الترويسات. التطبيق العملي للأنواع نرى في النموذج التالي الذي يمثِّل التحذيرات التي ترد عندما لا تتطابق الأنواع مثالًا على فرض الأنواع قيودًا تحدِّد أيّ العمليات المتاح تنفيذها على المتغير وكيف يستعين المصرِّف بهذه المعلومات ليعرض تحذيرًا عند استخدام المتغيرات بطريقة تخالف تلك القيود، إذ نبدأ في هذه الشيفرة البرمجية بإسناد قيمة عدد صحيح integer للمتغير char، وبما أنّ حجم المتغير char أصغر، فسنفقد القيمة الصحيحة للعدد الصحيح integer. نحاول بعدها تعيين مؤشر pointer للمتغير char يشير إلى الذاكرة التي حددنا بأنها عدد صحيح integer، ويمكن تنفيذ هذه العملية، لكنها ليست آمنةً، لذا نُفِّذ المثال الأول على جهاز معالجه بينتيوم Pentium ذو 32 بِتّ، وأعيدَت القيمة الصحيحة، لكن يبلغ حجم المؤشر 64 بتّ -أي 8 بايت- في نظام معالجه إيتانيوم Itanium ذو 64 بِتّ كما هو موضح في المثال الثاني، ولكن حجم العدد الصحيح integer يبلغ 4 بايت فقط، وبالطبع لن تتسع 8 بايت في 4 بايت. يمكننا محاولة خداع المصرف بتحويل القيمة قبل إسنادها، ولاحظ أننا في هذه الحالة فاقمنا المشكلة عندما نفَّذنا هذا التحويل وتجاهلنا تحذير المصرف، لأنّ المتغير الأصغر لا يمكنه الاحتفاظ بجميع المعلومات الواردة من المؤشر، فنتلقى في النهاية عنوانًا غير صالح. 1 /* * types.c */ 5 #include <stdio.h> #include <stdint.h> int main(void) { 10 char a; char *p = "hello"; int i; 15 // نقل متغير كبير إلى متغير أصغر منه i = 0x12341234; a = i; i = a; printf("i is %d\n", i); 20 // نقل المؤشر ليشير إلى متغير من نوع integer printf("p is %p\n", p); i = p; // الخداع بإجراء التحويلات 25 i = (int)p; p = (char*)i; printf("p is %p\n", p); return 0; 30 } 1 $ uname -m i686 $ gcc -Wall -o types types.c 5 types.c: In function 'main': types.c:19: warning: assignment makes integer from pointer without a cast $ ./types i is 52 10 p is 0x80484e8 p is 0x80484e8 $ uname -m ia64 15 $ gcc -Wall -o types types.c types.c: In function 'main': types.c:19: warning: assignment makes integer from pointer without a cast types.c:21: warning: cast from pointer to integer of different size 20 types.c:22: warning: cast to pointer from integer of different size $ ./types i is 52 p is 0x40000000000009e0 25 p is 0x9e0 تمثيل الأعداد سنشرح كيفية تمثيل الأعداد بمختلف مجالاتها مثل الأعداد السالبة والأعداد العشرية وغيرهما. القيم السلبية نميِّز العدد السالب في نظامنا العشري الحديث بوضع علامة الطرح - قبله؛ أما عندما نستخدِم النظام الثنائي، فعلينا اتباع أسلوب مختلف عند الإشارة إلى الأرقام السالبة، إذ يوجد نظام وحيد شائع استخدامه في العتاد الصلب الحديث، لكن معيار C99 يحدِّد ثلاثة أساليب مقبولة لتمثيل القيمة السلبية. بت الإشارة Sign Bit أبسط طريقة هي تخصيص بت واحد من العدد يشير إلى قيمة سالبة أو موجبة حسب هل هو محدَّد أم لا، وهذا مشابه للنهج الرياضي الذي يبين قيمة العدد بإشارتي + و-، إذ يُعَدّ هذا منطقيًا نوعًا ما، وقد مثّلت بعض أجهزة الحاسوب الأولية أعدادًا سالبةً بهذه الطريقة، لكن يتيح استخدام الأعداد الثنائية بعض الاحتمالات الأخرى التي تسهِّل عمل مصممي العتاد الصلب. لاحظ أنّ القيمة 0 قد أصبح لها الآن قيمتان مكافئتان، واحدة حُدِّد فيها بِتّ إشارة وواحدة دون تحديده، وقد يُشار أحيانًا إلى هذه القيم بـ 0+ و 0- على التوالي. المتمم الأحادي One's complement يطبِّق نهج المتمِّم الأحادي العملية not على العدد الموجب لتمثيل العدد السالب، لذا تمثَّل القيمة 90- (0x5A-) مثلًا بـ 10100101 = 01011010~. لاحظ أن العامِل ~ هو عامِل في اللغة C الذي يطبق عامِل NOT على القيمة، كما يدعى أحيانًا بعامِل المتمم الأحادي لأسباب صارت معروفة لدينا الآن. الميزة الأكبر في هذا النظام هي أنه لا يشترط تطبيق منطق خاص عند إضافة عدد سالب إلى عدد موجب، باستثناء أنه يجب إضافة أيّ حمل carry إضافي متبقي إلى القيمة النهائية، لذا تأمل الجدول التالي: النظام العشري النظام الثنائي العملية 90- 10100101 + 100 01100100 --- -------- 10 00001001 1 9 00001010 10 إذا أضفت البتات الواحد تلو الآخر، فستجد أنه سينتج لديك في النهاية بِتّ حمل carry bit الموضَّح في الجدول، وستنتج لدينا القيمة الصحيحة 10 بإضافته مجددًا إلى العدد الأصلي. مجددًا لا تزال لدينا مشكلة تمثيل الصِفرين، ولا يوجد حاسوب حديث يستخدِم المتمم الأحادي، والسبب الرئيسي في ذلك وجود نظام أفضل. المتمم الثنائي Two's Complement يتشابه المتمم الثنائي تمامًا مع المتمم الأحادي، باستثناء أنّ التمثيل السالب يضاف إليه واحد ونتجاهل أيّ بِتّات حمل متبقية، فإذا طبقناه على المثال السابق، فسنمثِّل العدد 90- وفق ما يلي: ~01011010+1=10100101+1 = 10100110 يعني هذا أنّ هناك تماثلًا غريبًا بعض الشيء في الأعداد التي يمكن تمثيلها؛ ففي العدد الصحيح integer مثلًا الذي يخزَّن على 8 بِتّ لدينا 82 = 256 قيمة ممكنة، كما يمكننا تمثيل 127- في نهج تمثيل بِتّ الإشارة بواسطة 127، لكن يمكننا تمثيل 127- في نظام المتمم الثنائي بواسطة 128 لأننا أزلنا مشكلة وجود صفرين، وضَع في الحسبان أنّ الصفر السالب هو (1 + 00000000~) = (1 + 11111111) = 00000000، ولاحظ تجاهل بِتّ الحمل. النظام العشري النظام الثنائي OP العملية 90- 10100110 + 100 01100100 --- -------- 10 00001010 لا بدّ أنك لاحظت أنّ تطبيق المتمم الثنائي لن يُحيج مصممي العتاد الصلب إلا إلى توفير عمليات منطقية لدارات الإضافة، إذ يمكن إجراء عملية الطرح عن طريق متمم ثنائي ينفي القيمة المراد طرحها ثم يضيف القيمة الجديدة، وبالمثل يمكنك تنفيذ عملية الضرب بالجمع المتكرر وعملية القسمة بالطرح المتكرر. وبالتالي يختزل المتمم الثنائي جميع العمليات الحسابية البسيطة بعملية الجمع، ومن الجدير بالذكر أنه تستخدِم جميع الحواسيب الحديثة تمثيل المتمم الثنائي. امتداد الإشارة Sign-extension بناءً على صيغة المتمم الثنائي، عند زيادة حجم القيمة المؤشَّرة signed value، من المهم أن تمدَّد إشارة sign-extended البتات الإضافية، أي المنسوخة من البِتّ الأولي للقيمة الحالية، إذ تمثَّل قيمة العدد الصحيح 10- من نوع int المخزَّن على 32 بت في المتمم الثنائي في النظام الثنائي عبى سبيل المثال بالعدد 111111111111111111111111110110، فإذا أردنا تحويله إلى عدد صحيح من نوع long long int مخزَّن على 64 بِتّ، فعلينا أن نحرص على تعيين الرقم 1 للـ 32 بِتّ الإضافية للاحتفاظ بالإشارة نفسها للعدد الأصلي. بفضل المتمم الثنائي، يكفي أخذ البِتّ الأولي من قيمة الخرج exiting value واستبدال جميع البتات المضافة بهذه القيمة، ويشار إلى هذه العمليات باسم امتداد الإشارة، وعادةً يتعامل معها المصرِّف في الحالات المحدَّدة في معيار اللغة، مع توفير المعالج عمومًا تعليمات خاصة لأخذ قيمة وتمديد إشارتها إلى قيمة أكبر. الأعداد العشرية Floating Point تحدثنا حتى الآن عن الأعداد الصحيحة integer أو الأعداد الكاملة فقط، وتسمى فئة الأعداد التي يمكن أن تمثِّل القيم العشرية بالأعداد العشرية. نحتاج لإنشاء عدد عشري إلى طريقة لتمثيل مفهوم الجزء العشري في النظام الثنائي، ويُعرف النظام الأشيع الذي يحقق ذلك بمعيار الأعداد العشرية IEEE-754 لأن من نشره كان معهد مهندسي الكهرباء والإلكترون، كما يُعَدّ النظام بسيط للغاية من ناحية المفهوم، وهو مشابه إلى حد ما للصيغة العلمية scientific notation. قد تمثَّل القيمة 123.45 عمومًا في الصيغة العلمية بالصيغة 1.2345*102، إذ نسمي 1.2345 الجزء المعنوي significand (أو الجزء الأهم الأساسي الذي له أهمية)؛ أما 10 فهو الأساس radix و 2 هو الأُس exponent. نفكك البتات المتاحة في نموذج العدد العشري IEEE لنمثِّل الإشارة والجزء العشري وأس العدد العشري، إذ يمثَّل العدد العشري بالصيغة: "الإشارة × الجزء المعنوي × الأس2"، ويعادل بِتّ الإشارة إما 1 أو 1-، وبما أننا نعمل في النظام الثنائي، فسيكون لدينا دائمًا الأساس الضمني 2، كما تتنوع أحجام قيمة العدد العشري، وسندرس في الفقرة التالية القيمة التي تخزَّن على 32 بت فقط، وكلما زاد عدد البتات حظينا بدقة أكبر. الإشارة الأس الجزء المعنوي/الجزء العشري S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM العامل المهم الآخر هو انحياز bias الأس، إذ يجب أن يمثِّل الأس القيم الموجبة والسالبة، وبالتالي تُطرَح القيمة الضمنية للعدد 127 من الأس، إذ يحتوي الأس 0 مثلًا على حقل أس يساوي 127، في حين يمثِّل 128 العدد 1 ويمثل 126 العدد 1-. يضيف كل بِتّ من الجزء المعنوي مزيدًا من الدقة إلى القيم التي يمكننا تمثيلها، وضَع في الحسبان تمثيل الصيغة العلمية للقيمة 198765، إذ يمكننا كتابة هذا بالصيغة 1.98765x106، الذي يقابل التمثيل التالي: 10-5 10-4 10-3 10-2 10-1 . 100 5 6 7 8 9 . 1 يتيح كل رقم إضافي مجالًا أكبر من القيم العشرية التي يمكننا تمثيلها، إذ يزيد كل رقم بعد الفاصلة العشرية من دقة العدد بمقدار 10 مرات في النظام العشري، فيمكننا مثلًا تمثيل 0.0 بـ 0.9 -أي 10 قيم- برقم واحد بعد الفاصلة عشرية، و0.00 بـ 0.99 -أي 100 قيمة- برقمين، وهكذا؛ أما في النظام الثنائي، فبدلًا من أن يمنحنا كل رقم إضافي دقة أكبر بعشر أضعاف، لا نحظى إلا بضعفَي الدقة كما هو موضَّح في الجدول التالي، ويعني هذا أنّ التمثيل الثنائي الخاص لا يوجّهنا دائمًا بطريقة مباشرة إلى التمثيل العشري. 10-5 10-4 10-3 10-2 10-1 . 100 5 6 7 8 9 . 1 لا تكون دقة كسورنا كبيرةً جدًا باستخدام بِتّ واحد فقط للدقة، فلا يسعنا إلا أن نقول أنّ الكسر إما 0 أو 0.5، فإذا أضفنا بِتًّا آخرًا للدقة، فيمكننا الآن القول أن القيمة العشرية هي إما 0 أو 0.25 أو 0.5 أو 0.75. ومع إضافة بِتّ آخر للدقة يمكننا الآن تمثيل القيم 0، 0.125، 0.25، 0.375، 0.5، 0.625، 0.75، 0.875. وبالتالي فكلما زدنا عدد البِتّات حظينا بدقة أكبر، لكن بما أنّ مجال الأعداد المحتملة غير محدود، فلن تكفي البِتَات أبدًا لتمثيل أية قيمة محتمَلة، فإذا كان لدينا بِتّين فقط للدقة على سبيل المثال، وأردنا تمثيل القيمة 0.3، فلا يمكننا القول إلا أنها أقرب إلى 0.25، وطبعًا هذا غير كاف في معظم التطبيقات، لكن عندما يكون لدينا 22 بِتّ للجزء المعنوي، فسنحظى بدقة أفضل بكثير، لكن لا يزال ذلك غير كاف في معظم التطبيقات. تزيد قيمة متغير من نوع double عدد بتات الجزء المعنوي إلى 52 بت، كما أنها تزيد مجال قيم الأس أيضًا، كما تخصص بعض الأجهزة 84 بِتّ للعدد العشري، و64 بِتّ للجزء المعنوي، إذ تتيح 64 بِتّ تلك دقةً هائلةً لا بدّ أن تكون مناسبةً لجميع التطبيقات،لشمهم باستثناء التطبيقات شديدة التعقيد والتي تحتاج حجمًا أكبر ( هل هذا كافٍ لتمثيل طول أقل من حجم الذرة؟). 1 $ cat float.c #include <stdio.h> int main(void) 5 { float a = 0.45; float b = 8.0; double ad = 0.45; 10 double bd = 8.0; printf("float+float, 6dp : %f\n", a+b); printf("double+double, 6dp : %f\n", ad+bd); printf("float+float, 20dp : %10.20f\n", a+b); 15 printf("dobule+double, 20dp : %10.20f\n", ad+bd); return 0; } 20 $ gcc -o float float.c $ ./float float+float, 6dp : 8.450000 double+double, 6dp : 8.450000 25 float+float, 20dp : 8.44999998807907104492 dobule+double, 20dp : 8.44999999999999928946 $ python Python 2.4.4 (#2, Oct 20 2006, 00:23:25) 30 [GCC 4.1.2 20061015 (prerelease) (Debian 4.1.1-16.1)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 8.0 + 0.45 8.4499999999999993 35 يُعَدّ النموذج السابق مثالًا عمليًا لما تحدثنا عنه، ولاحظ أنه تتطابق الإجابتان بالنسبة للأجزاء العشرية الستة الافتراضية لتحقيق الدقة التي حددناها في printf، وذلك لأن عملية تقريبهما نفِّذت تنفيذًا صحيحًا، لكن عندما يُطلب منك إعطاء نتائج بدقة أكبر ولتكن في هذه الحالة 20 منزلة عشرية، فسنجد أنها تبدأ في الاختلاف. منحتنا الشيفرة البرمجية التي تستخدِم النوع double نتيجةً أدق، لكنها لا تزال غير صحيحة كليًا، كما أننا نجد أنّ المبرمجين الذين لا يتعاملون بوضوح مع القيم من نوع float لا يزالون يواجهون مشاكل في دقة المتغيرات. القيم الموحدة Normalised Values يمكننا تمثيل قيمة بعدة أساليب مختلفة في الصيغة العلمية مثل 10023x100 = 1002.3x101 = 100.23x102، وبالتالي نعرّف صيغة التوحيد بأنه الصيغة التي يكون فيها 1/radix <= significand < 1، إذ تعني radix الأساس وتعني significand الجزء المعنوي، والعدد الموحَّد normalized number هو العدد المكتوب بالصيغة العلمية scientific notation مع رقم عشري واحد غير صفري على الأقل بعد الفاصلة. يضمن هذا في النظام الثنائي أن يكون البِتّ الذي يقع أقصى اليسار leftmost bit من الجزء المعنوي دائمًا 1، فعند معرفتنا لذلك، يمكننا الحصول على بِتّ إضافي للدقة حسب ما ورد في المعيار أنه عندما يكون البت الأيسر 1 يكون ضمنيًا. العملية الحسابية الأس 2-5 2-4 2-3 2-2 2-1 . 20 0.375 = 1* (0.25+0.125) 02 0 0 1 1 0 . 0 0.375= 5. * (0.5+0.25) 1-2 0 0 0 1 1 . 0 0.375= 0.25 * (1+0.5) 2-2 0 0 0 0 1 . 1 كما ترى في المثال السابق، يمكننا جعل القيمة قيمة موحَّدة من خلال تحريك البِتّات للأمام طالما أننا نعوِّض عن ذلك بزيادة الأس. مهارات التوحيد Normalisation من المشكلات الشائعة التي يواجهها المبرمجون هي العثور على أول بِتّ ضبط في مجموعة البِتّات bitfield، ولنأخذ مجموعة البتات 0100 مثالًا، فعند البدء من اليمين، يكون بِتّ الضبط الأول هو البِتّ 2، إذ نبدأ من الصفر كما هو معتاد. الطريقة المعيارية للعثور على هذه القيمة هي الإزاحة إلى اليمين والتحقق مما إذا كان البِتّ الأول هو 1 أي بت الضبط، ثم إنهاء العملية أو تكرارها، وتُعَدّ هذه عمليةً بطيئةً، فإذا كان طول مجموعة البِتّات 64 بِتّ وكان بِتّ الضبط هو الأخير فقط، فيجب أن تمر بجميع البتات الثلاثة والستين التي تسبقها. لكن إذا كانت قيمة مجموعة البتات هذه هي الجزء المعنوي لعدد عشري وكان علينا توحيدها، فسنعرف من قيمة الأس عدد مرات إزاحتها، كما تضمَّن عملية التوحيد عمومًا في وحدة عتاد العدد العشري على المعالج، لذا تؤدَّى بسرعة كبيرة، وعادةً أسرع بكثير من عمليات الإزاحة والاختبار المتكررة. يوضِّح البرنامج التالي طريقتين للعثور على أول بِتّ ضبط متَّبعتَين على معالج إتانيوم. إذ يدعم المعالج إتانيوم -مثل حال معظم معالجات الخوادم- نوع العدد العشري الموسَّع الذي يخزَّن على 80 بِتّ، والجزء المعنوي الذي يخزن على 64 بِتّ، ويعني هذا أنّ نوع unsigned long يتوافق بدقة في الجزء المعنوي لنوع long double، فعندما تحمَّل القيمة توحَّد، وبالتالي من خلال قراءة قيمة الأس مطروحًا منها انحياز 16 بِتّ يمكننا رؤية مدى انزياحها. 1 #include <stdio.h> int main(void) { 5 // في التمثيل الثنائي = 0000 0000 0000 1000 // عدد البتات 3210 7654 1098 5432 int i = 0x8000; int count = 0; while ( !(i & 0x1) ) { 10 count ++; i = i >> 1; } printf("First non-zero (slow) is %d\n", count); 15 // توحَّد هذه القيمة عندما تُحمَّل long double d = 0x8000UL; long exp; // تعليمات "الحصول على أس العدد العشري" في معالج إتانيوم 20 asm ("getf.exp %0=%1" : "=r"(exp) : "f"(d)); // الأس متضمنًا الانزياح printf("The first non-zero (fast) is %d\n", exp - 65535); 25 } خلاصة الأفكار السابقة نستخرج مكونات العدد العشري ونطبع القيمة التي يمثلها في نموذج الشيفرة البرمجية التالية، إذ سنحرز نتيجةً فقط عندما تكون القيمة عددًا عشريًا بحجم 32 بِتّ بصيغة المعيار IEEE، وهذا شائع في معظم المعماريات من نوع float أي عدد عشري. 1 #include <stdio.h> #include <string.h> #include <stdlib.h> 5 /* 2^n إرجاع */ int two_to_pos(int n) { if (n == 0) return 1; 10 return 2 * two_to_pos(n - 1); } double two_to_neg(int n) { 15 if (n == 0) return 1; return 1.0 / (two_to_pos(abs(n))); } 20 double two_to(int n) { if (n >= 0) return two_to_pos(n); if (n < 0) 25 return two_to_neg(n); return 0; } /* مراجعة بعض أجزاء الذاكرة للمتغير "m" الذي هو الجزء المعنوي 30 للعدد العشري بحجم 24 بت، نبدأ بالمقلوب من البتات في أقصى اليمين دون أي سبب معين */ double calc_float(int m, int bit) { /* 23 بت؛ هذا ينهي العودية */ 35 if (bit > 23) return 0; /* إذا كان البت مضبوطًا، فهو يمثل القيمة 2/1^بت */ if ((m >> bit) & 1) 40 return 1.0L/two_to(23 - bit) + calc_float(m, bit + 1); /* وإلا انتقل إلى البت التالي */ return calc_float(m, bit + 1); } 45 int main(int argc, char *argv[]) { float f; int m,i,sign,exponent,significand; 50 if (argc != 2) { printf("usage: float 123.456\n"); exit(1); 55 } if (sscanf(argv[1], "%f", &f) != 1) { printf("invalid input\n"); 60 exit(1); } /* سنحتاج إلى خداع المصرف، كأننا بدأنا استخدام التحويلات فمثلًا (int)(f) ستجري تحويلًا فعليًا لنا 65 نريد الوصول إلى البتات الأولية، لذا ننسخها إلى متغير بنفس الحجم. */ memcpy(&m, &f, 4); /* بت الإشارة هو أول بت */ 70 sign = (m >> 31) & 0x1; /* الأس هو البتات الثمانية التي تلي بت الإشارة */ exponent = ((m >> 23) & 0xFF) - 127; 75 /* الجزء المعنوي يملأ المنازل العشرية، ويكون أول بت ضمنيًا 1 وبالتالي هو قيمة المعامل OR 24 بت. */ significand = (m & 0x7FFFFF) | 0x800000; /* اطبع قيمةً تمثل الأس */ 80 printf("%f = %d * (", f, sign ? -1 : 1); for(i = 23 ; i >= 0 ; i--) { if ((significand >> i) & 1) printf("%s1/2^%d", (i == 23) ? "" : " + ", 85 23-i); } printf(") * 2^%d\n", exponent); /* اطبع تمثيلًا كسريًا */ 90 printf("%f = %d * (", f, sign ? -1 : 1); for(i = 23 ; i >= 0 ; i--) { if ((significand >> i) & 1) printf("%s1/%d", (i == 23) ? "" : " + ", 95 (int)two_to(23-i)); } printf(") * 2^%d\n", exponent); /* حول هذا إلى قيمة عشرية واطبعه */ 100 printf("%f = %d * %.12g * %f\n", f, (sign ? -1 : 1), calc_float(significand, 0), two_to(exponent)); 105 /* اجرِ العملية الحسابية الآن */ printf("%f = %.12g\n", f, (sign ? -1 : 1) * 110 calc_float(significand, 0) * two_to(exponent) ); return 0; 115 } وفيما يلي نموذج خرج القيمة 8.45 الذي درسناه سابقًا: $ ./float 8.45 8.450000 = 1 * (1/2^0 + 1/2^5 + 1/2^6 + 1/2^7 + 1/2^10 + 1/2^11 + 1/2^14 + 1/2^15 + 1/2^18 + 1/2^19 + 1/2^22 + 1/2^23) * 2^3 8.450000 = 1 * (1/1 + 1/32 + 1/64 + 1/128 + 1/1024 + 1/2048 + 1/16384 + 1/32768 + 1/262144 + 1/524288 + 1/4194304 + 1/8388608) * 2^3 8.450000 = 1 * 1.05624997616 * 8.000000 8.450000 = 8.44999980927 نستخلص من هذا المثال فكرةً عن تسلل عدم الدقة إلى أعدادنا العشرية. ترجمة -وبتصرّف- لقسم من الفصل Chapter 2. Binary and Number Representation من كتاب Computer Science from the Bottom Up. اقرأ أيضًا المقال التالي: تعرف على وحدة المعالجة المركزية وعملياتها في معمارية الحاسوب المقال السابق: تعرف على نظام العد الثنائي Binary أساس الحوسبة المدخل الشامل لتعلم علوم الحاسوب النسخة العربية لكتاب: أنظمة التشغيل للمبرمجين
-
النظام الثنائي هو نظام عددي يكون أساس العدد فيه 2، ويمثل المعلومات بحالتين متنافيتين لا ثالث لهما، ويتكون العدد الثنائي من عناصر تسمى بِتات bits بحيث يمكن أن يكون كل بت بإحدى الحالتين المحتمَلتَين، واللتين نمثلهما عمومًا بالرقمين 1 و 0. نظرية النظام الثنائي النظام الثنائي هو نظام يكون فيه الأساس هو العدد 2 ليمثل المعلومات بحالتين متنافيتين، ويتكون العدد الثنائي من عناصر تسمى بِتّات، إذ يمكن أن يكون كل بِتّ بإحدى الحالتين المحتمَلتين واللتين نمثِّلهما عمومًا بالرقمين 1 و 0، ويمكننا القول أنهما تمثِّلان القيمتَين الصحيحة والخاطئة؛ أما من الناحية الكهربائية، فقد تمثَّل الحالتين بجهد كهربائي مرتفع ومنخفض أو مثل زر التشغيل والإيقاف. نبني الأعداد الثنائية بالطريقة نفسها التي نبني بها الأعداد في نظامنا التقليدي العشري الذي يكون فيه الأساس هو العدد 10، لكن بدلاً من منزلة الآحاد ومنزلة العشرات ومنزلة المئات، …إلخ، لدينا منزلة الواحد ومنزلة الاثنين ومنزلة الأربعة ومنزلة الثمانية، …إلخ، أي كما هو موضح في الجدول التالي: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } 20 21 22 23 24 25 26 2... 1 2 4 8 16 32 64 … لنمثِّل العدد 203 على سبيل المثال في الأساس العشري، إذ نعلم أننا نضع الرقم 3 في منزلة الآحاد، والرقم 0 في منزلة العشرات والرقم 2 في منزلة المئات، ويمثَّل هذا من خلال الأُسس exponents كما في الجدول التالي: 100 101 102 3 0 2 أو نمثلها بطريقة أخرى: 2x 102 + 3 x 100 = 200 + 3 = 203 لنمثِّل العدد نفسه بالنظام الثنائي، إذ سيكون لدينا الجدول التالي: 20 21 22 23 24 25 26 27 1 1 0 1 0 0 1 1 ويكافئ هذا: 27 + 26 + 23 + 21 + 20 = 128 + 64 + 8 + 2 + 1 = 203 دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن أسس الحوسبة قد تتساءل كيف لعدد بسيط أن يكون الأساس الذي بنيَت عليه كل الأمور المذهلة التي يستطيع الحاسوب تنفيذها، ورغم صعوبة تصديق ذلك إلا أنها الحقيقة، إذ يحتوي المعالج الموجود في حاسوبك على مجموعة معقدة -لكنها محدودة في النهاية- من التعليمات instructions التي يمكن تنفيذها على قيم مثل الجمع والضرب، …إلخ، إذ يُسنَد عدد إلى كل تعليمة من هذه التعليمات بصورة أساسية، حتى يمثَّل برنامج كامل بسلسلة من الأعداد فقط، أي أضف هذا إلى ذاك، اضرب بذاك، قسّم عليه، وهكذا، فإذا كان المعالج مثلًا يعلم أنّ العملية 2 هي الجمع، فإنّ العدد 252 قد يعني "اجمع 5 و 2 وخزِّن الناتج في مكان ما"، وتُعَدّ العمليات في الواقع أعقد بكثير طبعًا، إذ سنتناولها في فصل معمارية الحاسوب لاحقًا، لكن باختصار هذا هو الحاسوب. كان بمقدور المرء في عهد البطاقات المثقَّبة punch-cards أن يرى بعينه الواحدات والأصفار التي تكوِّن مسار البرنامج من خلال النظر إلى الثقوب الموجودة على البطاقة، طبعًا تحوّل ذلك اليوم إلى آلية التخزين السريع والدقيق بواسطة قطبية الجزيئات الممغنطة الصغيرة مثل الأشرطة tapes أو الأقراص disks، والذي أتاح لنا حمل كميات هائلة تفوق التصور من البيانات في جيوبنا. إنّ ترجمة هذه الأعداد إلى خدمات تنفع البشرية هي ما يجعل الحاسوب نافعًا لهذه الدرجة، وتتكوّن الشاشات مثلًا من ملايين البكسلات pixels المنفصلة، وكل منها صغير لدرجة لا تميّزه عين الإنسان، لكنها تكوِّن صورةً مكتملةً عندما تكون مجتمعةً، إذ يحتوي كل بكسل عمومًا على عناصر محدَّدة من الأحمر والأخضر والأزرق التي تكوِّن اللون الذي يعرضه، وبالتأكيد يمكن تمثيل هذه القيم بالأعداد التي بالطبع يمكن تمثيلها بالنظام الثنائي، وبالتالي يمكن تقسيم أيّ صورة إلى ملايين النقاط الفردية، وتُمثَّل كل نقطة بمجموعة من ثلاث قيم تمثِّل قيم الأحمر والأخضر والأزرق للبكسل، وبالتالي عندما يكون لدينا سلسلة طويلة من هذه الأعداد وتكون مُصاغةً بصورة صحيحة، فستتمكن أجهزة الفيديو في حاسوبك من تحويل هذه الأعداد إلى إشارات كهربائية لتشغيل وإيقاف البكسلات الفردية لعرض صورة. سنبني بيئة الحوسبة الحديثة بأكملها في الكتاب بدءًا من اللبنة الأساسية هذه، أي من القاعدة إلى القمة إذا صح التعبير. البتات bits والبايتات byts يمكننا بصورة أساسية تمثيل أيّ شيء بعدد كما تحدثنا في الفقرات السابقة، ويمكن تحويله إلى النظام الثنائي وإجراء عمليات عليه بواسطة الحاسوب، إذ سنحتاج على الأقل لتمثيل جميع أحرف الأبجدية مثلًا إلى توليفات مختلفة وكافية لتمثيل جميع المحارف الصغيرة lower case والمحارف الكبيرة upper case والأعداد وعلامات الترقيم إلى جانب بعض الأمور الإضافية، ويعني هذا أننا ربما سنحتاج إلى حوالي 80 توليفة مختلفة. إذا كان لدينا بِتّان، فيمكننا تمثيل 4 توليفات فريدة محتملة وهي 00 01 10 11؛ أما إذا كان لدينا ثلاث بِتّات، فيمكننا تمثيل 8 توليفات مختلفة، وبصورة عامة، إذا كان لدينا عدد n من البِتّات يمكننا تمثيل 2n توليفة فريدة. تمنحنا 8 بِتّات 28 = 256 تمثيلًا فريدًا، وهذا عدد أكثر من كاف للتوليفات الأبجدية التي نحتاجها، كما أننا ندعو كل 8 بِتّات ببايت، كما أنّ حجم المتغير من نوع char هو بايت واحد في لغة C. أسكي ASCII يستطيع أيّ شخص اختلاق رابط بين الأحرف والأعداد عشوائيًا بما أنّ البايت يمكنه تمثيل أيّ قيمة بين 0 و 255، فقد تقرِّر الشركة المصنعة لبطاقات الفيديو مثلًا أنّ رقم 1 يمثل المحرف 'A'، لذا عندما ترسَل القيمة 1 إلى بطاقة الفيديو، ستعرض المحرف 'A' بحالته الكبيرة على الشاشة، وقد تقرِّر الشركة المصنعة للطابعة لسبب ما أن الرقم 1 يمثل 'z' بالحالة الصغيرة، وبالتالي سيتطلب عرض وطباعة الشيء نفسه تحويلات معقدة، ولتجنب حدوث ذلك ابتُكِرت الشيفرة المعيارية الأميركية لتبادل المعلومات American Standard Code for Information Interchange -أو ASCII اختصارًا-، وهذه الشيفرة مبنية على 7 بتات 7-bit code، أي توجد 27 أو 128 شيفرةً متاحةً. ينقسم مجال الشيفرات إلى جزأين رئيسيين هما الشيفرات الغير قابلة للطباعة والشيفرات القابلة للطباعة، إذ تكون المحارف القابلة للطباعة مثل الأحرف الكبيرة والصغيرة والأعداد وعلامات الترقيم، في حين تكون المحارف الغير قابلة للطباعة مخصصةً للتحكم وتنفيذ عمليات مثل محارف الإرجاع carriage-return، أي العودة إلى بداية السطر الحالي دون النزول إلى السطر التالي، أو رن جرس الطرفية عند ورود المحرف Bell أو شيفرة القيمة الفارغة NULL الخاصة التي لا تمثل شيئًا على الإطلاق. تكفي المحارف 127 الفريدة للغة الإنجليزية الأميركية، لكنها تصبح محدودةً جدًا عندما يريد المرء تمثيل المحارف السائدة في اللغات الأخرى وخاصةً اللغات الآسيوية التي قد تحتوي على عدة آلاف من المحارف الفريدة، وللحد من ذلك، تنتقل الأنظمة الحديثة من شيفرة أسكي إلى يونيكود Unicode التي تستخدِم ما يصل إلى 4 بايتات لتمثل محرفًا، وهذا يفسح مجالًا أكبر بكثير. التكافؤ Parity يبقى بت واحد من البايت فائضًا بما أنّ شيفرة الأسكي مبنية على 7 بتات فقط، ويمكن الاستفادة منه في تحقيق التكافؤ parity، إذ يُعَدّ شكلًا بسيطًا من أشكال التحقق من الأخطاء، فتخيّل حاسوبًا يستخدِم بطاقات مثقبة في عملية الإدخال، بحيث يمثِّل وجود الثقب البِتّ 1 وغيابه يمثل البِتّ 0، وستؤدي أية تغطية غير مقصودة لثقب ما إلى قراءة قيمة غير صحيحة وستتسبب في سلوك غير معرَّف. يتيح التكافؤ إجراء فحص بسيط للبِتّات المؤلِّفة للبايت للتأكد من أنها قُرِئت بصورة صحيحة، ويمكننا تنفيذ التكافؤ الفردي أو الزوجي باستخدام البِتّ الفائض الذي نَعدّه بِتّ التكافؤ، فإذا كان عدد الواحدات في المعلومات المخزَّنة على البِتّات السبعة فرديًا، فسيضبط بت التكافؤ ويكون حينها التكافؤ فرديًا odd parity، وإذا كان عددها زوجيًا، فلا يضبط بِتّ التكافؤ؛ أما التكافؤ الزوجي Even parity، فهو عكس ذلك، فإذا كان عدد الواحدات زوجي، فسيُضبط بِتّ التكافؤ على الرقم 1، وبهذه الطريقة سينتج عن تغيّر بِتّ واحد خطأ تكافؤ يمكن اكتشافه. الحواسيب ذات أنظمة 16 و 32 و 64 بت لا تتسع جميع الأعداد في بايت أو مجموعة محددة من البايتات، فبفرض أن كان رصيدك المصرفي كبيرًا مثلًا فهو يحتاج إلى مجال أوسع مما يمكن أن يتسع في بايت واحد لتمثيله، وتتألف المعماريات الحديثة في الحواسيب حاليًا من أنظمة 32 بت على الأقل، وهذا يعني أنها تعمل مع 4 بايتات في وقت واحد عند المعالجة والقراءة أو الكتابة على الذاكرة، ونشير آنذاك إلى كل 4 بايتات بالكلمة word، وهذا مشابه للغة حيث تكوِّن الأحرف -أو البتات- الكلمات في جملة ما، والفارق في الحاسوب عن اللغة أنه تكون كل الكلمات بالحجم نفسه، وهو حجم المتغير من نوع int في اللغة C الذي يساوي 32 بِتّ، أما معماريات 64 بت الحديثة، يضاعف حجم عمل المعالج إلى 8 بايت بدلًا من 4 في معماريات 32 بت. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن كيلوبايت وميغابايت وغيغابايت تتعامل الحواسيب مع عدد كبير من البايتات وهذا ما يجعلها شديدة القوة، وبالتالي نحتاج إلى وسيلة للتحدث عن أعداد ضخمة من البايتات، والوسيلة البديهية لذلك هي استخدام بادئات نظام الوحدات الدولي International System of Units -أو SI اختصارًا- كما هو متّبع في معظم المجالات العلمية الأخرى، إذ يشير الكيلو مثلًا إلى 103 أو 1000 وحدة، بحيث يكون الكيلوغرام الواحد هو 1000 غرام. يُعَدّ 1000 عددًا تقريبيًا round جيدًا في الأساس العشري، لكنه يمثَّل في النظام الثنائي بـ 1111101000 وهو ليس عددًا تقريبيًا، لكن 1024 أو 210 هو عدد تقريبي والذي يمثَّل في النظام الثنائي بـ 10000000000، وهو قريب جدًا من الكيلو في النظام العشري، أي العدد 1000 قريب من العدد 1024، وبالتالي أصبح 1024 بايت بطبيعة الحال يُعرَف بالكيلوبايت؛ أما الوحدة التالية في نظام الوحدات الدولي، فهي ميغا mega المقابلة لقيمة 106، كما تستمر البادئات بالازدياد بمقدار 103 المقابلة للتجميع المعتاد المكون من ثلاثة أرقام عند كتابة أعداد كبيرة، كما يصادف مجددًا أن تكون 220 قريبةً من تحديد نظام الواحدات الدولي للميغا في النظام العشري، أي 1048576 بدلًا من 1000000، فعند زيادة واحدات النظام الثنائي بالقوى من مضاعفات 10 تبقى قريبةً وظيفيًا من قيمة النظام العشري في نظام الواحدات الدولي، مع أنه يحيد قليلًا كل عامل متزايد عن دلالة أساس نظام الواحدات الدولي، وبالتالي فإنّ وحدات النظام العشري في نظام الواحدات الدولي قريبة بما يكفي على قيم النظام الثنائي، وقد شاع استخدامها لتلك القيم. الاسم معامل النظام الثنائي بايت معامل النظام العشري القريب بايت في النظام العشري 1 كيلوبايت 210 1024 103 1000 1 ميغابايت 220 1.048.576 106 1.000.000 1 غيغابايت 230 1.073.741.824 109 1.000.000.000 1 تيرابايت 240 1.099.511.627.776 1012 1.000.000.000.000 1 بيتابايت 250 1.125.899.906.842.624 1015 1.000.000.000.000.000 1 إكسابايت 260 1.152.921.504.606.846.976 1018 1.000.000.000.000.000.000 قد يفيدك ترسيخ معامِلات النظام الثنائي في ذاكرتك كثيرًا في الربط السريع للعلاقة بين عدد البِتّات والأحجام التي يفهمها الإنسان، إذ يمكننا بسرعة مثلًا حساب إمكانية حاسوب بنظام 32 بِتّ أن يعالج ما يصل إلى 4 غيغابايت من الذاكرة من خلال ملاحظة إعادة التركيب (4) 22 + 230، وبالمثل يمكن أن تعالِج قيمة 64 بِتّ ما يصل إلى 16 إكسابايت، أي 260 + 24، كما يمكنك حساب ضخامة هذا العدد، ولتأخذ فكرةً عن مدى ضخامته، فيمكنك حساب المدة التي ستستغرقها في العد إلى 264 إذا عددت رقمًا واحدًا كل ثانية. كيلوبت وميغابت وغيغابت سيشار إلى السعات غالبًا بالبِتّات بدلًا من البايتات إلى جانب الارتباك الذي يحدث نتيجة العبء المفرط لتحويل واحدات نظام الواحدات الدولي SI بين النظامَين الثنائي والعشري، ويحدث هذا عمومًا عند التحدث في مجال الشبكات أو أجهزة التخزين، فربما لاحظت أنّ اتصال ADSL لديك يشار إليه بقيمة مثل 1500 كيلوبِت في الثانية، إن العملية الحسابية بسيطة، إذ نضرب بالعدد 1000 للكيلو ثم نقسِّم على 8 لنحوِّله إلى بايت ثم نقسِّمه على العدد 1024 لنحوله إلى كيلوبايت، وبالتالي تكون 1500 كيلوبِت في ثانية = 183 كيلوبايت في الثانية. أقرَّت هيئة نظام الواحدات الدولي هذه الاستخدامات المزدوجة وحددت بادئات فريدةً للاستخدام الثنائي، إذ تقابل 1024 بايت بموجب المعيار كيبي بايت kibibyte، وهو اختصار للكيلوبايت الثنائي kilo binary byte وتُختصر بـ KiB؛ أما البادئات الأخرى، فلها بادئة مماثلة مثل ميبي بايتس MiB، ويمنع العرف المتَّبع إلى حد كبير استخدام هذه المصطلحات، لكنك قد تراها في بعض المؤلَّفات. التحويل يُعّدّ استخدام الحاسوب الطريقة الأسهل للتحويل بين الأنظمة، فبعد كل شيء هذا ما يبرع فيه. ومع ذلك، فمن المفيد معرفة كيفية إجراء التحويلات يدويًا. تُعَدّ القسمة المتكررة الطريقة الأسهل للتحويل بين الأنظمة، بحيث نقسِّم ناتج القسمة بصورة متكررة على الأساس إلى أن يصبح ناتج القسمة صفرًا مع تدوين الباقي في كل خطوة، ثم ندوِّن الباقي بالعكس، أي نبدأ من الأسفل ونلحق العدد بالجهة اليمين في كل مرة، وسنذكر مثالًا للتوضيح، كما سيكون الأساس 2 نظرًا لأننا نحوِّل إلى النظام الثنائي. عملية القسمة النتيجة الباقي اتجاه قراءة الباقي 2 ÷ 20310 101 1 2 ÷ 10110 50 1 ↑ 2 ÷ 5010 25 0 ↑ 2 ÷ 2510 12 1 ↑ 2 ÷ 1210 6 0 ↑ 2 ÷ 610 3 0 ↑ 2 ÷ 310 1 1 ↑ 2 ÷ 110 0 1 ↑ ابدأ بقراءة الباقي من الأسفل وأضف كل عدد منه إلى اليمين لتحصل على النتيجة 11001011، وقد وجدنا فعلًا أنّ هذه القيمة في النظام الثنائي هي 203 في النظام العشري. العمليات البوليانية Boolean Operations اكتشف جورج بول عالم الرياضيات مجالًا كاملًا في الرياضيات يسمى جبر بُول Boolean Algebra، وعلى الرغم من أنّ اكتشافاته كانت في منتصف القرن التاسع عشر، إلا أنها أصبحت لاحقًا أساسيات علوم الحاسوب، ويُعَدّ جبر بول هو موضوع واسع النطاق، لذا سنتناول في هذا الكتاب بعض مبادئه الأساسية فقط حتى تستطيع بدء رحلة التعلم. تأخذ العمليات البوليانية ببساطة دخلًا معينًا وتنتج خرجًا معينًا حسب قاعدة معينة، وأبسط عملية بوليانية مثلًا هي not، وهي تعكس قيمة معامِل operand الدخل؛ أما المعامِلات الأخرى، فتأخذ عادةً دخلين وتنتج خرجًا واحدًا. يسهل تذكر العمليات البوليانية الأساسية المستخدَمة في علوم الحاسوب وقد أدرجناها في هذا الفصل، ومثلناها بجداول الحقيقة truth tables التي تبيِّن بمظهر بسيط جميع المدخلات والمخرجات المحتمَلة، ويقابل مصطلح حقيقي true القيمة 1 في النظام الثنائي. معامل Not تمثَّل عادةً بالرمز !، وهي تعكس قيمة الدخل فتحول 0 إلى 1 و 1 إلى 0. الدخل الخرج 1 0 0 1 معامل And تذكَّر العبارة التالية: "تكون النتيجة حقيقيةً إذا كان الدخل الأول حقيقيًا و الدخل الثاني حقيقيًا" لكي يسهل عليك تذكُّر آلية عمل معامل and. الدخل الأول الدخل الثاني الخرج 0 0 0 1 0 0 0 1 0 1 1 1 معامل Or تذكَّر العبارة التالية: "تكون النتيجة حقيقيةً إذا كان الدخل الأول حقيقيًا أو الدخل الثاني حقيقيًا" لكي يسهل عليك تذكُّر آلية عمل معامل or . الدخل الأول الدخل الثاني الخرج 0 0 0 1 0 1 0 1 1 1 1 1 معامل أو الحصرية Exclusive Or تختصَر عبارة معامل أو الحصرية Exclusive Or بـ xor وهي حالة خاصة من معامِل or، بحيث يكون الخرج حقيقيًا عندما يكون أحد المدخَلين فقط حقيقيًا، وستدهشك الحيل المميزة التي يستطيع هذا المعامِل تنفيذها، لكنها ليست مستخدَمةً كثيرًا في النواة. الدخل الأول الدخل الثاني الخرج 0 0 0 1 0 1 0 1 1 1 1 0 استخدام العمليات البوليانية في الحواسيب قد يصعب عليك تصديق أنّ أساس كل ما ينفِّذه حاسوبك هو تلك المعامِلات التي تحدثنا عنها، فالجامع النصفي half adder مثلًا هو أحد أنواع الدارات التي تتكون من العمليات البوليانية التي تجمع البِتّات، وقد سُمّي الجامع النصفي لأنه لا يعالج البتات الفائضة، وستبدأ في بناء كيان يجمع أعداد ثنائية طويلة من خلال وضع أكثر من جامع نصفي معًا، ثم أضف إليه بعض الذواكر الخارجية وستكون قد بنيت حاسوبًا. تنفَّذ العمليات البوليانية من الناحية الإلكترونية في بوابات gates مصنوعة من الترانزستورات transistors، لذا لا بد أنك سمعت عن عدد الترانزستورات transistor counts وقانون مور وغيرها، وكلما زاد عدد الترانزستورات زاد عدد البوابات وزاد عدد الأشياء التي يمكنك جمعها، كما ستحتاج لبناء الحاسوب الحديث إلى عدد هائل من البوابات وعدد هائل من الترانزستورات، إذ تحتوي بعض معالِجات إيتانيوم Itanium الحديثة على حوالي 460 مليون ترانزستور. العمل بالنظام الثنائي في اللغة C توجد واجهة مباشرة لجميع المعامِلات التي ذكرناها في اللغة C، ويشرح الجدول التالي هذه المعامِلات: المعامل اصطلاحه في اللغة C not ! and & or \ xor ^ نطبّق هذه المعامِلات على المتغيرات لتعديل البِتّات ضمن المتغير، ولكن يجب علينا أولًا أن نتناول شرحًا للترميز الست العشري قبل أن نستعرض أمثلةً عن ذلك. طور أعمالك مع حلول الذكاء الاصطناعي المبتكرة اسبق منافسيك نحو المستقبل وحقق أهدافك بالاستعانة بقوة الذكاء الاصطناعي اطلب خدمات الذكاء الاصطناعي الآن النظام الست عشري Hexadecimal يشير النظام الست عشري إلى نظام أساسه العدد 16، والسبب الوحيد لاستخدامنا هذا النظام في علوم الحاسوب هو أنه يسهِّل على الإنسان التفكير في الأرقام الثنائية، إذ يسهِّل عدم تعامل الحواسيب إلا مع النظامَين الثنائي والست عشري على الإنسان محاولته التعامل مع الحاسوب. لكن لماذا اختير الأساس 16؟ إن الخيار الطبيعي هو الأساس 10 لأننا معتادون على التفكير في الأساس 10 حسب نظامنا العددي اليومي، لكن الأساس 10 لا يتوافق كثيرًا مع النظام الثنائي؛ إذ نحتاج إلى أربع بتات لتمثيل 10 عناصر مختلفة في النظام الثنائي، لكن تلك الأربع بتات توفر لنا ست عشرة توليفة محتمَلة، لذا نحن أمام احتمالين؛ إما أن نختار الطريقة شديدة التعقيد المتمثلة في محاولة التحويل بين النظام العشري والثنائي، أو أن نختار الطريقة السهلة وننشئ نظامًا عدديًا أساسه العدد 16 وهو النظام الست عشري. يستخدِم النظام الست عشري الأعداد القياسية في النظام العشري مع إضافة الأحرف A B C D E F التي تشير إلى الأعداد 10 11 12 13 14 15، مع الانتباه إلى بدء العدّ من الصفر، فمتى ما رأيت عددًا مسبوقًا بـ 0x، فاعلم أنه يدل على عدد ست عشري، وكما ذكرنا أنه سنحتاج إلى أربع بتات بالضبط لتمثيل 16 نمط مختلف في النظام الثنائي، لذا يمثِّل كل عدد ست عشري أربع بتات بالضبط، ويجب أن تعدّه تمرينًا لتتعلم الجدول التالي عن ظهر قلب. النظام الست عشري النظام الثنائي النظام العشري 0 0000 0 1 0001 1 2 0010 2 3 0011 3 4 0100 4 5 0101 5 6 0110 6 7 0111 7 8 1000 8 9 1001 9 A 1010 10 B 1011 11 C 1100 12 D 1101 13 E 1110 14 F 1111 15 بالطبع لا يوجد سبب للتوقف عن متابعة النمط (مثل تحديد G للقيمة 16)، ولكن القيم الستة عشرة هي موازنة ممتازة بين تقلبات الذاكرة البشرية وعدد البتات التي يستخدمها الحاسوب، كما ستجد أيضًا الأساس 8 مستخدَمًا أحيانًا في سماحيات الملفات في أنظمة يونكس مثلًا، ونمثِّل ببساطة أعدادًا أكبر من البتات بأعداد أكثر، إذ يمكن مثلًا تمثيل متغير يتألف من ستة عشر بت بالقيمة 0xAB12، وما عليك سوى تحويل كل رقم على حدى وفقًا للجدول السابق ثم جمع القيم معًا لتجد مقابلها في النظام الثنائي، أي لتكون القيمة المقابلة للقيمة 0xAB12 هي العدد الذي يتألف من 16 بت في النظام الثنائي 1010101100010010، كما نستطيع التحويل من النظام الثنائي إلى النظام الست عشري بعكس تلك العملية، كما نستطيع الاستعانة بنهج القسمة المتكررة ذاته لتغيير أساس أي عدد، فلإيجاد قيمة العدد 203 بالنظام الست عشري مثلًا: عملية القسمة النتيجة الباقي اتجاه قراءة الباقي 16 ÷ 20310 12 11 (0xB) 16 ÷ 1210 0 12 (0xC) ↑ لذا تكون قيمة 203 في النظام الست عشري هي 0xCB الاستخدام العملي للأنظمة العددية سنطلع فيما يلي على الاستخدام العملي للأنظمة العددية وما النتائج العملية التي ممكن أن نحصل عليها. استخدام النظام الثنائي في الشيفرات البرمجية تُعَدّ برمجة حاسوب بلغات عالية المستوى high level دون معرفة أيّ شيء عنه هو أمر عملي بحت على الرغم من أنّ النظام الثنائي هو اللغة الأساسية لكل حاسوب، وعلى أية حال نهتم ببعض مبادئ النظام الثنائي الأساسية والمستخدَمة بصورة متكررة بالنسبة شيفرة البرمجية منخفضة المستوى low level code التي سنتناولها. التقنع والرايات سنشرح مفهوم عمليتي التقنع والرايات وكيفية تطبيقهما عمليًا على الأنظمة العددية. التقنع Masking من المهم غالبًا جعل البنى والمتغيرات تحجز مساحةً بأكثر طريقة فعالة ممكنة في الشيفرة البرمجية منخفضة المستوى، وقد يتضمن هذا في بعض الحالات تعبئة packing متغيرين -يكونان مرتبطين ببعضهما عمومًا- بمتغير واحد بطريقة فعالة. تذكَّر أنّ كل بِتّ يمثل حالتين، فإذا علمنا مثلًا أنّ للمتغير 16 حالة محتمَلة فقط، فيمكن تمثيله بـ 4 بِتّات، أي 24 = 16 قيمةً فريدةً، لكن أصغر نوع يمكننا التصريح عنه في اللغة C هو 8 بتات وهو نوع char أي محرف، فإما نهدر أربع بتات، أو نجد طريقةً نستخدِم فيها تلك البتات الفائضة، ويمكننا تحقيق ذلك بسهولة من خلال عملية التقنُّع التي تتبع قواعد العمليات المنطقية لاستخراج القيم وهي موضَّحة في الصورة التالية. نحتفظ بقيمتَين منفصلتين تتألفان من 4 بِتّات داخل محرف واحد يتألف من 8 بِتّات، إذ نُعِدّ البِتّات الأربعة الأولى (الزرقاء) قيمةً واحدةً والبِتَات الأربعة الأخيرة (الحمراء) قيمةً أخرى، وقد ضبطنا القناع على تعيين قيمة البتات الأربعة الأخيرة 1 (0x0F) لاستخراج البِتّات الأربعة السفلية، وبما أنّ المعامِل and المنطقي سيضبط البت إلى 1 فقط إذا كانت قيمة كلا البتّين 1، فستخفي البِتّات التي ضبطنا قيمتها على 0 في القناع وهي البتات التي لا تهمنا بصورة فعالة. (التقنُّع) نقلب القناع للحصول على البِتّات الأربعة الأولى (الزرقاء)، أي نضبط البِتّات الأربعة الأولى على القيمة 1 والبتات الأربعة الأخيرة على القيمة 0، وستلاحظ أنّ نتيجة هذا ستكون 0000 1010 أو 0xA0 في النظام الست عشري، على حين أننا نريد فعلًا أن نعتبر هذه القيمة الفريدة المؤلفة من 4 بتات 1010 أي 0x0A، ولوَضع هذه البتات في الموضع الصحيح نستخدِم المعامِل right shift أربع مرات، والذي سيمنحنا القيمة النهائية 1010 0000. 1 #include <stdio.h> #define LOWER_MASK 0x0F #define UPPER_MASK 0xF0 5 int main(int argc, char* argv[]) { /* قيمتان بحجم 4 بتات مخزنتان في متغير بحجم 8 بتات */ 10 char value = 0xA5; char lower = value & LOWER_MASK; char upper = (value & UPPER_MASK) >> 4; printf("Lower: %x\n", lower); 15 printf("Upper: %x\n", upper); } يتطلب ضبط البِتّات المعامِل or المنطقي، لكن سنستخدم الأصفار 0 بدلًا من استخدام الواحدات 1 على أساس قناع، كما ننصحك برسم مخطط مشابه للصورة السابقة والعمل على ضبط البِتّات بواسطة المعامِل or المنطقي. الرايات flags يتضمن البرنامج غالبًا عددًا كبيرًا من المتغيرات التي توجد فقط بصيغة رايات flags في شروط معينة، فآلة الحالات state machine مثلًا هي خوارزمية تتنقل عبر عدد من الحالات المختلفة، لكنها لا تتواجد إلا في حالة واحدة فقط في المرة الواحدة، ولنقل أنه لديها 8 حالات مختلفة، إذ نستطيع بسهولة التصريح عن 8 متغيرات مختلفة، بحيث يكون هناك متغير واحد لكل حالة، لكن في كثير من الحالات يفضَّل التصريح عن متغير واحد مؤلف من 8 بتات وتعيين راية لكل بِتّ للإشارة إلى حالة معينة. تُعَدّ الرايات حالةً خاصةً من التقنُّع، لكن يمثِّل كل بِتّ حالةً بوليانيةً معينةً، أي تشغيل أو إيقاف، كما يمكن لمتغير مؤلَّف من عدد n من البتات أن يحمل العدد n من الرايات المختلفة، ويُعَدّ نموذج الشيفرة البرمجية التالي هو مثال نموذجي على استخدام الرايات، وستلحظ اختلافات في هذه الشيفرة البرمجية الأساسية في معظم الأحيان. 1 #include <stdio.h> /* * تعريف كافة الرايات الثمانية المحتمَلة لمتغير بحجم 8 بتات 5 * الاسم النظام الست عشري النظام الثنائي */ #define FLAG1 0x01 /* 00000001 */ #define FLAG2 0x02 /* 00000010 */ #define FLAG3 0x04 /* 00000100 */ 10 #define FLAG4 0x08 /* 00001000 */ /* ... وهكذا */ #define FLAG8 0x80 /* 10000000 */ int main(int argc, char *argv[]) 15 { char flags = 0; /* متغير بحجم 8 بتات */ /* ضبط الرايات بمعامل orالمنطقي */ flags = flags | FLAG1; /* ضبط الراية الأولى */ 20 flags = flags | FLAG3; /* ضبط الراية الثالثة /* تحقق من الرايات بالمعامل and المنطقي. إذا كانت الراية مضبوطة بالقيمة 1 * سيرجع المعامل and قيمة 1 * if مما سيحقق الشرط الوارد في */ 25 if (flags & FLAG1) printf("FLAG1 set!\n"); /* سيكون هذا بالطبع غير صحيح */ if (flags & FLAG8) 30 printf("FLAG8 set!\n"); /* تحقق من عدة رايات بواسطة or المنطقي * سيمرر هذا لأن الراية الأولى مضبوطة */ if (flags & (FLAG1|FLAG4)) 35 printf("FLAG1 or FLAG4 set!\n"); return 0; } ترجمة -وبتصرف- للقسم Binary — the basis of computing من الفصل Chapter 2. Binary and Number Representation من كتاب Computer Science from the Bottom Up. اقرأ أيضًا المقال التالي: تمثيل الأنواع والأعداد في الأنظمة الحاسوبية المقال السابق: مفهوم واصفات الملفات File Descriptors وارتباطها بعملية التجريد في أنظمة التشغيل أساسيات نظام العد الثنائي في الشبكات
-
إحدى أولى المفاهيم التي يتعلمها مبرمج أنظمة يونكس هي أنّ عمل كل برنامج يبدأ بثلاث ملفات تكون مفتوحةً مسبقًا: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } الاسم الوصفي الاسم المختصر رقم الملف الشرح مجرى الدخل القياسي stdin 0 الدخل من لوحة المفاتيح مجرى الخرج القياسي stdout 1 الخرج الظاهر على الطرفية مجرى الخطأ القياسي stderr 2 خرج رسائل الخطأ على الطرفية (ملفات يونيكس الافتراضية) يستحضر هذا إلى أذهاننا السؤال عمّا يمثله الملف المفتوح وكيفية فتحه، إذ تسمى القيمة التي يعيدها استدعاء open لفتح الملف اصطلاحًا بواصف الملف file descriptor، وهي أساسًا فهرس لمصفوفة من الملفات المفتوحة المخزَّنة في النواة. (فائدة واصفات الملفات في عملية التجريد) تُعَدّ واصفات الملفات فهرسًا لجدول واصفات الملفات تخزنه النواة، بحيث تنشئ النواة واصف ملف استجابةً لاستدعاء open وتربطه ببعض التجريد لكائن يشبه الملف سواءً كان جهازًا فعليًا أو نظام ملفات أو شيء بعيد عن هذا كل البعد، وبالتالي توجه النواة استدعاءات عمليات القراءة read والكتابة write التي تشير إلى واصف الملف ذاك إلى الموضع الصحيح لتنفذ مهمة مفيدة في النهاية. تعرض الصورة نظرةً عامةً على تجريد العتاد، وباختصار يُعَدّ واصف الملف البوابة إلى تجريدات النواة للعتاد والأجهزة الأساسية. لنبدأ من المستوى الأدنى، إذ يتطلب نظام التشغيل وجود مبرمج ينشئ تعريفًا للجهاز device driver أو برنامج تعريف حتى يتمكن من التواصل مع أحد أجهزة العتاد، ويُكتَب تعريف الجهاز هذا إلى واجهة API التي توفرها النواة بالطريقة نفسها والتي وردت في مثال المقال السابق، إذ سيوفر تعريف الجهاز مجموعة دوال تستدعيها النواة استجابةً للمتطلبات المختلفة، ويمكننا في المثال المبسَّط في الصورة السابقة رؤية أن تعريف الجهاز يوفِّر دالة القراءة read والكتابة write اللتين ستُستدعيان استجابةً للعمليات المماثلة التي تنفذ على واصف الملف، كما يعلم تعريف الجهاز كيف يحوِّل هذه الطلبات العامة إلى طلبات أو أوامر محددة لجهاز محدد. تقدم النواة واجهة-ملف file-interface لتوفير التجريد لمساحة المستخدِم عبر ما يسمى بطبقة الجهاز device layer عمومًا، إذ تمثَّل الأجهزة المادية على المضيف بملف له نظام ملفات خاص مثل dev/، ففي أنظمة يونكس وما يشابهها تحتوي عقد الجهاز device-nodes على ما اصطلح تسميته بالعدد الرئيسي major number والعدد الثانوي minor number، مما يتيح للنواة ربط عقد محددة بما يقابلها ببرنامج التعريف الموفر، كما يمكنك الاطلاع عليها من خلال الأمر ls كما هو موضح في المثال التالي: $ ls -l /dev/null /dev/zero /dev/tty crw-rw-rw- 1 root root 1, 3 Aug 26 13:12 /dev/null crw-rw-rw- 1 root root 5, 0 Sep 2 15:06 /dev/tty crw-rw-rw- 1 root root 1, 5 Aug 26 13:12 /dev/zero ينقلنا هذا إلى واصف الملف، وهو الأداة التي تستخدِمها مساحة المستخدِم للتواصل مع الجهاز الأساسي، وبصورة عامة ما يحدث عند فتح الملف هو أنّ النواة تستخدِم معلومات المسار لربط map واصف الملف بشيء يوفِّر واجهتّي API قراءة وكتابة وغيرهما مناسبة، فعندما تكون عملية فتح الملف open للجهاز مثل /dev/sr0 في مثالنا السابق، فسيوفر العدد الرئيسي والثانوي لعقدة الجهاز المفتوح المعلومات التي تحتاجها النواة للعثور على تعريف الجهاز الصحيح وإتمام عملية الربط mapping، كما ستعلم النواة بعد ذلك كيف توجه الاستدعاءات اللاحقة مثل القراءة read إلى الدوال الأساسية التي يوفرها تعريف الجهاز. يعمل الملف غير المرتبط بجهاز non-device file بآلية مشابهة، على الرغم من وجود طبقات أكثر خلال العملية، فالتجريد هنا هو نقطة الوصل أو الربط mount point، وكما تملك عملية توصيل نظام الملفات file system mounting غايةً مزدوجةً تتمثل في إعداد عملية الربط mapping، بحيث يتعرف نظام الملفات على الجهاز الأساسي الذي يوفِّر التخزين وتعلم النواة أنّ الملفات المفتوحة في نقطة التوصيل تلك يجب أن توجَّه إلى تعريف نظام الملفات، كما تُكتَب أنظمة الملفات على واجهة API محددة لنظام الملفات العام التي توفرها النواة على غرار تعريفات الأجهزة. بالطبع الصورة الكاملة معقدة أكثر في الواقع، إذ تضم عدة طبقات أخرى، فتبذل النواة على سبيل المثال جهدًا كبيرًا لتخزين cache أكبر قدر ممكن من البيانات الواردة من الأقراص في الذاكرة الخالية، ويقدِّم هذا العديد من الميزات التي تحسِّن السرعة، كما تحاول النواة تنظيم الوصول إلى الجهاز بأكثر طريقة فعالة وممكنة مثل محاولة طلب الوصول إلى القرص للتأكد من أن البيانات المخزَّنة فيزيائيًا بالقرب من بعضها ستستعاد معًا حتى لو لم ترد الطلبات بترتيب تسلسلي، بالإضافة إلى انتماء العديد من الأجهزة إلى فئة أعم مثل أجهزة USB أو SCSI التي توفِّر طبقات التجريد الخاصة بها للكتابة عليها، وبالتالي ستمر أنظمة الملفات في هذه الطبقات المتعددة بدلًا من الكتابة مباشرةً على الأجهزة، أي يكون فهم النواة هو فهم كيفية ترابط واجهات API المتعددة تلك وتواجدها مع بعضها. الصدفة Shell تُعَدّ الصدفة بوابة التفاعل مع نظام التشغيل سواءً كانت باش bash أو zsh أو csh أو أيّ نوع من أنواع الأصداف الأخرى العديدة، إذ تشترك جميعها أساسًا في مهمة رئيسية واحدة فقط، وهي أنها تتيح لك تنفيذ البرامج، كما ستبدأ بفهم آلية تنفيذ الصدفة لهذه المهمة فعليًا عندما سنتحدث لاحقًا عن بعض العناصر الداخلية لنظام التشغيل. لكن الأصداف قادرة على تنفيذ مهام أكبر بكثير من مجرد إتاحة تنفيذ برنامج، إذ تتميز بقدرات قوية لإعادة توجيه الملفات، وتتيح لك تنفيذ عدة برامج في الوقت نفسه وكتابة نصوص برمجية تبني برامج متكاملة، وهذا كله يعيدنا إلى مقولة كل شيء هو عبارة عن ملف. إعادة التوجيه Redirection لا نريد في معظم الأحيان أن تشير واصفات الملفات القياسية التي تحدثنا عنها في بداية المقال إلى مواضع محددة افتراضيًا، فقد ترغب مثلًا في تسجيل كامل خرج البرنامج على ملف تحدده على القرص أو في جعله يتلقى أوامره من ملف أعددته مسبقًا، وقد ترغب في تمرير خرج برنامج ليكون دخل برنامج آخر، إذ تيسّر الصدفة ذلك وأكثر بالعمل مع نظام التشغيل. الاسم الأمر الوصف مثال إعادة التوجيه إلى ملف filename < أخذ كامل الخرج الناتج عن Standard Out وتسجيله في الملف filename (استبدل filename باسم الملف). ملاحظة: استخدم << لتُلحق الخرج بنهاية محتوى الملف بدلًا من استبدال محتواه ls > filename القراءة من ملف filename > نسخ كافة البيانات من الملف إلى دخل البرنامج القياسي standard input echo < filename التمرير Pipe program1 | program2 أخذ كامل خرج standard out البرنامج الأول program1 وتمريره إلى دخل standard input البرنامج الثاني program2 ls | more تنفيذ عملية التمرير pipe يُعَدّ تنفيذ الأمر ls | more مثالًا آخرَ على قدرة التجريد، فما يحدث هنا بصورة أساسية هو أنه بدلًا من ربط واصف الملف لمجرى الخرج القياسي بإحدى الأجهزة الأساسية مثل الطرفية لعرض الخرج عليها، يوجَّه الواصف إلى مخزن مؤقت buffer في الذاكرة توفِّره النواة ويطلق عليه عادةً الأنبوب pipe، والمميز هنا هو إمكانية عملية أخرى أن تربط دخلها القياسي standard input بالجانب الآخر من المخزن المؤقت ذاته buffer وتستحوذ على خرج العملية الأخرى بفعالية كما هو موضَّح في الصورة التالية: (الأنبوب) الأنبوب هو مخزن مؤقت في الذاكرة يربط عمليتين معًا، وتشير واصفات الملف إلى كائن الأنبوب الذي يخزن البيانات المرسلة إليه من خلال عملية الكتابة ليصرِّفها من خلال عملية القراءة. تخزِّن النواة عمليات الكتابة في الأنبوب حتى تصرّف عملية قراءة مقابلة من الجانب الآخر للمخزن المؤقت، وهذا مفهوم قوي جدًا وهو أحد الأشكال الأساسية للتواصل بين العمليات inter-process communication -أو IPC اختصارًا- في أنظمة يونكس وما يشابهها، كما لا تقتصر عملية التمرير على نقل البيانات، إذ يمكن أن تؤدي دور قناة إشارات signaling channel، فإذا قرأت إحدى العمليات أنبوبًا فارغًا، فستعطله أو تجمده block افتراضيًا أو تضعه في حالة سبات hibernation إلى حين توفر بعض البيانات، وسنتعمق في هذا أكثر في مقال لاحق من هذه السلسلة، وبالتالي قد تستخدِم عمليتان أنبوبًا للإبلاغ عن اتخاذ إجراء ما عن طريق كتابة بايت واحد من البيانات، فبدلًا من أن تكون البيانات الفعلية مهمةً، فإن مجرد وجود أية بيانات في الأنبوب يمكن أن تشير إلى رسالة، فلنفترض مثلًا أنّ إحدى العمليات تطلب طباعة عملية أخرى لملف وهو أمر سيستغرق بعض الوقت، لذا قد تُعِدّ العمليتان أنبوبًا بينهما بحيث تقرأ العملية التي أرسلت الطلب الأنبوب الفارغ، وبما أنه فارغ، فسيعطّل هذا الاستدعاء وتبطِل العملية، لكن بمجرد الانتهاء من الطباعة، ستكتب العملية الأخرى رسالةً في الأنبوب ويؤدي ذلك إلى إيقاظ العملية التي أرسلت الطلب بصورة فعالة وإرسال إشارة تدل على انتهاء العمل. ينبثق عن السماح للعمليات بتمرير البيانات بين بعضها بهذه الطريقة مصطلح شائع آخر في يونكس للأدوات الصغيرة التي تنفذ أمرًا معينًا، ويضفي تسلسل هذه الأدوات الصغيرة مرونةً لا تستطيع أداة موحَّدة إضفاءها في معظم الأحيان. ترجمة -وبتصرُّف- لقسم من الفصل Chapter 1. General Unix and Advanced C من كتاب Computer Science from the Bottom Up. اقرأ أيضًا المقال التالي: تعرف على نظام العد الثنائي Binary أساس الحوسبة المقال السابق: مفهوم التجريد abstraction في أنظمة التشغيل وأهميته للمبرمجين التجريد (Abstraction) والواجهات (Interfaces) والسمات (Traits) في PHP النسخة العربية الكاملة لكتاب: أنظمة التشغيل للمبرمجين
-
مفهوم الملف هو تجريد abstraction مناسب إما كحوض للبيانات أو مصدر لها، وبالتالي هو تجريد ممتاز لجميع الأجهزة التي قد يوصلها المرء بالحاسوب. هذا الإدراك هو سر القوة العظيمة لنظام التشغيل يونيكس ويتجلى في مجمَل تصميم كامل المنصة. ويُعَدّ توفير تجريد الأجهزة هذا للمبرمج من الأدوار الرئيسية لنظام التشغيل. كل شيء عبارة عن ملف تُعَدّ مقولة كل شيء عبارة عن ملف مبدأً يُستمَد غالبًا من أنظمة يونكس Unix وما يشابهها مثل لينكس linux وبي إس دي BSD. لنتخيل ملفًا في إطار مألوف مثل معالج النصوص، إذ تكون العمليتان الأساسيتان اللتان نستطيع تنفيذهما على ملف في معالج النصوص التخيلي هذا كما يلي: قراءته، أي قراءة معالج النصوص البيانات الحالية المحفوظة. الكتابة ضمنه، أي كتابة المستخدِم بيانات جديدةً. لنستعرض بعض الطرفيات الشائعة الموصولة بالحاسوب، وما هو ارتباطها بالعمليات الأساسية على الملفات: الشاشة. لوحة المفاتيح. الطابعة. القرص المدمَج CD-ROM. تشبه كل من الشاشة والطابعة ملفًا للكتابة فقط، إذ تُعرَض المعلومات نقاطًا على الشاشة أو خطوطًا على الصفحة بدلًا من تخزينه على هيئة بِتّات على القرص؛ أما لوحة المفاتيح، فتُعَدّ مثل ملف للقراءة فقط، إذ ترد البيانات من ضغطات المستخدِم على المفاتيح، وكذلك الأمر بالنسبة للقرص المضغوط CD-ROM مثلًا، لكن تخزَّن البيانات مباشرةً على القرص بدلًا من أن يدخلها المستخدِم عشوائيًا. وبالتالي فإن مفهوم الملف هو تجريد abstraction مناسب إما لحوض البيانات أو مصدرها، لذا فهو تجريد ممتاز لجميع الأجهزة التي قد يوصلها المرء بالحاسوب، ويُعَدّ هذا الإدراك هو سر القوة العظيمة لنظام التشغيل يونيكس ويتجلى في مجمَل تصميم كامل المنصة، كما يُعَدّ توفير تجريد الأجهزة هذا للمبرمج من الأدوار الرئيسية لنظام التشغيل. ربما لا نبالغ عندما نقول أنّ التجريد هو المفهوم الأساسي الذي يدعم جميع أشكال الحوسبة الحديثة، إذ لا يمكن لشخص واحد فهم كل الأمور من تصميم واجهة مستخدِم حديثةً إلى العمليات الداخلية لوحدة المعالجة المركزية CPU الحديثة، ناهيك عن بنائها بكاملها بأنفسهم؛ أما بالنسبة للمبرمجين، فالتجريد هو اللغة المشتركة التي تتيح لنا التعاون والابتكار. يمنحنا تعلّم التنقل بين التجريدات رؤيةً أعمق لطريقة استخدام التجريدات بأفضل الأساليب وأكثرها ابتكارًا، وسندرس في هذه السلسلة التجريدات في الطبقات الدنيا وبين التطبيقات ونظام التشغيل وبين نظام التشغيل والعتاد الصلب، كما توجد العديد من الطبقات الأعلى منها وكل منها تستحق التفرُّد بسلسلة خاصة بها، ونأمل منك اكتساب بعض الرؤى عن التجريدات التي يقدِّمها نظام التشغيل الحديث مع دراسة كل مقال من مقالات هذه السلسلة. (صورة توضح مفهوم التجريد) تطبيق التجريد يُطبَّق التجريد عمومًا بما يسمى واجهة برمجة التطبيق API، ويُعَدّ API مصطلحًا مبهمًا نوعًا ما، إذ يشير إلى أمور مختلفة حسب سياقات الأعمال البرمجية المتنوعة،يصمم المبرمج في الأساس مجموعة دوال functions، ويُوثِّق واجهتها ووظيفتها حسب مبدأ أن التنفيذ الفعلي الذي يزوده بواجهة API يكون مخفيًا. تقدِّم العديد من تطبيقات الويب على سبيل المثال واجهة API يمكن الوصول إليها عن طريق بروتوكول HTTP، ويطلق الوصول إلى البيانات بهذه الطريقة عدة سلاسل معقدة من استدعاءات الإجراءات البعيدة remote procedure calls واستعلامات قاعدة البيانات database queries وعمليات نقل البيانات data transfers، وتكون جميعها غير مرئية بالنسبة للمستخدِم النهائي الذي يتلقى البيانات المقتضبة ببساطة. سيألف الذين هم على دراية باللغات البرمجية كائنية التوجه object-oriented مثل جافا Java أو بايثون Python أو ++C مفهوم التجريد في الأصناف classes، إذ تزِّود التوابع methods الصنف بالواجهة لكنها تجرِّد التنفيذ. تطبيق التجريد بلغة البرمجة C تُعَدّ مؤشرات الدالة function pointers منهجيةً شائعةً تُستخدَم في نواة نظام تشغيل لينكس وغيرها من الشيفرات البرمجية الأساسية المكتوبة بلغة C والتي لا يكون مفهوم كائنية التوجه مدمجًا فيها، كما يُعَدّ فهم هذا المصطلح أمرًا رئيسيًا لقراءة معظم الشيفرات البرمجية الأساسية المكتوبة بلغة C، إذ يمكّنك فهم طريقة قراءة التجريدات الموجودة ضمن الشيفرة البرمجية من تكوين فكرة عن تصاميم واجهات API الداخلية. #include <stdio.h> /* الواجهة البرمجية التي سننفذها */ struct greet_api { int (*say_hello)(char *name); int (*say_goodbye)(void); }; /* تطبيق دالة hello */ int say_hello_fn(char *name) { printf("Hello %s\n", name); return 0; } /* تطبيق دالة goodbye */ int say_goodbye_fn(void) { printf("Goodbye\n"); return 0; } /* بنية لتنفيذ الواجهة البرمجية*/ struct greet_api greet_api = { .say_hello = say_hello_fn, .say_goodbye = say_goodbye_fn }; /* لا تحتاج الدالة main() معرفة أيّ شيء عن آلية عمل * say_hello/goodbye، فهي لا تعلم إلا أنها تعمل*/ int main(int argc, char *argv[]) { greet_api.say_hello(argv[1]); greet_api.say_goodbye(); printf("%p, %p, %p\n", greet_api.say_hello, say_hello_fn, &say_hello_fn); exit(0); } تُعَدّ هذه الشيفرة البرمجية بأنها أبسط نموذج عن البنى التي يتكرر استخدامها في جميع أجزاء نواة لينكس والبرامج الأخرى المبنية على اللغة C، ولنلقِ نظرةً على بعض العناصر المحددة. نبدأ بالبنية التي تحدِّد الواجهة البرمجية struct greet_api، فالدوال التي أحيطت أسمائها بأقواس مع محدد المؤشر pointer marker تصف مؤشر الدالة، إذ يصف مؤشر الدالة النموذج الأولي للدالة التي يجب أن يشير إليها، كما سيؤدي توجيهه إلى دالة دون إضافة النوع المُعاد return type الصحيح أو المعاملات الصحيحة على الأقل إلى توليد تحذير من المصرِّف، وإذا تركته في الشيفرة البرمجية، فيحتمل أن يؤدي إلى تنفيذ عملية خاطئة أو أعطال، لذلك إذ ستجد غالبًا أنّ أسماء المعامِلات parameters قد حُذفت ولم يُحدَّد إلا نوع المعامِل، ويتيح هذا للمنفذ تحديد أسماء المعامِلات لتجنب ورود تحذيرات من المصرِّف. سنتناول الآن تنفيذ الواجهة البرمجية، إذ ستجد عادةً في الدوال الأعقد مصطلحًا يدل على أنّ دوال تنفيذ الواجهة البرمجية هي عبارة عن غلاف حول الدوال الأخرى التي تكون عادةً مسبوقةً بشرطة سفلية أو اثنتين، إذ ستستدعي الدالة ()say_hello_fn دالةً أخرى ()say_hello_function_ على سبيل المثال، ولهذه عدة استخدامات، إذ نستخدمها عمومًا لنحظى بأجزاء أبسط وأصغر من الواجهة API -في تنظيم الوسائط arguments أو التحقق منها مثلًا- منفصلةً عن عملية التنفيذ الأعقد، ويسهّل هذا غالبًا المسار إلى تحقيق تغييرات ملموسة في العمليات الداخلية مع ضمان بقاء الواجهة ثابتة، إلا أنّ عملية التنفيذ هنا بسيطة جدًا ولا تحتاج حتى إلى دوال داعمة خاصة بها، كما يختلف مدلول بادئات الدالة التي تكون شرطة سفلية واحدة _ أو مزدوجة __ أو حتى ثلاثية ___ باختلاف المشاريع، لكنها عمومًا تُعَدّ تحذيرًا مرئيًا بأنه لا يُفترَض استدعاء الدالة مباشرةً من خارج الواجهة. ملاحظة: قد يُشار إلى دالة الشرطة السفلية المزدوجة __foo في المحادثات بالتابع السحري dunder foo وتكون فو foo مثل س أو ص في الجبر. نملأ مؤشرات الدالة في المرحلة ما قبل الأخيرة في struct greet_api greet_api، إذ يُعَدّ اسم الدالة مؤشرًا، لذا لا حاجة لأخذ عنوان الدالة مثل say_hello_fn&، وأخيرًا يمكننا استدعاء دوال واجهة API ضمن بنية main. ستلاحظ هذا المصطلح باستمرار عند تصفحك الشيفرة المصدرية source code،ـ ويمكن أن نوضح ذلك في هذا المثال البسيط الذي اجتزأناه من الملف include/linux/virtio.h في الشيفرة المصدرية لنواة نظام لينكس: /** * virtio_driver - operations for a virtio I/O driver * @driver: underlying device driver (populate name and owner). * @id_table: the ids serviced by this driver. * @feature_table: an array of feature numbers supported by this driver. * @feature_table_size: number of entries in the feature table array. * @probe: the function to call when a device is found. Returns 0 or -errno. * @remove: the function to call when a device is removed. * @config_changed: optional function to call when the device configuration * changes; may be called in interrupt context. */ struct virtio_driver { struct device_driver driver; const struct virtio_device_id *id_table; const unsigned int *feature_table; unsigned int feature_table_size; int (*probe)(struct virtio_device *dev); void (*scan)(struct virtio_device *dev); void (*remove)(struct virtio_device *dev); void (*config_changed)(struct virtio_device *dev); #ifdef CONFIG_PM int (*freeze)(struct virtio_device *dev); int (*restore)(struct virtio_device *dev); #endif }; كل المطلوب هو أن نفهم فهمًا سطحيًا أنّ هذه البنية هي وصف لجهاز الإدخال والإخراج I/O الافتراضي، ونلاحظ أن المتوقَّع من مستخدِم واجهة API هذه -أي كاتب تعريف الجهاز device driver- هو تقديم عدد من الدوال التي ستُستدعَى في شروط مختلفة أثناء تشغيل النظام، أي عند تقصّي عتاد جديد hardware أو عند إزالة عتاد ما، …إلخ على سبيل المثال، كما يحتوي على مجموعة بيانات، وهي البُنى التي يجب تعبئتها بالبيانات المرتبطة بها، كما يُعَدّ البدء بعناصر توصيف مثل هذه أسهل طريقة لبدء فهم الطبقات المختلفة لشيفرة النواة البرمجية. المكتبات تؤدي المكتبات دورَين يوضحان التجريد، هما: تتيح للمبرمجين إعادة استخدام الشيفرة البرمجية المتاح الوصول إليها عمومًا. تؤدي دور الصندوق الأسود في تنفيذ الخصائص الوظيفية عن المبرمج. تختص المكتبة التي تنفذ الوصول إلى البيانات غير المعالَجة في الملفات على سبيل المثال بلاحقة JPEG بميزة تتيح للعديد من البرامج التي ترغب في الوصول إلى ملفات الصور استخدام المكتبة نفسها، كما لا يضطر المبرمجون الذين يبرمجون هذه البرامج إلى الانشغال بالتفاصيل الدقيقة لصيغة الملف JPEG، وإنما يركزون جهودهم على دور الصورة أو موضعها في البرنامج. يشار إلى المكتبة القياسية في منصة يونكس باسم libc عمومًا، ومهمتها توفير الواجهة الأساسية للنظام، والاستدعاءات الأساسية مثل ()read و ()write و ()printf، كما توصَف واجهة API هذه بمجملها بتوصيف يسمى بوزيكس POSIX، وهي متاحة مجانًا على الإنترنت وتصف العديد من الاستدعاءات التي تؤلف واجهة API القياسية في نظام يونكس. تتبع معظم منصات يونكس عمومًا معايير بوزيكس، مع وجود بعض الفروقات الطفيفة التي تكون مهمةً أحيانًا (وهذا ما يفسر تعقيد أنظمة بناء غنو Gnu autotools المختلفة، التي تحاول دومًا إخفاء هذه الفروقات عنك). يحتوي نظام لينوكس على العديد من الواجهات التي لا تتبع معايير بوزيكس، لذا فإن بناء تطبيقات تستخدم هذه الواجهات دون غيرها لن يجعل تطبيقك محمولًا portable بما يكفي. تُعّدّ المكتبات تجريدًا أساسيًا يضم الكثير من التفاصيل، وسنتناول في فصول لاحقة آلية عمل المكتبات بالتفصيل. ترجمة -وبتصرّف- للقسم Everything is a file! والقسم Implementing abstraction من الفصل Chapter 1. General Unix and Advanced C من كتاب Computer Science from the Bottom Up. اقرأ أيضًا المقال التالي: مفهوم واصفات الملفات File Descriptors وارتباطها بعملية التجريد في أنظمة التشغيل التجريد (Abstraction) والواجهات (Interfaces) والسمات (Traits) في PHP نمط التصميم معمل التجريد Abstract Factory النسخة العربية الكاملة لكتاب: أنظمة التشغيل للمبرمجين
-
يدير فريق مطوِّري البرامج مفتوحة المصدر والمشرفون عليها مشاريعهم عادةً من خلال نظام غيت، وهو نظام إدارة الإصدارات الموزعة التي تدعم المشاركة. يقدم لك هذا الدليل المُعَدّ على نمط الورقة المرجعية cheat sheet مرجعًا سريعًا للأوامر التي تفيدك في العمل والمشاركة في مستودع غيت. ولتثبيت نظام غيت وإعداده اِقرأ المقالة "كيف تساهم في المشاريع مفتوحة المصدر: ابدأ بتعلم نظام غيت Git". إليك بعض الملاحظات قبل البدء بهذا الدليل: أُعِدّ هذا الدليل على نمط الورقة المرجعية وأُضيفت إليه مقتطفاتٌ مستقلة من موجّه الأوامر. انتقل إلى أي قسم ذي صلة بالمهمة التي تحاول تنفيذها. عندما ترى نصًا مظللًا ضمن الأوامر في هذا الدليل، تذكر أن تستبدل هذا النص بنصٍ يشير إلى الإيداعات commits والملفات الموجودة في مستودعك. الإعداد والتهيئة تحقَّق من إصدار نظام غيت لديك بالاستعانة بالأمر التالي، والذي سيؤكد أيضًا أن النظام مثبَّتٌ على جهازك: $ git --version يتيح لك غيت ضبط بعض الإعدادات، التي تُطبَّق على جميع المستودعات الموجودة على جهازك المحلي. على سبيل المثال، اِضبط اسم مستخدمٍ سيستخدمه غيت ليوثِّق به أية تعديلات تجريها على مستودع محلي: $ git config --global user.name "firstname lastname" اضبط عنوان البريد الإلكتروني ليُربَط مع كل علامة سجل محفوظة history marker على النحو التالي: $ git config --global user.email "valid-email" اضبط محرر النصوص الذي تفضله أيضًا: $ git config --global core.editor "nano" يمكنك تهيئة دليل العمل working directory الحالي على أنه مستودع غيت باستخدام الأمر init على النحو التالي: $ git init لنسخ مستودع غيت مُستضاف عن بُعد، ستستخدم الأمر git clone مع عنوان url للمستودع أو موقع الخادم (في حالة إضافة موقع الخادم، ستستخدم الأمر ssh): $ git clone https://www.github.com/username/repo-name اِعرض المستودع البعيد لدليل غيت الحالي لديك: $ git remote للحصول على خرج مطوَّل verbose، استخدم الراية v- على النحو التالي: $ git remote -v أضِف فرع غيت الأولي primary، ,الذي قد يكون عنوان url، أو مُستضافًا على خادم (في هذه الحالة اتصل بالخادم باستخدام الأمر ssh): $ git remote add upstream https://www.github.com/username/repo-name التحضير للإدراج عندما تعدل ملفًا وتضع علامةً عليه للانتقال إلى الإيداع التالي، فإنه يُعد ملفًا مُدرجًا staged. يمكن التحقق من حالة مستودع غيت لديك، بحيث يتضمن الملفات المضافة المُدرجة وغير المُدرجة على النحو التالي: $ git status استخدم الأمر add لإدراج الملفات المُعدَّلة، إذ يمكنك تنفيذه عدّة مرات قبل ملف الإيداع؛ وإذا أجريت تعديلات لاحقة تريد إدراجها في الإيداع التالي، عليك تنفيذ الأمر add مجددًا. كما يمكنك تحديد ملفٍ معين في الأمر add على النحو التالي: $ git add my_script.py ويمكنك باستخدام النقطة . إضافة جميع الملفات الموجودة في الدليل الحالي، وهذا يشمل الملفات التي تبدأ بالنقطة .: $ git add . إذا أردت إضافة جميع الملفات الموجودة في الدليل الحالي إضافةً إلى الملفات الموجودة في الدلائل الفرعية، فيمكنك استخدام الراية all- أو A-: $ git add -A يمكنك إزالة ملف من مرحلة الإدراج مع الاحتفاظ بالتعديلات ضمن دليل العمل الخاص بك باستخدام الأمر reset: $ git reset my_script.py الإيداع بمجرد انتهائك من إدراج التحديثات التي أجريتها، فأنت جاهزٌ لإضافة إيداع، والذي سيسجِّل التعديلات التي أجريتها على المستودع. لإيداع ملفاتٍ مُدرجة، نفِّذ الأمر commit وأضف رسالة إيداعٍ ذات مغزًى حتى تتمكن من متابع الإيداعات: $ git commit -m "Commit message" يمكنك اختصار جميع الملفات التي تتابعها من خلال إضافة إيداعٍ لها في خطوةٍ واحدة: $ git commit -am "Commit message" يمكنك تعديل رسالة الإيداع بإضافة الراية amend--: $ git commit --amend -m "New commit message" الفروع الفرع في غيت هو مؤشرٌ متنقلٌ لأحد الإيداعات في المستودع، ويتيح لك عزل العمل وإدارة تطوير الخصائص وعمليات الدمج. إذا أردت معرفة المزيد عن الفروع اقرأ توثيق غيت. اعرض جميع الفروع الحالية بتنفيذ الأمر branch، إذ ستظهر علامة النجمة (*) بجوار فرعك النشط حاليًا: $ git branch أنشئ فرعًا جديدًا. ستبقى في فرعك النشط حاليًا حتى تبدّل إلى الفرع الجديد: $ git branch new-branch بدِّل إلى أيّ فرعٍ موجود، وتحقق منه في دليل العمل الحالي لديك: $ git checkout another-branch يمكنك دمج عمليتي إنشاء فرع جديد والتحقق منه باستخدام الراية b- على النحو التالي: $ git checkout -b new-branch أعِد تسمية فرعك على النحو التالي: $ git branch -m current-branch-name new-branch-name ادمج سجلات الفرع المحدد مع الفرع الذي تعمل فيه حاليًا: $ git merge branch-name بإمكانك إلغاء عملية الدمج في حال وجود تعارضات على النحو التالي: $ git merge --abort كما يمكنك تحديد إيداعٍ معيّن لدمجه باستخدام الأمر cherry-pick وكتابة سلسلة المحارف التي تشير إلى ذلك الإيداع: $ git cherry-pick f7649d0 عندما تدمج فرعًا ولم تعد بحاجة إليه، يمكنك حذفه على النحو التالي: $ git branch -d branch-name إذا لم تدمج فرعًا مع الفرع الرئيسي، لكنك متأكد من رغبتك في حذفه، فيمكنك فرض حذف الفرع: $ git branch -D branch-name المشاركة والتحديث يمكنك استخدام الأمر fetch لتنزيل التعديلات من مستودع آخر، مثل المستودع الأوّلي البعيد على النحو التالي: $ git fetch upstream يُستخدم الأمر التالي لدمج الإيداعات التي جلبناها fetched. تذكر أن بعض المستودعات قد تستخدِم master بدلاً من main: $ git merge upstream/main ومن أجل دفع أو نقل إيداعات الفرع المحلي إلى فرع المستودع البعيد، استخدم الأمر التالي: $ git push origin main ولجلب ودمج أية إيداعات من فرع المتابعة tracking البعيد: $ git pull الفحص Inspecting اِعرض سجل الإيداع للفرع النشط حاليًا: $ git log اِعرض الإيداعات التي عدَّلت ملفًا معينًا، إذ يتبَع هذا العرض الملف بغض النظر عن إعادة التسمية: $ git log --follow my_script.py اعرض الإيداعات الموجودة في فرعٍ محدد وليست موجودة في الفرع الآخر، إذ سيعرض الأمر التالي الإيداعات في الفرع a-branch وغير الموجودة في الفرع b-branch: $ git log a-branch .. b-branch اطلع على السجلات المرجعية reflog لتعرف آخر مرةٍ حُدِّث فيها أحدث إيداعٍ في الفروع والمراجع الأخرى ضمن المستودع: $ git reflog اعرض أي كائنٍ في غيت من خلال سلسلة محارف إيداعه أو القيمة المعمَّاة Hash بصياغةٍ قابلة للقراءة على النحو التالي: $ git show de754f5 عرض التغييرات يعرض الأمرgit diff الفروقات بين الإيداعات والفروع وغيرها. يمكنك الاطلاع على المزيد عنها من خلال قراءة توثيق غيت. يُستخدم الأمر التالي لموازنة الملفات المُعدّلة الموجودة في مرحلة الإدراج: $ git diff --staged اعرض التغييرات على ما هو موجود في الفرع a-branch وغير الموجود في الفرع b-branch على النحو التالي: $ git diff a-branch .. b-branch اِعرض التغييرات بين إيداعين محدّدين على النحو التالي: $ git diff 61ce3e6 .. e221d9c تتبع مسار التغييرات من خلال حذف ملف من مشروعك ونظِّم هذا الحذف لإضافته إلى إيداع على النحو التالي: $ git rm file أو غيِّر مسار ملفٍ موجود، ثم نظِّم الانتقال: $ git mv existing-path new-path تحقَّق من سجل الإيداع لتعرف ما إذا نُقلت أية مسارات: $ git log --stat -M الإخفاء Stashing ستجد أحيانًا نفسك بعد إجراء بعض التعديلات على جزءٍ من الشيفرة البرمجية وقبل الانتهاء مضطرًا إلى بدء العمل على أمرٍ آخر، وأنت لست مستعدًا لاعتماد التعديلات التي أجريتها حتى الآن، لكنك لا تريد أن يضيع عملك. في هذه الحالة، سيتيح لك الأمر git stash حفظ تعديلاتك المحلية في مكان ما والعودة مرةً أخرى إلى دليل العمل الذي يتوافق مع أحدث إيداع HEAD وتدعى هذه العملية بعملية الإخفاء أو الادخار stashing. لإخفاء عملك الحالي: $ git stash اطلِّع على ما اخفيته حاليًا: $ git stash list تُسمى الأعمال المُخبأة كما يلي: {stash@{0، و {stash@{1 وهكذا. لعرض معلومات عن عملٍ مُخبأ stash معين: $ git stash show stash@{0} أضف apply لاستخراج الملفات الموجودة في عملٍ مُخبأ حالي منه مع الاحتفاظ به: $ git stash apply stash@{0} إذا أردت استخراج الملفات من العمل المُخبأ ولم تعد بحاجته، أضف pop: $ git stash pop stash@{0} إذا لم تعد بحاجة الملفات المحفوظة في ملفٍ مُخبأ معين، أضف drop لإلغائه: $ git stash drop stash@{0} إذا كان لديك عدة أعمال مُدخرة محفوظة لم تعد تحتاج إلى استخدام أيٍّ منها، أضِف clear لإزالتها: $ git stash clear تجاهل الملفات إذا أردت الاحتفاظ بالملفات في دليل غيت المحلي لديك لكنك لا تريد إضافة إيداعٍ لهم إلى المشروع، أضِف هذه الملفات إلى ملف "gitignore." لديك حتى لا تتسبب بأية تعارضات. استخدم محرر نصوص مثل نانو، لإضافة الملفات إلى ملف "gitignore." على النحو التالي: $ nano .gitignore إذا أردت أن تجد نماذج لملفات "gitignore."، اطلع على مستودع قالب gitignore. لموقع غيت هَب GitHub. إعادة تأسيس الفروع تتيح لنا عملية إعادة التأسيس Rebase نقل الفروع من خلال تغيير الإيداع المبنية عليه، كما تتيح لك إزالة squash الإيداعات أو إعادة صياغتها. يمكنك بدء عملية إعادة التأسيس، إما باستدعاء عدد الإيداعات التي أنشأتها وتريد إعادة تأسيسها (العدد هو 5 في مثالنا التالي): $ git rebase -i HEAD~5 أو يمكنك إعادة التأسيس بالاعتماد على سلسلة محارف إيداع معين أو القيمة المُعمَّاة Hash: $ git rebase -i 074a4e5 بعد إزالة أو إعادة صياغة الإيداعات، يمكنك متابعة عملية إعادة تأسيس فرعك على أحدث إصدار من الشيفرة البرمجية الأولية للمشروع. تذكر أن بعض المستودعات قد تستخدم master بدلًا من main: $ git rebase upstream/main لتتعلم المزيد عن إعادة التأسيس والتحديث اقرأ كيف تعيد تأسيس طلب سحب وتحدِّثه الذي يمكن تطبيقه على أي نوع إيداعٍ تريده. التراجع وإعادة الضبط يمكنك التراجع عن التعديلات التي أجريتها على إيداعٍ معين باستخدام الأمر revert، إذ يجب أن تكون شجرة العمل نظيفةً حتى يتحقق ذلك: $ git revert 1fc6665 تحتاج أحيانًا إلى إعادة ضبط دليل شجرة العمل حتى بعد عملية إعادة التأسيس، إذ يمكنك باستخدام الأمر التالي إعادة الضبط إلى إيداعٍ معين، وحذف كافة التعديلات: $ git reset --hard 1fc6665 لفرض دفع push أحدث إيداعٍ معروف وغير متعارض لديك إلى المستودع الأصلي، عليك استخدام force-- على النحو التالي: $ git push --force origin main لإزالة الملفات والدلائل الفرعية غير المتتبعة من دليل غيت للحصول على فرع عملٍ نظيف، استخدم الأمر git clean: $ git clean -f -d إذا أردت تعديل مستودعك المحلي ليبدو مثل الفرع الرئيسي الأولي الحالي (أي عندما توجد كثيرٌ من التعارضات)، يمكنك تنفيذ استعادة الإعدادات الأصلية hard reset على النحو التالي: $ git reset --hard upstream/main ملاحظة: سيجعل تنفيذ هذا الأمر مستودعك المحلي يبدو تمامًا مثل الفرع الأولي، وستُتلف أية إيداعات أنشأتها ولم تسحبها إلى الفرع الأولي. الخاتمة يتناول هذا الدليل بعض أكثر أوامر غيت شيوعًا، والتي قد تستخدمها عند إدارة المستودعات والمشاركة في البرامج. توجد العديد من الأوامر التي قد تجدها مفيدةً لعملك على غيت. لمعرفة المزيد حول جميع الخيارات المتاحة لك، يمكنك تنفيذ الأمر التالي للحصول على معلومات مفيدة: $ git --help كما يمكنك قراءة المزيد حول غيت والاطلاع على ملفات توثيق غيت في قسم Git في أكاديمية حسوب وإن واجهتك أي مشكلة فأضف سؤالك في قسم الأسئلة والأجوبة لطلب المساعدة. ترجمة -وبتصرف- للمقال How To Use Git: A Reference Guide لصاحبته Lisa Tagliaferri. اقرأ أيضًا [فيديو] أساسيات Git مدخل إلى نظام التحكم في النسخ Git مبادئ Git الأساسية إعداد Git للمرة الأولى أساسيات سير عمل نظام التحكم في النسخ git
-
ترخيص البرنامج software license هو اتفاقيةٌ قانونيةٌ تحدِّد كيفية استخدام جزءٍ محددٍ من البرنامج، إذ يُعَد اختيار ترخيص البرنامج قرارًا مهمًا بالنسبة لمطوري البرامج الذين قد يرغبون في تطبيق حقوق وتصريحات permissions معينة على عملهم والتحكم في كيفية استخدام الآخرين له وتعديله ومشاركته؛ فقد يرغب بعض المطورين في فرض قيودٍ صارمة على كيفية استخدام برامجهم، على حين قد يختار آخرون ترخيص برامجهم بفرض قيودٍ قليلة أو دون فرض أية قيود، وقد ينبع هذا من رغبتهم في انتشار استخدام برامجهم على أوسع نطاقٍ ممكن، أو ربما لأنهم يعارضون مفهوم تراخيص البرامج المقيدة لأسباب فلسفية. يستطيع المطورون بغض النظر عن أسبابهم تحقيق ذلك من خلال تطبيق ترخيص برنامج مفتوح المصدر open-source، إذ تتيح تراخيص البرامج مفتوحة المصدر عمومًا الشيفرة البرمجية المصدرية source code للاستخدام والتعديل والنشر بناءً على شروطٍ وأحكامٍ مُتفَّقٍ عليها. يوجد العديد من تراخيص البرامج مفتوحة المصدر المختلفة، وهي تختلف بناءً على القيود التي يرغب مبتكر البرنامج أن يمتثل المستخدمون المستقبليون لها. عند وضع خططٍ طويلة الأمد لمشروعك، سيكون من المجدي فهم تراخيص البرامج مفتوحة المصدر المتاحة حتى تختار بحكمة الترخيص الذي يلائم متطلباته. سنستعرض في هذه المقالة معلوماتٍ حول حقوقك عند إنشاء عملك (مثل حقوق النشر)، وكيف يساعد الترخيص في إنشاء الاتفاقية القانونية التي تريد أن يمتثل المستخدمون لها عند استخدام برنامجك، كما سنناقش الفروقات بين البرمجيات الاحتكارية proprietary والمجانية ومفتوحة المصدر، وبين التراخيص المتساهلة permissive وتراخيص الحقوق المتروكة copyleft، ومعلوماتٍ عن خيارات ترخيص البرامج مفتوحة المصدر المقترحة عند إنشاء مشروع على موقع غيت هَب GitHub. تعريف حق النشر والترخيص تمنَح الولايات المتحدة والعديد من البلدان الأخرى تلقائيًا نوعًا من الحماية القانونية لأي عملٍ مُبتَكرٍ تنتجه، ويسمى أحد أنواع هذه الحماية حقوق النشر copyright؛ إذ يُعرِّف مكتب حقوق النشر في الولايات المتحدة حقوق النشر بأنها "أحد أنواع الملكية الفكرية التي تحمي الأعمال الأصلية المؤلَّفة"، تحديدًا عندما "ينظِّم المؤلف العمل بصيغة تعبير ملموسة"؛ أي أن منحك حقوق النشر لا يعني أنك صاحب الفكرة، بل أنك صاحب التعبير المادي عن الفكرة. إذا رغب مالك حقوق النشر بتطبيق حمايةٍ قانونيةٍ لعمله أكثر صرامة، يمكنه التوجُّه إلى براءات الاختراع والعلامات التجارية وقوانين الملكية الفكرية، إذ لا يتطلب حصولك على حقوق النشر لعملك إجراءً رسميًا لضمان منحها لك. تمنح حقوق النشر للمالك حقوقًا متنوعةً، مثل إعادة إنتاج نسخٍ من العمل ونشرها. إذا أراد المالك التحكم في كيفية استخدام الآخرين لعمله، يجب عليه تطبيق ترخيص يحدد القواعد التي يجب أن يمتثل لها المستخدمون، أما إذا صرَّح مالك حقوق النشر أن في عمله "جميع الحقوق محفوظة All Rights Reserved"، فهذا يعني أنه لا يحق لأي شخص سوى مالك حقوق النشر استخدام عمله أو تعديله. تتمثل إحدى تشعبات هذا الموضوع في العمل المبتكر الذي تقدمه لصاحب العمل؛ فإذا كنت منخرطًا في ما يُعرف باسم العمل مقابل الأجر work for hire، فهذا يعني أن أيّ عملٍ تبتكره لصالح الشركة أو المؤسَّسة التي تعمل بها تعود ملكيته إلى هذا الكيان، بما أنه يعطيك أجرًا مقابل هذا العمل. نتيجةً لذلك، تترتب عواقبٌ قانونية على مشاركتك هذا العمل دون إذن لعدم امتلاكك حقوق الملكية لحقوق النشر أو الترخيص. البرمجيات الاحتكارية والحرة ومفتوحة المصدر البرمجيات الاحتكارية Proprietary software هي أيُّ برنامجٍ له ترخيصٌ يقيد كيفية استخدامه أو تعديله أو مشاركته، وتُعد ألعاب الفيديو من الأمثلة الشائعة عن البرمجيات الاحتكارية. فإذا اشتريت لعبة فيديو -سواءٌ كانت على هيئة خرطوشة cartridge (بطاقات الألعاب التي نضعها بأجهزة الألعاب مثل نينتيندو Nintendo)، أو قرص، أو عن طريق تنزيلها رقميًا-، فلا يحق لك إنشاء نسخةٍ من تلك اللعبة لمشاركتها مع أصدقائك أو بيعها بغرض الربح، كما يُحتمَل ألا يُسمح لك بتعديل الشيفرة البرمجية للعبة لتشغيلها على نظامٍ مختلفٍ عن النظام الأصلي الذي صُمّمت لتعمل عليه عندما اشتريتها. يخضع عادةً مستخدمو البرامج لقيودٍ معينة بموجب اتفاقية ترخيص المستخدم النهائي end-user license agreement -أو اختصارًا EULA-؛ فإذا كنت قد اشتريت برنامجًا من قبل، لربما افترضت أنك تمتلك هذا البرنامج؛ ولكن إذا اشتريت برنامجًا احتكاريًا، فمن المرجّح أن يكون مرفقًا باتفاقية ترخيص المستخدم النهائي، التي تحدد أنك لا تملك البرنامج، وإنما تمتلك ترخيص البرنامج الذي يسمح لك باستخدامه. قد تحدد اتفاقيات ترخيص المستخدم النهائي أيضًا كيفية استخدام الترخيص نفسه، والتي تمنعك عادةً من مشاركته مع الآخرين دون الحصول على إذنٍ من مالك البرنامج (مطوِّر البرنامج أو ناشره). اتفاقية شروط الخدمة Terms of Service agreement -أو اختصارًا ToS-، هي صكٌ قانوني آخر مشابهٌ لاتفاقية ترخيص المستخدم النهائي EULA، وتُعرف أحيانًا باسم شروط الاستخدام Terms of Use أو الشروط والأحكام Terms and Conditions، ويُحدَّد ضمنها القواعد الواجب على المستخدم اتباعها من أجل السماح له باستخدام برنامج أو خدمة. من الشائع أن تتضمن البرامج التي تتطلب الشراء لمرةٍ واحدة اتفاقية ترخيص المستخدم النهائي، على حين تكون اتفاقيات شروط الخدمة أكثر شيوعًا في خدمات الاشتراك subscription والمواقع الإلكترونية؛ ففي المرة الأولى التي تبدأ فيها العمل على برنامج احتكاري معين، سيظهر مربع حوار في معظم الأحيان يشرح اتفاقية ترخيص المستخدم النهائي، أو اتفاقية شروط الخدمة ويحتوي على زر أوافق I Agree (أو عبارة مشابهة)، والذي يجب أن تنقر عليه قبل أن تتمكن من استخدام البرنامج. لم يكن فرض مثل هذه القيود العرف السائد دائمًا، إذ كانت تُنشَر البرامج عادةً مع شيفرتها البرمجية المصدرية قبل سبعينيات القرن الماضي، وهذا يعني أن المستخدمين كانوا أحرارًا في تعديل البرنامج ومشاركته كما يحلو لهم، ولكن مع مرور الوقت، بدأ ناشرو البرامج في فرض قيودٍ على هذه العمليات، بهدف زيادة الأرباح من خلال تخفيض عدد الأشخاص الذين يستخدمون برامجهم دون مقابل. كان لهذا التطور تداعيات تمثلت في حركتين مرتبطتين ارتباطًا وثيقًا، هما حركتي البرمجيات الحرة والبرمجيات مفتوحة المصدر. على الرغم من اختلاف الحركتين عن بعضهما، إلا أن كلاهما تدعوان إلى وجوب السماح لمستخدمي البرامج بالحصول على الشيفرة البرمجية المصدرية للبرنامج، وتعديلها على النحو الذي يرونه مناسبًا، ومشاركتها بالقدر الذي يريدونه ومع من يحلو لهم. يُعد البرنامج الحر عمومًا مفتوح المصدر، لكن لا يُعد البرنامج مفتوح المصدر مجانيًا دائمًا، لذلك سنعود في تتمة هذا الدليل إلى استخدام المصطلحات الأشمل "البرنامج مفتوح المصدر" و"ترخيص البرنامج مفتوح المصدر". ومع ذلك، يرجى أخذ العلم أنه لا يحل أحد المصطلحين محل الآخر دائمًا. لا يزال مناصرو البرمجيات مفتوحة المصدر يشجعون المطورين على نشر برامجهم بموجب ترخيص، لكن بدلًا من ترخيص البرنامج الاحتكاري الذي يحدد ما لا يجوز للمستخدمين فعله، يوصون باستخدام ترخيص برنامج مفتوح المصدر يحدِّد الحريات المتاحة لمستخدمي جزءٍ معينٍ من البرنامج. توزَّع هذه التراخيص غالبًا على هيئة ملفٍ واحدٍ ضمن البرنامج، يُسمى عادةً "LICENSE.txt" أو اصطلاح تسميةٍ مشابه. على مر السنين، دار بعض الخلاف حول الحريات المحددة التي يجب أن يضمنها ترخيص البرمجيات مفتوحة المصدر، وقد أدى هذا إلى ظهور العديد من تراخيص البرامج مفتوحة المصدر المختلفة، لكن يندرج معظمها ضمن إحدى الفئتين التاليتين: التراخيص المتساهلة وتراخيص الحقوق المتروكة. تراخيص البرامج مفتوحة المصدر المتساهلة والحقوق المتروكة الترخيص المتساهل permissive license والذي يُشار إليه أحيانًا بترخيص الحقوق غير المتروكة non-copyleft، هو ترخيصٌ يمنح المستخدمين تصريحًا باستخدام الشيفرة البرمجية المصدرية وتعديلها ومشاركتها، ويتيح للمستخدمين أيضًا خيار تعديل بعض شروط وأحكام إعادة النشر، بما في ذلك الأعمال المشتقة derivative work؛ إذ يُعرف العمل المشتق في مجال البرامج بأنه جزءٌ من البرنامج ومبنيٌ على برنامجٍ موجود. فإذا أُصدر البرنامج الأصلي بموجب ترخيصٍ متساهل، يحق لمبتكر البرنامج اختيار مشاركة عمله المشتق بموجب شروطٍ مختلفةٍ عن شروط ترخيص العمل الأصلي. يمنح ترخيص الحقوق المتروكة copyleft license للمستخدمين أيضًا تصريحًا باستخدام الشيفرة البرمجية المصدرية وتعديلها ومشاركتها، لكنه يوفر الحماية ضد إعادة الترخيص relicensing من خلال فرض قيودٍ وشروطٍ وأحكامٍ محددة؛ وهذا يعني أن مستخدمي البرامج الذين ينشئون أعمالًا مشتقةً ملزمون بإصدارها بموجب نفس شروط وأحكام ترخيص الحقوق المتروكة الخاص بالعمل الأصلي. تُعد هذه التبادلية reciprocity السمة المميِّزة لتراخيص الحقوق المتروكة، وتهدف إلى حماية نوايا المبتكرين من خلال ضمان حصول المستخدمين على نفس الحقوق والتصريحات عند استخدام الأعمال المُشتقة من البرنامج الأصلي. إضافةً إلى ما سبق، توجد تراخيصٌ مكافئةٌ للملكية العامة public-domain، وهي تمنح المستخدمين تصريحًا باستخدام الأعمال المحمية بحقوق النشر دون إسنادها، أو إلزامهم بالتوافق مع الترخيص المطلوب، وهذا يعني أن أي حقوق لمبتكر البرنامج على عمله مصادرةٌ تمامًا. على الرغم من وجود بعض التداخل في الفلسفات الكامنة وراء تراخيص برامج الملكية العامة والحرة ومفتوحة المصدر، فقد دار خلافٌ على مر السنين حول ما إذا كان الترخيص المكافئ للملكية العامة يُصنَّف حقًا على أنه ترخيصٌ مفتوح المصدر. قدِّمت هيئة المشاع الإبداعي CC0 في عام 2012 ترخيصًا، ولكن رفضت مؤسسة مبادرة المصدر المفتوح Open Source Initiative -أو اختصارًا OSI- اعتماده؛ وهي مؤسسة غير ربحية تحدِّد معايير البرامج مفتوحة المصدر وتحتفظ بقائمة التراخيص مفتوحة المصدر المعتمدة. ومع ذلك، وافقت المؤسسة على ترخيصٍ مكافئ للملكية العامة يُدعى غير مرخص Unlicense في عام 2020. ما فائدة إضافة ترخيص برنامج مفتوح المصدر؟ بصفتك مطورًا يبدأ مشروعًا من نقطة الصفر، فمن الضروري أن تكون مُلمًا بعض الشيء بتراخيص البرامج مفتوحة المصدر المتاحة لتختار طريقة استخدام الآخرين لعملك؛ كما يُعد التعرف على هذه التراخيص أمرًا مهمًا أيضًا بالنسبة للمستخدمين حتى يتمكنوا من فهم التصريحات أو القيود التي حددتها الاتفاقية المُبرمة عند استخدام عمل المبتكِر. نكرر ثانيةً، سيكون لأي عمل أصلي حقوق نشر عند إنهائه، لكن لن يكون له ترخيص، فلا يتضح لمن يرغبون في استخدامه ما الأمور المُصرَّح بها وغير المصرح بها. ألقِ نظرةً على الأسباب التالية التي تدفعك إلى إضافة ترخيص برنامج مفتوح المصدر: التطوير: يفخَر مجتمع المصدر المفتوح بنفسه لغرس ثقافةٍ تشجع على التعاون والابتكار، كما يدعو استخدام ترخيص برنامج مفتوح المصدر المستخدمين إلى الانخراط في تنمية المجتمع، وهذا يولد إحساسًا مشتركًا بالمسؤولية لتطوير الشيفرة البرمجية المصدرية باستمرار أو توسيع البرنامج لصالح الجميع. الملكية: إذا كنت ترغب في أن يكون لديك سلطةٌ أكبر على عملك، فسيساعدك اختيار ترخيصٍ يمكنه فرض تلك القيود على تحقيق ذلك. فإذا أردت مثلًا منح أية أعمالٍ مشتقةٍ التصريحات ذاتها التي اخترتها في الأصل، فقد ترغب في اختيار ترخيص الحقوق المتروكة. لحسن الحظ، يوفِّر ترخيص البرنامج مفتوح المصدر الشفافية للمستخدمين المستقبليين حول مقدار تحكُّمك في العمل، سواءٌ كان كبيرًا أو قليلًا، فالأمر يعود إليك. المنافسة: يوجد عددٌ هائلٌ من البرامج، وإذا كنت ترغب في اقتحام هذا السوق، يمكن أن يساعدك استخدام ترخيص مفتوح المصدر على البروز فيه. يُعد نظام التشغيل لينوكس Linux ونظام أندرويد Android الذي أنتجته شركة جوجل Google ومتصفح فايرفوكس Firefox من بين الأمثلة الشائعة للبرامج مفتوحة المصدر التي طوِّرَت لتنافس البدائل الاحتكارية الراسخة. تذكر أنك تستطيع تحقيق أرباحٍ من مشروعٍ برمجي مفتوح المصدر، لكن العرف التجاري لتحقيق أرباحٍ من البرامج هو استخدام ترخيصٍ احتكاري لحماية البرنامج من المشاركة أو السرقة. قد لا تنطبق عليك جميع الأسباب المذكورة لاستخدام ترخيص برنامج مفتوح المصدر، ولذلك نحثُّك على البحث بنفسك في هذا الموضوع قبل اختيار ترخيصٍ لمشروعك القادم، وربما يجب أن تطلب استشارةً قانونيةً لتتأكد من فهمك التام لما قد يمثّله الترخيص لعملك في الحاضر والمستقبل. كما سبق وذكرنا، تتناول هذه المقالة تراخيص البرامج مفتوحة المصدر المُدرجة عند إنشاء مستودعٍ جديد لمشروعك على موقع غيت هَب. ستلاحظ في نهاية الصفحة وجود خيارٍ لاختيار ترخيص، وبمجرد النقر على المربع ستظهر قائمةٌ منسدلةٌ تحتوي التراخيص لتختار واحدًا منها، كما هو موضحٌ في الصورة التالية: (التراخيص على موقع غيت هَب) سنقدِّم في الفقرات اللاحقة توصيفًا موجزًا لأنواع تراخيص البرامج مفتوحة المصدر، والتي يمكنك اختيار أحدها لإضافته إلى مشروعك القادم، بدءًا من التراخيص المتساهلة التي يوصي بها موقع غيت هَب. تراخيص البرامج مفتوحة المصدر المتساهلة تمنح التراخيص المتساهلة مستخدمي البرامج تصريحًا باستخدام الشيفرة البرمجية المصدرية وتعديلها ومشاركتها. إضافةً إلى ذلك، يحق لمبتكري البرامج المُشتقة من البرامج المُرخصة ترخيصًا متساهلًا تغيير شروط الترخيص لإعادة نشرها. يرجى أخذ العلم أن القائمة التالية لا تمثِّل جميع تراخيص البرامج مفتوحة المصدر المتساهلة المتاحة، بل هي مأخوذةٌ من خيارات الترخيص التي يقدمها موقع غيت هَب عند إنشاء مشروعٍ جديد، كما أن هذه التوصيفات الموجزة ليست شاملة. ننصحك أن تقرأ بتمعنٍ توثيق أيِّ ترخيصٍ ترغب في استخدامه، أو تتحدث مع مختصٍ قانوني للحصول على مزيدٍ من المعلومات. ترخيص أباتشي Apache أُصدِر ترخيص أباتشي من قِبل مؤسَّسة برمجيات أباتشي، وهو ينص على عدم إلزام المستخدم مشاركة نسخته المُعدّلة من الشيفرة البرمجية المصدرية بموجب نفس الترخيص، بحيث يمكنه اختيار استخدام ترخيصٍ مختلف، وهذا ما يُعرف باسم الترخيص الفرعي sublicensing. ترخيص معهد ماساتشوستس للتكنولوجيا MIT أصدر معهد ماساتشوستس للتكنولوجيا Massachusetts Institute of Technology -أو اختصارًا MIT- ترخيص معهد ماساتشوستس للتكنولوجيا MIT، وهو أحد أقصر التراخيص في القراءة ويتضمن قيودًا قليلةً؛ وعلى غرار ترخيص أباتشي، فإنه يمنح المستخدمين أيضًا خيار ترخيص البرنامج ترخيصًا فرعيًا. تراخيص بي إس دي BSD يتيح لك موقع غيت هَب الاختيار بين نوعين من تراخيص BSD، هما ترخيصترخيص BSD 2-Clause "المُبسَّط"، والذي يُشار إليه أحيانًا باسم ترخيص بي إس دي الحر "FreeBSD"، و ترخيص BSD 3-Clause "الجديد" أو "المعدَّل"؛ إذ يكمن الفرق الرئيسي بينهما في البند الثالث، الذي يقيِّد مستخدمي البرامج من استخدام اسم المؤلف، أو المؤلفين، أو المساهمين في مصادقة المنتجات أو الخدمات. ترخيص برنامج بوست Boost يمكننا الحصول على ترخيص برنامج بوست من مكاتب بوست في اللغة البرمجية ++C، وقد أقرَّته مؤسسة مبادرة المصدر المفتوح في عام 2008. يُعد هذا الترخيص مشابهٌ لتراخيص MIT و BSD، إلا أنه لا يتطلب إسنادًا عند إعادة نشر البرنامج في الصيغة الثنائية binary. تراخيص الحقوق المتروكة للبرامج مفتوحة المصدر تمنح تراخيص الحقوق المتروكة لمستخدمي البرنامج تصريحًا باستخدام الشيفرة البرمجية المصدرية وتعديلها ومشاركتها، لكنها توفِّر أيضًا الحماية من إعادة الترخيص من خلال فرض قيودٍ وشروطٍ وأحكامٍ محدّدة؛ وهذا ما يُمثِّل الخاصية التبادلية لهذا الترخيص التي تتطلب امتثال عمل المستخدم للحقوق الأصلية الموضحة في الترخيص. وكما ذكرنا، لا تمثل القائمة التالية جميع تراخيص الحقوق المتروكة للبرامج مفتوحة المصدر المتاحة، بل هي مأخوذةٌ من خيارات الترخيص التي يقدمها موقع غيت هَب عند إنشاء مشروعٍ جديد، كما أن هذه التوصيفات الموجزة ليست شاملة. ننصحك أن تقرأ بتمعنٍ توثيق أيّ ترخيصٍ ترغب في استخدامه، أو تتحدث مع مختصٍ قانوني للحصول على مزيدٍ من المعلومات. تراخيص جنو GNU أصدرت مؤسسة البرمجيات الحرة عدة إصدارات من ترخيص جنو العلني General Public License - أو اختصارًا GPL-، إذ يتيح موقع غيت هَب للمستخدم الاختيار بين أربعٍ منها. يُلزِم الإصدار 3.0 من GPL أو GPL v3.0 المستخدمين بذكر أية تعديلات على الشيفرة البرمجية الأساسية، وإتاحتها عند نشر أية ملفاتٍ ثنائيةٍ مُستخدمة على عملهم بموجب هذا البرنامج المرخص؛ كما يسهِّل هذا الترخيص العمل مع التراخيص الأخرى، مثل ترخيص أباتشي، الذي لم يكن الإصدار السابق منه v2.0 متوافقًا معه. أُنشأ ترخيص جنو العلني الإصدار الثاني أو GPL v2.0 قبل الإصدار الحالي GPL v3.0، ويشترك في الشروط والأحكام مع الإصدار الثالث، لكنه يُعد ترخيصًا قويًا للحقوق المتروكة، إذ يتطلب ترخيص الحقوق المتروكة القوي إصدار أية تعديلات على الشيفرة المصدرية بموجب نفس الترخيص. يتمثل الاختلاف الأساسي بين الإصدار 3.0 و 2.0 في أنه يُسمح لمستخدمي البرامج في الإصدار 2.0 بنشر العمل إذا كانوا يلتزمون بشروط الترخيص، بغض النظر عن الالتزامات القانونية السابقة، والهدف من هذا البند هو منع أي فرد أو طرف من تقديم ادعاء بانتهاك براءة الاختراع التي تقيد حرية المستخدم بموجب هذا الترخيص. كانت إحدى الإصدارات الأخرى للترخيص رخصة جنو ليسر Lesser العلنية، والمُشار إليها باسم LGPL، أو بالإصدار 2.1 من إصدار GPL v2.0، ويهدف هذا الترخيص إلى أن يكون في الوسط بين تراخيص الحقوق المتروكة القوية والضعيفة. يتمثّل الاختلاف الرئيسي في هذا الترخيص في أنه يتيح لمستخدمي البرامج دمج عنصرٍ من برنامجٍ مرخص بموجب ترخيص LGPL مع عناصر برنامجهم، وليسوا مطالبين بمشاركة الشيفرة البرمجية المصدرية لعناصر برنامجهم؛ كما يحق للمستخدمين أيضًا نشر مكتبةٍ هجينة، وهي مجموعةٌ من الدالات من مكتبة مرخصة بموجب ترخيص LGPL ودالاتٍ من مكتبةٍ مرخصة بموجب ترخيص آخر، لكن يجب أن يوفِّروا نسخةً من تلك المكتبة المرخصة بترخيصٍ غير LGPL ومعلوماتٍ عن مكانها. تُعد رخصة جنو أفيرو Affero العلنية الإصدار v3.0 إصدارًا آخرًا من تراخيص جنو، ويُشار إليها باسم AGPL. يتمثل الاختلاف الرئيسي في هذا الترخيص في أنه مخصصٌ للبرامج المستخدمة على الخوادم، ويلزِم هذا الترخيص المستخدمين الذين يشغلون برنامجًا مُعدَّلًا على خادمٍ ما بمشاركة هذه المعلومات وإتاحة الشيفرة البرمجية المصدرية المعدلة للتنزيل إلى الإصدار المُعدَّل الملائم المُشغّّل حاليًا على الخادم. ترخيص إكليبس العلني Eclipse Public أصدرت مؤسَّسة إكليبس Eclipse ترخيص إكليبس العلني، الذي يُعد ترخيص حقوق متروكة ضعيف يُلزِم مستخدمي البرامج بمشاركة أية تغييرات يجرونها على الشيفرة البرمجية. اختار هذا الترخيص تطبيق ترخيص حقوق متروكة أضعف لتخفيف تشدُّد شروط تراخيص جنو العلنية على المستخدمين. ترخيص موزيلا العلني Mozilla Public أصدرت مؤسَّسة موزيلا ترخيص موزيلا العلني Mozilla Public License -أو اختصارًا MPL-، ويُعد أيضًا ترخيص حقوق متروكة ضعيف. يتمثل الاختلاف في هذا الترخيص موازنةً مع ترخيص إكليبس العلني، في أنه ترخيص حقوقٍ متروكة مبنيٌ على الملفات، ما يعني أنه يمكن دمج الشيفرة البرمجية مع شيفرة برمجية مفتوحة المصدر أو احتكارية. التراخيص المكافئة للملكية العامة تمنح التراخيص المكافئة للملكية العامة المستخدمين تصريحًا باستخدام الأعمال المحمية بحقوق النشر دون إسنادها، أو إلزامهم بالتوافق مع الترخيص المطلوب. وكما ذكرنا، لا تكون هذه التراخيص مُعتمدةً دائمًا من قِبل مؤسَّسة مبادرة المصدر المفتوح OSI. ترخيص المشاع الإبداعي العالمي الصفري أصدرت منظمة المشاع الإبداعي ترخيص المشاع الإبداعي العالمي الصفري، الذي يُعد ترخيص حقوق نشر علنية، أي يمكن نشر العمل المحمي بحقوق النشر بحرية. يرجى أخذ العلم أن هذا الترخيص غير مُعتمَدٍ من مؤسسة مبادرة المصدر المفتوح OSI. تتمثل النقطة الأساسية في هذا الترخيص في امكانية المستخدمين من استخدام الشيفرة البرمجية المصدرية وتوزيعها وتعديلها، لكن عليهم أن يوافقوا على التنازل عن أي حقوق نشر لضمان إمكانية الوصول إلى هذا العمل في النطاق العلني. إضافةً إلى ذلك، لا يُلزَم المستخدمون بتقديم أي إسنادٍ للعمل ويمكنهم استخدامه تجاريًا. الترخيص غير المرخص Unlicense أُصدِر الترخيص غير المرخص Unlicense في عام 2012، ويُعد ترخيصًا مكافئًا للملكية العامة ومُعتمَدًا من مؤسَّسة مبادرة المصدر المفتوح. بموجب هذا الترخيص، يحق لمستخدمي البرامج استخدام الشيفرة البرمجية المصدرية والملفات الثنائية المُجمَّعة وتعديلها ونشرها لأغراضٍ تجارية وغير تجارية، كما ينصح هذا الترخيص المستخدمين الذين يرغبون في ضمان توفِّر مساهماتٍ في الشيفرة البرمجية أو البرنامج للعامة بتضمين تصريحٍ حول التزامهم بمشاركة الشيفرة الرئيسية مع العامة. الخاتمة توجد عواملٌ كثيرة يجب دراستها عند اختيار ترخيص برنامج مفتوح المصدر، ولكن توجد بالتأكيد بعض الخيارات الشائعة في مجتمع المطورين. نذكر من التراخيص المتساهلة الشائعة ترخيص معهد ماساتشوستس للتكنولوجيا MIT، وترخيص أباتشي، وتراخيص BSD، كما تتضمن بعض تراخيص الحقوق المتروكة الشائعة رخصة جنو العلنية ورخصة موزيلا العلنية. تذكر أن هذه المقالة قدَّمت معلوماتٍ حول بعض تراخيص البرامج مفتوحة المصدر الشائعة فقط، وتحديدًا التراخيص التي اقترحها موقع غيت هَب. نحثُّك على استكشاف جميع خيارات الترخيص المتاحة، أو استشارة مختصٍ قانوني حتى تختار بحكمة الترخيص الذي يلائم متطلبات مشروعك. ترجمة -وبتصرف- للمقال Understanding Open-Source Software Licenses لصاحبته Jeanelle Horcasitas. اقرأ أيضًا تعرف على أنواع التراخيص الحرة التي تسمح لك ببيع المواد بشكل تجاري طرق التعريف بمشروعك مفتوح المصدر صيانة المشاريع مفتوحة المصدر ثلاث خطوات لتأمين DevOps مفتوح المصدر
-
عندما تشرف maintain على مستودع برنامجٍ مفتوح المصدر، فإنك تتولى دورًا قياديًا، سواءً كنت مؤسِّس المشروع الذي أطلقه وأتاحه للاستخدام والمساهمات، أو كنت تعمل ضمن فريق وتشرف على جانبٍ محددٍ من المشروع، فأنت تقدم خدمةً مهمةً لمجتمع المطورين العام. على الرغم من أن مساهمات مجتمع المطورين مفتوحة المصدر التي تجري من خلال طلبات السحب ضروريةٌ لضمان تحقيق البرنامج الفائدة القصوى للمستخدمين النهائيين، لكن يوجد للمشرفين تأثيرٌ حقيقي على صياغة مجمَل المشروع؛ إذ يشارك المشرفون على المستودعات لدرجة هائلة في المشاريع مفتوحة المصدر التي يديرونها، من التنظيم والتطوير اليومي إلى التفاعل مع الجمهور وتقديم ملاحظاتٍ فوريةٍ وفعالةٍ للمساهمين. سيتناول هذا الدليل بعض النصائح حول الإشراف على المستودعات العامة للبرامج مفتوحة المصدر، إذ يترافق كونك قائدًا لمشروعٍ مفتوح المصدر مع مسؤولياتٍ تقنية وغير تقنية للمساهمة في تعزيز قاعدة المستخدمين والدائرة المجتمعية حول مشروعك. إن تولي دور المشرف هو فرصة للتعلُّم من الآخرين، واكتساب الخبرة في إدارة المشاريع، ومراقبة نمو مشروعك وتغيره عندما يصبح المستخدمون مساهمين مستثمرين. كتابة توثيق مفيد يساهم التوثيق Documentation الشامل وحسن التنظيم الذي يخدم الفئات المستهدفة في مشروعك على توسيع قاعدة مستخدميه، وستصبح قاعدة المستخدمين هذه مع مرور الوقت هي المساهمة في مشروعك مفتوح المصدر. قد يفيدك جعل كتابة التوثيق جزءًا من عملية التطوير الخاصة بك، لأنك ستفكر في الشيفرة البرمجية التي تكتبها على أية حال، وربما تدِّون ملاحظاتٍ عنها، فتستغل بذلك أن الأفكار حديثة في ذهنك؛ وربما ترغب في كتابة التوثيق قبل الشيفرة البرمجية، فتكون بذلك متبعًا لفلسفة نهج التطوير المستند على التوثيق، إذ يوثق هذا النهج خصائص البرنامج أولًا ثم يبرمجها بعد كتابة وظيفة كلٍ منها. إليك بعض ملفات التوثيق التي يجب الاحتفاظ بها في مجلد المستوى الأعلى top-level directory الخاص بك، إلى جانب ملف شيفرتك البرمجية: ملف README.md، الذي يقدم ملخصًا عن المشروع وأهدافك منه. ملف CONTRIBUTING.md، الذي يحتوي على تعليمات المساهمة. ترخيص برنامجك، والذي يمكن أن يشجع الأشخاص على تقديم مساهماتٍ أكثر. ويمكنك قراءة المزيد حول اختيار ترخيص لبرنامجٍ مفتوح المصدر. يوجد للتوثيق عدّة صيغٍ، ويمكن أن يُوجَّه لجماهير مختلفة، إذ يمكنك اختيار نوعٍ واحد أو أكثر من الأنواع التالية على أنه جزءٌ من توثيقك بناءً على مجال عملك: دليل عام general guide: لتعريف المستخدمين بالمشروع. دروس تعليمية Tutorials: لشرح حالات الاستخدام المختلفة. الأسئلة الشائعة FAQs: للإجابة على أكثر الأسئلة التي يطرحها المستخدمون. أدلة اكتشاف الأخطاء وتصحيحها Troubleshooting guides: لمساعدة المستخدمين على حل المشاكل. مرجع للواجهة البرمجية API reference: الذي يوفر للمستخدمين طريقةً سريعةً للعثور على معلومات الواجهة البرمجية API. ملاحظات الإصدار Release notes: إضافةً إلى الأخطاء البرمجية bugs المعروفة وذلك لإعلام المستخدمين ماذا يتوقعون في كل إصدار. الخصائص المخطط لها Planned features: لمتابعتها وشرح الخصائص المُخطط إضافتها لاحقًا. مقاطع فيديو توجيهية Video walkthroughs: لتزويد المستخدمين بنهج وسائط متعددة لاستخدام برنامجك. قد تلائم أنواعٌ معينة من التوثيق مشروعك أكثر من غيرها، ولكن سيساعد تقديم أكثر من نهجٍ واحدٍ في البرنامج قاعدة المستخدمين لديك على فهم آلية التفاعل مع عملك بصورةٍ أفضل. عند كتابة التوثيق أو تسجيل مقطع صوت أو فيديو، يجب أن تكون واضحًا قدر الإمكان، إذ يُستحسن ألا تضع افتراضاتٍ حول إمكانيات جمهورك التقنية، وعليك أيضًا التعامل مع التوثيق من القشرة إلى اللب، أي شرح وظائف برنامجك بصورةٍ عامة، مثل أتمتة مهام الخادم وإنشاء موقع إلكتروني وتحريك العفاريت لتطوير لعبة، قبل الخوض في التفاصيل. أصبحت اللغة الإنجليزية لغةً عالميةً في مجال التكنولوجيا، ومع ذلك عليك دراسة هوية المستخدمين المستهدفين وكيفية الوصول إليهم؛ إذ قد تكون اللغة الإنجليزية هي الخيار الأفضل للتواصل مع قاعدة مستخدمين واسعة، لكن عليك أن تُبقي في ذهنك أن توثيقك سيكون مُوجَّهًا للعديد من الأشخاص الذين لا تكون اللغة الإنجليزية لغتهم الأم، لذا اعمل على تفضيل لغةٍ يسهل الوصول إليها ولا تربك القراء أو المشاهدين. حاول كتابة التوثيقات كما لو كانت موجهةً إلى أحد المساهمين الذين يحتاجون إلى الاطلاع على المشروع الحالي بسرعة؛ ففي النهاية، سترغب في تشجيع المساهمين المحتملين على تقديم طلبات سحب لمشروعك. تنظيم المشاكل تُعد المشاكل issues عادةً طريقةً لمتابعة الزلات البرمجية أو الإبلاغ عنها، أو لطلب خصائص جديدة لإضافتها إلى الشيفرة البرمجية الرئيسية، إذ تقدم خدمات استضافة المستودعات مفتوحة المصدر، مثل غيت هَب وغيت لاب GitLab وبيت بَكيت Bitbucket واجهةً لك وللآخرين لمتابعة المشاكل ضمن مستودعك. عند إصدار شيفرة برمجية مفتوحة المصدر للعامة، يجب أن تتوقع ظهور مشاكل يفتحها مجتمع المستخدمين، لذلك يمنحك تنظيم المشاكل وترتيب أولويتها دليلًا تفصيليًا جيدًا للعمل اللاحق في مشروعك. يستطيع كل مستخدم تقديم قضية، وبالتالي لن تكون كل المشاكل إبلاغًا عن أخطاء برمجية أو طلبات لإضافة خصائص، فقد تتلقى مثلًا أسئلةً عبر أداة تتبع المشاكل، أو طلباتٍ لتحسينات صغيرة على واجهة المستخدم، لذلك يُستحسن تنظيم هذه المشاكل قدر الإمكان والتواصل مع المستخدمين الذين يقدمون هذه المشاكل. ينبغي أن تمثّل المشاكل مهامًا محددة تحتاج تنفيذها على الشيفرة البرمجية المصدرية، وعليك ترتيبها حسب أولويتها وفقًا لذلك؛ كما لا بُدّ من التفاهم مع فريقك على مقدار الوقت والطاقة الذي ستكرسه أنت أو المساهمون لتطبيق المشاكل المقدَّمة، ويمكنكم التعاون معًا في اتخاذ القرارات ووضع خطة قابلة للتنفيذ؛ وعندما تعلم أنك لن تتمكن من تناول قضيةٍ معينة خلال إطارٍ زمني عاجل، علِّق على القضية لإعلام المستخدم بأنك قد اطلعت عليها وأنك ستتطرق إليها عندما تستطيع، وإذا استطعت يمكنك تزويده بالجدول الزمني المتوقع الذي يتضمن الوقت الذي سيُتاح لك فيه مراجعة القضية مجددًا. بالنسبة إلى المشاكل التي تتضمن طلبات خصائص أو تحسينات، يمكنك أن تسأل الشخص الذي قدَّم القضية عما إذا كان قادرًا على المساهمة في الشيفرة البرمجية بنفسه، ويمكنك توجيهه إلى الملف "CONTRIBUTORS.md" وأي توثيقٍ آخر ذي صلة. لا تمثِّل الأسئلة غالبًا مهامًا محددةً، لذلك يُعد تعليقك على القضية بتوجيه المستخدم بلطف إلى التوثيق المرتبط بسؤاله خيارًا جيدًا للمحافظة على أسلوب تواصلك احترافيًا ولطيفًا؛ وإذا لم يكن التوثيق المتعلق بهذا السؤال موجودًا، فهذا الوقت المناسب لإضافة توثيقٍ ذي صلة به والتعبير عن امتنانك للمستخدم لتنبيهك على إغفالك لهذا الجزء؛ وإذا كنت تتلقى كثيرًا من الأسئلة عبر المشاكل، ينصح أن تفكر في إنشاء قسم الأسئلة الشائعة بين ملفات توثيقك، أو ملف توثيق ويكي wiki، أو منتدى ليشارك فيه الآخرون في الإجابة على الأسئلة. عندما يقدم المستخدم قضيةً، حاول أن تكون لطيفًا وحليمًا قدر الإمكان، فالمشكلات هي مؤشرات على إعجاب المستخدمين ببرنامجك ويريدون تحسينه. يجعل تنظيم المشاكل قدر الإمكان مشروعك محدثًا باستمرار وعلى صلةٍ بمجتمع المستخدمين، لذلك احذف المشاكل التي تكون خارج مجال مشروعك أو التي أصبحت قديمة، وحدِّد أولوية المشاكل الأخرى حتى تتمكن من تحقيق تقدُّمٍ متواصل. أتمتة المهام يمكنك تحسين فعالية وجودة مشروعك عن طريق أتمتة مهام الصيانة والاختبار، إذ يمكن للصيانة والاختبار المؤتمتَين التحقُّق باستمرار من دقة شيفرتك البرمجية وتوفر عمليةٍ رسميةٍ أكثر للموافقة على عمليات تقديم المساهمين، ويساعد هذا في توفير الوقت حتى تتمكن من التركيز على الجوانب الأهم في مشروعك، ولعل الجانب الإيجابي في توفُّر كثيرٍ من الأدوات المُطوّرة فعلًا لذلك قد يلبي احتياجات مشروعك. أعِدَّ الاختبار المؤتمت للمساهمات الواردة من خلال فرض عمليات تحقق من الحالة، واحرص على إضافة معلوماتٍ حول آلية عمل الاختبار لمشروعك إلى ملف "CONTRIBUTORS.md". تحقق من الأدوات المُطوَّرة لأتمتة مهام الصيانة، إذ تقدِّم لك هذه الأدوات خياراتٍ متنوعة، مثل أتمتة الإصدارات الخاصة بك ومراجعة الشيفرة البرمجية، أو إغلاق المشاكل إذا لم يستجب كاتبها عند طلب معلوماتٍ منه. أبقِ في ذهنك أن كل زائدٍ ناقص، واحرص على أن تكون العمليات والمهام التي تختار أتمتتها مدروسةً وبطرائقٍ تُحسِّن كفاءة وإنتاجية وجودة عملك ومشروعك والمساهمين فيه. اجعل المساهمة مجزية كلما رحبت بالمساهمين في مشروعك وكافأت جهودهم، زادت احتمالية تشجيع تلقي مساهماتٍ أكثر. ولمساعدة الأشخاص على البدء، عليك أن تضع ملف "CONTRIBUTORS.md" في أعلى مستوى top-level من المستودع الخاص بك، ومؤشرٌ على مكان هذا الملف في ملف "README.md". ستحدّد سمات ملف المساهمة النافع طريقة بدء المطور في العمل على المشروع، وتقديم دليلٍ مفصَّل أو قائمة تحقق يتّبعها المطورون، تشرح كيف ينجحون في دمج شيفرتهم البرمجية في المشروع من خلال طلب السحب. لاتنسَ بعد إضافة توثيقٍ حول طريقة المساهمة في المشروع، أن تحافظ على تناسق كامل شيفرتك البرمجية وقابليتها للقراءة، إذ ستسهم الشيفرة البرمجية التي يسهل فهمها من خلال إضافة تعليقاتٍ إليها واستخدامها الواضح والمتناسق إسهامًا كبيرًا في منح المساهمين الإحساس بأنهم يستطيعون المشاركة في المشروع. وختامًا، أبقِ قائمةً بالمساهمين والكتاب لديك، كما يمكنك أن تدعو المساهمين إلى إضافة أنفسهم إلى هذه القائمة مهما كانت مساهماتهم (حتى تصحيح الأخطاء الإملائية يُعَد مساهمةً مهمةً، وقد تقود إلى مساهمات أكبر لاحقًا). يتيح هذا الأسلوب إبراز المساهمين وعملهم على المشروع للجميع بحيث يستطيعون الإشارة إليه، وجعل الجميع يعي قدر المعاملة الحسنة التي يتلقاها المساهمون. بناء مجتمعك يعني تمكينك للمستخدمين من خلال إضافتك للتوثيق، وتجاوبك مع المشاكل، وتشجيع المستخدمين على المشاركة، أنك تسير على الطريق الصحيح نحو بناء مجتمعٍ حول مشروعك مفتوح المصدر، إذ سيروِّج المستخدمون الذين تحرص على إسعادهم وتعاملهم على أنهم مساهمون لبرنامجك بدورهم. إضافةً إلى ما سبق، يمكنك العمل على الترويج لمشروعك بعدة أساليب: التدوين Blogging. إصدار مقاطع فيديو للمراجعة walkthrough أو متضمنةً لمحةً عامةً عن المشروع. حفظ قائمة بحسابات بريد إلكتروني. كن نشطًا على قنوات وسائل التواصل الاجتماعي. التعاون مع مطوري مشاريع مشابهة لمشروعك أو مرتبطةً به وتحقيق الترويج المتبادل بينهما. عليك تصميم أسلوبك الترويجي وفقًا لمجال مشروعك وعدد أعضاء الفريق والمساهمين النشطين الذين يعملون معك؛ وكلما توسع مجتمعك، يمكنك توفير مساحات أكبر يتفاعل ضمنها المساهمون والمستخدمون والمشرفون. إليك بعض الخيارات التي قد تنظر في تطبيقها: ملفات توثيق ويكي، التي تقدم توثيقًا يُحفَظ في متناول المجتمع. منتديات لمناقشة الخصائص المحتمَلة والإجابة على الأسئلة. خادم قوائم بريدية للمشاركة المجتمعية المعتمدة على البريد الإلكتروني. ادرس قاعدة المستخدمين الأساسية لديك ومجال مشروعك (وهذا يشمل عدد الأشخاص الذين يعملون على الإشراف على المشروع والموارد المتاحة لديك) قبل نشر هذه المساحات المحتمَلة؛ واِسعَ للحصول على آراء مجتمعك حول ما يناسبهم؛ وقبل كل شيء، لا بد أن تكون لطيفًا وأن تُظهر بعض المودة في جميع تفاعلاتك مع مجتمعك. قد يصعب أن تتسم بالحلم عندما تؤدي دور المشرف، لكن ذلك سيؤتي ثماره على مشروعك في المستقبل. الخاتمة يؤدي المشرفون على المستودعات دورًا بالغ الأهمية ضمن المجتمع مفتوح المصدر العام، وعلى الرغم أن ذلك يتطلب استثمارًا ضخمًا وعملًا شاقًا، إلا أنه يكون غالبًا تجربةً مجزيةً تتيح لك النمو بصفتك مطورًا ومساهمًا، كما يمكن أن يساهم تأديتك لدور المشرف بودٍ ولطف مساهمةً كبيرةً في تطوير المشروع الذي تهتم به. ترجمة -وبتصرف- للمقال How To Maintain Open-Source Software Projects لصاحبته Lisa Tagliaferri اقرأ أيضًا الفرق بين البرمجيات الحرة ومفتوحة المصدر طرق التعريف بمشروعك مفتوح المصدر صيانة المشاريع مفتوحة المصدر كيف تساهم في مشاريع مفتوحة المصدر على Github
-
تُعد مساهمتك في المشاريع مفتوحة المصدر تجربةً مجزيةً، إذ تتمثل في سعيك لتحسين تجربة المستخدمين النهائيين أمثالك في استخدام البرامج؛ فعندما تقدم طلب سحب pull request، ستتطلب عملية المساهمة في مشروعٍ ما بعضًا من إعادة تأسيس تفريعات rebase الشيفرة البرمجية وإعادة صياغتها قبل قبولها، متبوعةً بعملية تنظيفٍ عامة لفروعك. سيدلك هذا الدرس التعليمي على بعض الخطوات التي تلي تقديمك طلب سحب إلى مشروع برنامجٍ مفتوح المصدر. المتطلبات الأساسية بما أن هذا الدرس التعليمي سيدلك على بعض الخطوات التي ستتخذها بعد تقديمك طلب السحب، فهذ يعني أن نظام غيت Git سيكون مثبتًا لديك مسبقًا، وأنك إما أنشأت طلب سحب أو تفكر في إنشائه. ألغى موقع غيت هَب GitHub الاستيثاق Authentication من خلال كلمة المرور في شهر تشرين الثاني من عام 2020. لذلك، حتى تتمكن من الوصول إلى مستودعات repositories موقع غيت هَب من خلال سطر الأوامر، فعليك إنشاء مفتاح الوصول الشخصي Personal Access Token -أو اختصارًا PAT-، أو إضافة معلومات مفتاح SSH العام public SSH key. لتتعلم أكثر عن المساهمة في المشاريع مفتوحة المصدر اقرأ هذه المقدمة، ولتعلُّم كيفية إنشاء طلبات سحب، اقرأ المقالة إنشاء طلب سحب على Github. إعادة تأسيس الشيفرة البرمجية وتنظيف التعليقات عندما تساهم في البرامج مفتوحة المصدر، قد تجد بعض التعارضات conflicts بين فروعك أو طلب السحب الذي قدمته، وبين الشيفرة البرمجية الأولية upstream. وقد ترد رسالة خطأ على الصدفة shell لديك كما في المثال التالي: CONFLICT (content): Merge conflict in your-file.py Automatic merge failed; fix conflicts and then commit the result. أو كما في الصورة التالية عندما تقدم طلب سحب على موقع غيت هَب: (تعارضات) يحدث هذا عندما يتأخر المشرفون maintainers في الإجابة على طلب السحب الذي قدمته، أو عندما يساهم الكثيرون في مشروعٍ ما بنفس الوقت، وعندما تواجه هذه المشكلة وأنت لا تزال ترغب في تقديم طلب السحب خاصتك، ستضطر إلى معالجة هذه التعارضات وإعادة تأسيس rebase الشيفرة البرمجية التي تعمل عليها. تتيح لنا عملية إعادة تأسيس التفريعات نقل الفروع بتغيير الإيداع commit المبنية عليه، لنتمكن بهذه الطريقة من إعادة تأسيس شيفراتها البرمجية وجعلها مبنيةً على أحدث إيداعات الفرع الرئيسي main. لذلك، يجب أن تنفذ إعادة تأسيس التفريعات بدقة، وتحرص على تنفيذ كامل العملية في الإيداعات والفروع الصحيحة. وسنستعرض لاحقًا استخدام الأمر git reflog، في حال حدوث خطأ. سننتقل إلى مجلد الشيفرة البرمجية، تمامًا كما فعلنا في المقال السابق: $ cd repository ومن ثم ينبغي عليك التأكُّد من أنك في الفرع الصحيح بالانتقال إليه من خلال استخدام الأمر git checkout: $ git checkout new-branch ثم نفذ الأمر git fetch للحصول على أحدث نسخةٍ أولية للشيفرة البرمجية: $ git fetch origin بمجرد الحصول على النسخة الأولية للمشروع، يمكنك تنظيف clean up التعليقات لديك، إما بدمجها squashing، أو بإعادة صياغة رسائل الإيداع خاصتك لتسهيل فهمها على مشرفي المشروع، ولكن قد لا يكون هذا ضروريًا إذا لم تنشئ رسائل إيداع صغيرة كثيرة. لبدء هذه العملية، ستنفِذ عملية إعادة تأسيس التفريعات التفاعلية المُستخدمة لتعديل رسائل إيداع سابقة، أو جمع عدة رسائل إيداع في رسالة واحدة، أو حذف أو التراجع عن رسائل إيداع لم تَعُد ضرورية؛ ولتنفيذ ذلك، علينا أن نتمكن من ذكر رسائل الإيداع التي أنشأناها، إما برقمها، أو بسلسلة المحارف التي تذكر أساس الفروع لدينا. لمعرفة عدد الإيداعات التي أنشأناها، يمكننا تفقُّد الرقم الإجمالي للإيداعات المُنشأة في المشروع من خلال الأمر التالي: $ git log وسيكون الخرج مشابهًا للخرج التالي: commit 46f196203a16b448bf86e0473246eda1d46d1273 Author: username-2 <email-2> Date: Mon Dec 14 07:32:45 2015 -0400 Commit details commit 66e506853b0366c87f4834bb6b39d941cd034fe3 Author: username1 <email-1> Date: Fri Nov 27 20:24:45 2015 -0500 Commit details يعرض السجل جميع الإيداعات المُنشأة في مستودع المشروع المحدد، لذلك ستُعرَض الإيداعات التي أنشأها آخرون إلى جانب الإيداعات التي أنشأتها أنت. وبالتالي، عندما يكون للمشاريع سجلًا حافلًا من الإيداعات التي أنشأها عدة مؤلفين، ستحتاج إلى تحديد نفسك على أنك مؤلفًا من خلال الأمر: $ git log --author=your-username سيتيح لك هذا المعامل عدَّ الالتزامات التي أنشأتها؛ فإذا كنت تعمل على عدة فروع، تستطيع إضافة branches[=<branch>]-- في نهاية الأمر لتظهر النتيجة حسب الفرع. والآن بعد أن عرفت عدد الإيداعات التي أنشأتها على الفرع الذي تريد إعادة تأسيسه، يمكنك تنفيذ الأمر git rebase كما يلي: $ git rebase -i HEAD~x تشير i- في هذا المثال إلى أن إعادة تأسيس التفريعات تفاعلية، و HEAD إلى أحدث إيداع في الفرع الرئيسي، بينما تشير x إلى عدد الإيداعات التي أنشأتها في فرعك منذ أن جلبته في البداية. لكن إذا كنت لا تعرف عدد الإيداعات التي أنشأتها في فرعك، عليك أن تعرف ما هو الإيداع الذي يمثِّل أساس الفرع خاصتك، من خلال تنفيذ الأمر التالي: $ git merge-base new-branch main وسيكون خرج هذا الأمر سلسلة محارف طويلة تُعرف باسم الإيداع المعمَّى Hash، كما يبدو في المثال التالي: 66e506853b0366c87f4834bb6b39d341cd094fe9 سنمرر الإيداع المعمَّى هذا إلى الأمر git rebase: $ git rebase -i 66e506853b0366c87f4834bb6b39d341cd094fe9 ستكون نتيجة كلا الأمرين السابقين فتح ملفٍ في محرر نصوص واجهة الأوامر يتضمن قائمةً بجميع الإيداعات في فرعك، ويمكنك الآن إما دمجها أو إعادة صياغتها. دمج الإيداعات تتمثل عملية دمج رسائل الإيداع بدمج أو جمع عدة إيداعات صغيرة في رسالة أكبر. ستجد بداية كل إيداع كلمة انتقاء "pick"، لذا سيبدو ملفك مشابهًا للملف التالي إذا كان لديك إيداعين: الملف "…username/repository/.git/rebase-merge/git-rebase-todo": pick a1f29a6 Adding a new feature pick 79c0e80 Here is another new feature # Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s)) ولدمج الإيداع، ينبغي عليك تبديل الكلمة "pick" بالكلمة "squash" في كل سطر من سطور الملف الموجود ضمن المسار "username/repository/.git/rebase-merge/git-rebase-todo…" باستثناء السطر الأول: pick a1f29a6 Adding a new feature squash 79c0e80 Here is another new feature يمكنك في هذه المرحلة حفظ الملف وإغلاقه، وهذا سيفتح ملفًا جديدًا يجمع بين جميع رسائل الإيداع لجميع الإيداعات، وتستطيع إعادة صياغة رسالة الإيداع على النحو الذي تراه مناسبًا، ثم حفظ الملف وإغلاقه. ستتلقى ملاحظةً بمجرد إغلاق الملف على النحو التالي: Successfully rebased and updated refs/heads/new-branch. لقد جمعت الآن جميع الإيداعات في إيداعٍ واحد بدمجها معًا. إعادة صياغة الإيداعات تُعد إعادة صياغة رسائل الإيداع رائعةً عند ملاحظتك خطًأ إملائيًا، أو عندما تدرك أنك تستخدم صياغةً مختلفةً في كل إيداع لديك. بمجرد أن تنفذ عملية إعادة تأسيس التفريعات التفاعلية باتباع الخطوات التي ذكرناها من خلال تنفيذ الأمر git rebase -i، سيُفتح ملفٌ مشابهٌ للملف في المسار "username/repository/.git/rebase-merge/git-rebase-todo…" على النحو التالي: pick a1f29a6 Adding a new feature pick 79c0e80 Here is another new feature # Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s)) بدِّل الكلمة "reword" بالكلمة "pick"، أي إعادة الصياغة في كل إيداع تريد إعادة صياغته، فمثلًا في الملف الموجود ضمن المسار "username/repository/.git/rebase-merge/git-rebase-todo…"، ستكون إعادة الصياغة على النحو التالي: pick a1f29a6 Adding a new feature reword 79c0e80 Adding a second new feature # Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s)) وبمجرد حفظ الملف وإغلاقه، سيظهر ملفٌ جديدٌ في محرر طرفيتك يعرض صياغة رسالة الإيداع المعدَّلة؛ وإذا أردت تعديل الملف مرةً أخرى، افعل ذلك قبل حفظ الملف وإغلاقه. تضمن هذه العملية أن تكون رسائل الإيداع نافعةً ومتسقةً. استكمال عملية إعادة تأسيس التفريعات عندما تجد عدد الإيداعات التي تنشئها ورسائل الإيداع المتعلقة بها مناسبًا، عليك استكمال إعادة تأسيس فرعك بناءً على أحدث نسخةٍ من الشيفرة البرمجية الأولية للمشروع، وذلك بتنفيذ هذا الأمر من دليل directory المستودع الخاص بك: $ git rebase origin/main سيبدأ نظام غيت في هذه المرحلة بإعادة تنفيذ إيداعاتك في أحدث نسخةٍ من الفرع الرئيسي؛ وفي حالة حدوث تعارضات في تلك العملية، سيوقفها غيت مؤقتًا ليطالبك بمعالجة تلك التعارضات قبل متابعة العملية؛ أما إذا لم يجد تعارضات، فسيرِد في الخرج ما يلي: Current branch new-branch is up to date. بعد معالجة التعارضات، نفِّذ الأمر: $ git rebase --continue إذ سيشير هذا الأمر إلى غيت بأنه يستطيع الآن متابعة إعادة تنفيذ إيداعاتك. إذا سبق ودمجت الإيداعات من خلال استخدام أمر squash، فستضطر إلى معالجة التعارضات مرةً واحدةً فقط. تحديث طلب السحب باستخدام الدفع القسري Force-Push عندما تجري إعادة تأسيس التفريعات، يتغير سجل الفرع الخاص بك، ولن تتمكن من استخدام الأمر get push لأن المسار المباشر قد عُدِّل، وسنضطر عوضًا عن ذلك استخدام force-- أو الراية f- لفرض دفع التغييرات، وهذا يبلغ غيت أنك على درايةٍ كاملة بالذي تدفعه. دعنا أولًا نتأكد من أن push.default الخاص بنا مضبوطٌ على simple (وهو الإعداد الافتراضي في الإصدار 2.0 وما بعده من نظام غيت) من خلال تنفيذ ما يلي لإعداده: $ git config --global push.default simple علينا أن نتأكد في هذه المرحلة أننا في الفرع الصحيح من خلال التحقُّق من الفرع الذي نعمل عليه على النحو التالي: $ git checkout new-branch Already on 'new-branch' . . . نستطيع حينها تنفيذ عملية الدفع القسري كما يلي: $ git push -f سيرد إليك الآن تعليقٌ عن التحديثات التي أجريتها إلى جانب رسالةٍ تشير إلى أن هذا التحديث كان forced update أي تحديثًا قسريًا، وأصبح طلب السحب الذي قدمته محدثًا الآن. استعادة الإيداعات الضائعة إذا أزلت في مرحلةٍ ما إيداعًا تحتاج فعلًا إلى دمجه مع مُجمَل المشروع، تستطيع استخدام الأمر git لاستعادة الإيداعات التي أزلتها من دون قصد. سنستخدم الأمر git reflog للبحث عن الإيداعات الناقصة، ثم ننشئ فرعًا جديدًا من ذلك الإيداع، إذ تشير كلمة Reflog إلى اختصارٍ لعبارة السجل المرجعي reference log، الذي يسجل آخر تحديثٍ للإيداعات في الفروع والمراجع الأخرى ضمن المستودع المحلي. سننفِّذ الأمر التالي من الدليل الحالي لمستودع الشيفرة البرمجية الذي نعمل فيه: $ git reflog وسيكون الخرج عند تنفيذ هذا الأمر مشابهًا للخرج التالي: 46f1962 HEAD@{0}: checkout: moving from branch-1 to new-branch 9370d03 HEAD@{1}: commit: code cleanups a1f29a6 HEAD@{2}: commit: brand new feature 38f2fc2 HEAD@{3}: commit: remove testing methods . . . ستعرف عند الاطلاع على رسائل الإيداع أيُّ الإيداعات التي أزلتها، وستجد سلسلة المحارف المتعلقة بها قبل معلومات HEAD@{x} في الجهة اليسارية من نافذة الطرفية. تستطيع الآن الاستفادة من تلك المعلومة وإنشاء فرعٍ جديدٍ من الإيداع المناسب: $ git checkout -b new-new-branch a1f29a6 أنشأنا في المثال السابق فرعًا جديدًا من ثالث إيداع حصلنا عليه في الخرج السابق، وهو الإيداع الذي بدأ تنفيذ وسم خاصية جديدة "brand new feature"، مُتمثِّل بسلسلة المحارف a1f29a6. يمكنك الآن المتابعة حسب ما تريد فعله، إما باتباع خطوات إعداد فرعك الواردة في المقال السابق المشار إليه سلفًا، أو العودة إلى جزئية إعادة تأسيس الشيفرة البرمجية وتنظيف التعليقات في المقال التعليمي الحالي لتتابع إعادة تأسيس الفرع الجديد. ما الذي تتوقع رؤيته في مراجعة الشيفرة البرمجية؟ عندما ترسل طلب سحب، تكون بحالة حوار مع المشروع العام، إذ يُعد إرسال طلب سحب بمثابة دعوة الآخرين لمناقشة عملك، تمامًا كما تناقش أنت مشروعًا عامًا وتشارك فيه. ولكي تجري نقاشًا ناجحًا، من المهم أن تكون قادرًا على توضيح سبب تقديمك طلب السحب من خلال رسائل الإيداع خاصتك، لذلك من الأفضل أن تكون دقيقًا وواضحًا قدر الإمكان. قد تكون مراجعة طلب السحب طويلةً ومفصلةً، وذلك حسب المشروع. ومن الأفضل أن تنظر إلى هذه العملية بأنها تجربةٌ تعليمية، وطريقةٌ نافعة لتحسين شيفرتك البرمجية، وجعل طلب السحب أفضل ومتوافقًا أكثر مع احتياجات مشروع البرنامج. كما يجب أن تتيح لك المراجعة إجراء التعديلات بنفسك متبعًا نصائح وتوجيهات المشرفين. سيحتفظ طلب السحب بسجلٍ لملاحظات المراجعين وأية تحديثات ومناقشات أجريتموها معًا، وقد تحتاج إلى إنشاء عدة إيداعات إضافية خلال هذه العملية قبل قبول طلب السحب، وهذا أمرٌ طبيعي تمامًا ويوفّر لك فرصةً جيدةً لتشارك في المراجعة بصفتك جزءًا من الفريق. سيكون الإشراف على طلب السحب الذي قدمته مستمرًا من خلال نظام غيت، وسيُحدَّث تلقائيًا طوال العملية طالما واصلت إضافة إيداعات إلى نفس الفرع وطبقتها على فرعك المشتق. عندما تنشر شيفرتك البرمجية ليراجعها أقرانك، لا يجب أن تشعر أبدًا أن المراجعة تتخذ منحًى شخصيًا، لذا احرص على قراءة ملفات "CONTRIBUTION.md" ذات الصلة أو مدونات قواعد السلوك. ومن الضروري أن تتأكد من توافق إيداعاتك مع الإرشادات المحددة ضمن المشروع؛ ولكن إذا بدأت تشعر بالاستياء، فقد لا يستحق المشروع الذي تعمل عليه مساهمتك. توجد العديد من المساحات الترحيبية في مجتمع البرامج مفتوحة المصدر، وبما أنك تتوقع أن يُنظَر إلى الشيفرة البرمجية التي تشاركها بعينٍ ناقدة، يجب أن تكون جميع الملاحظات التي تتلقاها مهنيةً ولبِقة. قبول طلب السحب وحذف فرعك يعني قبول طلب السحب الذي قدمته أنك نجحت في تقديم مساهمةٍ في مشروع برنامجٍ مفتوح المصدر، وستحتاج في هذه المرحلة إلى التفتيش عن التعديلات التي أجريتها في فرعك المشتق من خلال مستودعك المحلي، وهذا ما فعلته مسبقًا عندما نفَّذت عملية مزامنة فرعك المشتق من مقال طلبات السحب السابق. يمكنك فعل ذلك من خلال تنفيذ عدة أوامر في نافذة طرفيتك: $ git checkout main $ git pull --rebase origin main $ git push -f origin main عليك الآن تنظيف كلٍ من فروعك المحلية والبعيدة بحذف الفرع الذي أنشأته في كلا الموضعين لأنك لن تحتاج إليهما بعد الآن. لنحذف أولًا الفرع المحلي: $ git branch -d new-branch مهمة الراية d- المُضافة إلى أمر git branch هي حذف الفرع الذي سنذكره في هذا الأمر، والذي سميناه في مثالنا السابق "new-branch". ثم سنحذف الفرع البعيد على النحو التالي: $ git push origin --delete new-branch بعد أن حذفت الفروع، تكون قد نظفت المستودع وأصبحت التغييرات التي أجريتها الآن جزءًا من المستودع الرئيسي. ويجب ألا تنسى أن انتقال التغييرات التي أجريتها من خلال طلب السحب لتصبح جزءًا من المستودع الرئيسي، قد لا يعني أنها أصبحت متاحةً في الإصدارات العامة التي ينزِّلها المستخدم النهائي، إذ يجمِّع مشرفو البرنامج عمومًا عدة خصائص جديدة وإصلاحات معًا، ويطلقونها في إصدار عامٍ واحد. الخاتمة تناول هذا الدرس التعليمي بعض الخطوات التي قد تلي عملية تقديم طلب السحب إلى مستودع برنامجٍ مفتوح المصدر. تكون مساهمتك في المشاريع مفتوحة المصدر وانضمامك لمجموعة مطوري البرامج مفتوحة المصدر النشطين غالبًا تجربةً مجزيةً، إذ تساعد مساهماتك الدورية في برامجك المفضلة في جعلها قيمةً ونافعةً لمستخدميها. ترجمة -وبتصرف- للمقال How To Rebase and Update a Pull Request لصاحبته Lisa Tagliaferri. اقرأ أيضًا الفرق بين البرمجيات الحرة ومفتوحة المصدر طرق التعريف بمشروعك مفتوح المصدر صيانة المشاريع مفتوحة المصدر كيف تحول مستخدمي مشروعك مفتوح المصدر إلى مساهمين
-
نظام غيت Git هو نظام إدارة الإصدارات الموزعة distributed version الذي يسهّل إدارة المشاريع البرمجية المشتركة. تحتفظ العديد من المشاريع بملفاتها في مستودع غيت Git repository، كما جعلت مواقع، مثل غيت هَب GitHub مشاركة الشيفرة البرمجية والمساهمة فيها متاحةً ومفيدةً وفعالةً. تفيد المساهمات التي يقدمها مجتمع المطورين العام في تطوير المشاريع مفتوحة المصدر المستضافة في المستودعات من خلال طلبات السحب pull requests التي تطلب أن يقبل مشرف المشروع التعديلات التي أجريتها على مستودع شيفرته البرمجية. ستتعلم في هذا الدرس التعليمي خطوات تقديم طلب سحب إلى مستودع غيت من خلال واجهة الأوامر حتى تتمكن من المساهمة في المشاريع مفتوحة المصدر. يجب أن يكون نظام غيت مثبّتًا على جهازك المحلي، ويمكنك التحقق إذا كان مثبتًا على حاسوبك والخوض في عملية تثبيته على نظام التشغيل لديك من خلال الاطلاع على مقال كيف تساهم في المشاريع مفتوحة المصدر: ابدأ بتعلم نظام Git. كما تحتاج إلى إنشاء حساب على موقع غيت هَب، إذ تستطيع إنشاء حساب أو تسجيل الدخول على حسابك إذا سبق وأنشأته من خلال زيارة موقع غيت هَب github.com. ألغى موقع غيت هَب الاستيثاق authentication عن طريق كلمة المرور في بداية شهر تشرين الثاني من عام 2020، لذا ستحتاج إلى إنشاء رمز وصول شخصي access token، أو إضافة معلومات المفتاح العام للوصول عن طريق SSH حتى تتمكن من الوصول إلى مستودعات غيت هَب من خلال واجهة الأوامر. وأخيرًا، عليك أن تحدد المشروع البرمجي مفتوح المصدر الذي تريد المساهمة فيه. إنشاء نسخة عن المستودع إن المستودع repository، والذي يُشار إليه بكلمة ريبو أو repo هو المجلد الرئيسي للمشروع أساسًا، ويحتوي على جميع الملفات المتعلقة بالمشروع، مثل ملفات التوثيق documentation، كما يحتفظ بسجل التعديلات revision history لكل ملف. ويمكن أن يشترك أكثر من شخص في العمل على المستودعات على موقع غيت هَب، كما يمكن أن تكون عامةً أو مغلقة. حتى تعمل على مشروع مفتوح المصدر ستحتاج أولًا إلى إنشاء نسخة عن المستودع خاصةً بك؛ ولتنفيذ هذا اشتق fork المستودع، ثم استنسخه clone حتى يصبح لديك نسخةً محليةً فعالةً. اشتقاق المستودع لاشتقاق مستودع على موقع غيت هَب انتقل إلى رابط المشروع مفتوح المصدر الذي تريد المساهمة فيه على الموقع من خلال المتصفح لديك، إذ تشير روابط المستودعات على غيت هَب إلى كلٍ من اسم المستخدم المرتبط بمالك المستودع إضافةً إلى اسم المستودع؛ فمثلًا إذا مالك مستودع مشروع "cloud_haiku" هو مجتمع DigitalOcean، فسيكون رابط هذا المشروع على موقع غيت هَب على النحو التالي: https://github.com/do-community/cloud_haiku يشير do-community في هذا المثال إلى اسم المستخدم و cloud_haiku إلى اسم المستودع. بعد أن حددت المشروع الذي تريد المساهمة فيه، انتقل إلى الرابط الذي ستكون صيغته على النحو التالي: https://github.com/username/repository أو يمكنك البحث عنه في شريط بحث موقع غيت هَب. عندما تفتح الصفحة الرئيسية للمستودع، ستجد زر الاشتقاق Fork في زاوية الصفحة العليا على اليمين، وأسفل أيقونة المستخدم الخاص بك: (سهم وامض) عند الضغط على زر الاشتقاق لبدء عملية الاشتقاق، ستتلقى إشعارًا ضمن المتصفح لديك يفيد بأن المستودع الذي تشتقه قيد المعالجة: (الاشتقاق في غيت هَب) سينتقل المتصفح لديك إلى صفحةٍ مشابهة لصفحة المستودع السابقة عند الانتهاء من العملية، مع اختلافَين بسيطين يتمثلان بأنك سترى في الأعلى اسم المستخدم الخاص بك قبل اسم المستودع، كما ستجده قبل اسم المستودع في الرابط. إذًا سترى الآن في المثال الذي طرحناه your-username / cloud_haiku بدلًا عن do-community / cloud_haiku في أعلى الصفحة، حيث أن your-username هي اسم المستخدم الخاص بك، وسيكون الرابط الجديد على النحو التالي: https://github.com/your-username/cloud_haiku بعد اشتقاق المستودع، يمكنك البدء باستنساخه clone لتصبح لديك نسخةً محليةً فعالةً من الشيفرة الأساسية. استنساخ المستودع لإنشاء نسختك المحلية من المستودع الذي تريد المساهمة فيه، ابدأ بفتح الطرفية؛ إذ سنستخدم الأمر git clone إلى جانب الرابط الذي يشير إلى النسخة المشتقة من المستودع. سيكون هذا الرابط مشابهًا للرابط الذي ذكرناه سابقًا، إلا أن هذا الرابط سينتهي باللاحقة git.، وسيكون الرابط حسب مثالنا عن "cloud_haiku" على النحو التالي: https://github.com/your-username/cloud_haiku.git أو يمكنك نسخ الرابط باستخدام الزر الأخضر الشيفرة Code⤓ الموجود في صفحة مستودعك الذي اشتققته من صفحة المستودع الأصلية، وبمجرد الضغط على الزر ستتمكن من نسخ الرابط من خلال النقر على زر المجلد binder بجانب الرابط: (سهم يشير إلى زر المجلد في مربع الشيفرة) عندما نحصل على الرابط سنكون جاهزين لاستنساخ المستودع، ولتنفيذ ذلك سنجمّع أمر git clone مع رابط المستودع في موجه الأوامر في الطرفية على النحو التالي: git clone https://github.com/your-username/repository.git أصبح لدينا الآن نسخةً محليةً من الشيفرة البرمجية، لذا يمكننا الانتقال إلى إنشاء فرعٍ branch جديدٍ لنعمل ضمنه على الشيفرة البرمجية. إنشاء فرع جديد عندما تعمل على مشروع مبني على العمل التشاركي، سيكون لديك ولدى غيرك من المبرمجين المساهمين في المستودع أفكارًا مختلفةً لخصائصٍ جديدة أو حلولٍ لمشكلاتٍ معينة في نفس الوقت، إذ لن تستهلك بعض هذه الخصائص وقتًا في تطبيقها، بينما سيكون العمل على بعضها الآخر جارٍ؛ لذا من الضروري أن تنشئ فرعًا عن المستودع حتى تتمكن من إدارة سير العمل، وعزل شيفرتك البرمجية، والتحكم في تحديد الخصائص المُعتمَدة في الفرع الرئيسي للمستودع. يدعى الفرع الأولي primary من مستودع مشروع عادةً الفرع الرئيسي main. ومن أفضل الممارسات الشائعة أن تعد أي شيءٍ ضمن الفرع الرئيسي قابلًا للنشر ليستخدمه الآخرون متى شاؤوا. ملاحظة: حدَّث موقع غيت هَب المصطلحات التي يستخدمها ليشير إلى مستودعات الشيفرة البرمجية المصدرية الافتراضية بالمستودع الرئيسي main بدل المستودع الأساسي master؛ فإذا كان الموقع لديك ما زال يشير إلى الفرع الرئيسي بمصطلح master، يمكنك تحديثه إلى main بتغيير إعدادات الفرع الافتراضية. احرص على إنشاء الفرع الجديد من الفرع الرئيسي، كما عليك أن تختار اسمًا توصيفيًا لهذا الفرع؛ فبدلًا من تسميته "my-branch" سمّه "frontend-hook-migration" أي "تهجير-خطاف-الواجهة الأمامية"، أو fix-documentation-typos أي "تصحيح-التوثيق-الأخطاء الإملائية". لإنشاء فرعٍ على نافذة طرفيتنا، نبدأ بتغيير المجلد لنعمل ضمن مجلد المستودع، ونتأكد من استخدام الاسم الفعلي للمستودع، مثل "cloud_haiku" للانتقال إلى مجلده. cd repository ثم ننشئ فرعنا الجديد بواسطة الأمر git branch، لذلك احرص على تسميته تسميةً توصيفية كي يفهم الآخرون الذين يعملون على المشروع ما الذي تعمل عليه. git branch new-branch بعد أن أنشأنا فرعنا الجديد نستطيع الانتقال إليه لنتأكد أننا نعمل على ذلك الفرع من خلال تنفيذ الأمر git checkout على النحو التالي: git checkout new-branch سيرِد الخرج التالي عندما تدخل الأمر git checkout: Switched to branch 'new-branch' أو يمكنك اختصار الأمرين السابقين، وهما إنشاء فرع جديد والانتقال إليه، بواسطة الأمر التالي وإضافة الراية b-: git checkout -b new-branch إذا أردت العودة إلى الفرع الرئيسي أو main، استخدم الأمر checkout مع إدخال اسم الفرع الرئيسي: git checkout main يتيح لك الأمر checkout الانتقال بين عدة فروع، لذا تستطيع العمل على عدة خصائص بنفس الوقت. تستطيع حتى الآن تعديل ملفات موجودة أو إضافة ملفات جديدة إلى المشروع الموجود ضمن فرعك. إجراء التعديلات محليًا دعنا نبدأ بإنشاء ملف جديد وليكن اسمه "poetry.md" باستخدام محرّر النصوص الذي تفضله، وسنستخدم في مثالنا هذا محرر النصوص نانو nano: nano poetry.md أضف أي محتوًى إلى ملفك الجديد، فمثلًا نحن أضفنا الاسم "haiku" في هذا الملف: The taste Of rain —Why kneel? “The Taste of Rain” by Jack Kerouac بعد إدخال المحتوى الذي تريده، احفظ التعديلات وأغلق الملف؛ وإذا كنت تستخدم محرر النصوص نانو، يمكنك تنفيذ ذلك بالضغط على "CTRL + X"، ثم "y"، ثم "ENTER". بعد أن عدّلت ملفًا موجودًا أو أضفت ملفًا جديدًا إلى المشروع، يمكنك إضافته إلى مستودعك المحلي عن طريق تنفيذ الأمر git add على النحو التالي: git add filename.md بدِّل الآن filename.md باسم الملف poetry.md الذي أنشأته لإضافته إلى مستودعك المحلي: git add poetry.md سيؤكد لك هذا الأمر أن ملفك جاهزٌ للإضافة. وإذا كنت تريد أن تضيف جميع الملفات الموجودة في مجلد معين، يمكنك إدراجها من خلال الأمر . git add، إذ ستضيف النقطة أو الفاصلة جميع الملفات المعنية؛ وإذا أردت إضافة جميع التعديلات متضمنةً المجلدات الفرعية بصورةٍ متكررة، نفذ الأمر git add -A أو git add -all لإدراج جميع الملفات الجديدة. بعد إدراج ملفاتنا، يُفضَّل تسجيل التعديلات التي أجريناها في المستودع بتنفيذ الأمر git commit. تُعد رسالة الإيداع commit عنصرًا مهمًا في مساهمتك في الشيفرة البرمجية؛ فهي تساعد المساهمين الآخرين على فهم التعديلات التي أجريتها كاملةً، وسبب إجرائها، ومدى أهميتها، إضافةً إلى توفير سجلٍ تاريخي للتغييرات المُجراة على المشروع عامةً، لمساعدة المساهمين المستقبليين. إذا كانت الرسالة مقتضبةً، نستطيع تسجيلها بإضافة الراية m- ووضع الرسالة بين إشارتي اقتباس على النحو التالي: git commit -m "Added a new haiku in poetry.md file" أما إذا لم تكن التغييرات طفيفة، يفضَّل إضافة رسالة إيداع أطول، ليكون المساهمون الآخرون على درايةٍ بآخر مستجدات مساهماتنا. لتوضيح ذلك أنشئ ملفًا جديدًا آخر: nano more-poetry.md ثم أضف إليه بعض المحتوى ليكون الملف "more-poetry.md" على النحو التالي: The light of a candle Is transferred to another candle— Spring twilight “Lightning One Candle” by Yosa Buson بعد إضافة المحتوى إلى الملف، احفظ التعديلات وأغلقه؛ وإذا كنت تستخدم محرر النصوص نانو يمكنك تنفيذ ذلك بالضغط على "CTRL + X"، ثم "Y"، ثم "ENTER". ثم نفذ الأمر git add لإضافة الملف الجديد إلى إلى مستودعك المحلي: git add more-poetry.md إذا أردت إضافة رسالة إيداع أطول، نفِّذ الأمر git commit دون إضافة أية رايات لفتح محرر النصوص الافتراضي على نظام التشغيل لديك. git commit إذا أردت ضبط محرر النصوص الافتراضي لديك، نفِّذ الأمر git config وحدد نانو مثلًا ليكون المحرر الافتراضي: git config --global core.editor "nano" أو ليكن محرر النصوص فيم vim: git config --global core.editor "vim" وبعد تنفيذ الأمر، ستعرض نافذة الطرفية مستندًا جاهزًا لتعديله حسب محرر النصوص الافتراضي الذي تستخدمه، وسيبدو المستند مشابهًا للنموذج التالي: # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch new-branch # Your branch is up-to-date with 'origin/new-branch'. # # Changes to be committed: # modified: new-feature.py # أضف رسالة الإيداع إلى الملف النصي أسفل التعليقات الافتتاحية. لكتابة رسالة إيداع مفيدة، عليك أن تضيف في السطر الأول ملخصًا يتألف من حوالي 50 حرفًا، ثم أضِف تحته توصيفًا ينص على سبب إجرائك لهذا التعديل، وآلية عمل شيفرتك البرمجية، ومعلوماتٍ إضافية ستحدد سياقها وتوضِّحها للآخرين الذين سيراجعون عملك بعد دمجه، وقسِّم كل ما سبق إلى مقاطع مفهومة، وحاول قدر استطاعتك أن تكون رسالتك مفيدةً وتفاعليةً لتضمن أن يفهم مشرفو المشروع مساهمتك فهمًا تامًا. تعديلات الدفع push بعد أن تحفظ ملف رسالة الإيداع النصي وتغلقه، يمكنك التحقق من رسالة الإيداع التي ستخصِّصها غيت بتنفيذ الأمر التالي: git status وسيكون الخرج مشابهًا للنموذج التالي حسب التعديلات التي أجريتها: On branch new-branch nothing to commit, working tree clean تستطيع في هذه المرحلة تنفيذ الأمر git push لتطبيق التعديلات على الفرع الحالي لمستودعك المُشتَق: git push --set-upstream origin new-branch سيزودك هذا الأمر بخرجٍ يُعلمك بمسار التقدم، وسيبدو مثل النموذج التالي: Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 336 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/your-username/repository.git a1f29a6..79c0e80 new-branch -> new-branch Branch new-branch set up to track remote branch new-branch from origin. انتقل الآن إلى مستودعك المشتق على صفحة موقع غيت هَب وبدِّل إلى الفرع الذي طبقت عليه التعديلات لمشاهدتها ضمن المتصفح، إذ يمكنك في هذه المرحلة إنشاء طلب سحب إلى المستودع الأصلي؛ لكن إذا لم تفعل ذلك مسبقًا، يُستحسن أن تتأكد أن مستودعك المحلي محدَّثًا مع المستودع الأولي upstream. تحديث المستودع المحلي أثناء عملك على مشروع إلى جانب مساهمين آخرين، من المهم أن تبقي مستودعك المحلي محدثًا مع المشروع، فليس من مصلحتك أن تنشئ طلب سحب لشيفرةٍ برمجية ستسبب تعارضًا مع شيفراتٍ برمجية أخرى. ولتبقى نسخة الشيفرة البرمجية المحلية محدَّثةً، ستحتاج إلى مزامنة التعديلات. سنبدأ باستعراض ضبط مستودع بعيد remote للاشتقاق، ثم مزامنته. ضبط مستودع بعيد للاشتقاق تتيح لك المستودعات البعيدة Remote repositories المساهمة مع الآخرين على مشروع في غيت، إذ يُعَد كل مستودعٍ بعيد إصدارًا من إصدارات المشروع المُستضافة على الإنترنت، أو الموجودة على شبكةٍ يمكنك الوصول إليها. ويجب أن يتوفر لديك وصول إلى كل مستودع بعيد؛ إما بصلاحيات قراءة فقط، أو صلاحيات قراءة وكتابة، ويعتمد ذلك على صلاحيات المستخدم الخاص بك. تحتاج إلى ضبط مستودعٍ بعيدٍ مرجعي إلى المستودع الأولي حتى تتمكن من مزامنة التعديلات التي تجريها في المستودع المشتَق مع المستودع الأصلي الذي تعمل عليه، كما ينبغي عليك إعداد المستودع البعيد ليتزامن مع المستودع الأصلي مرةً واحدةً فقط. لنبدأ بالتحقق ما هي الخوادم البعيدة التي ضبطتها، إذ سيعرض الأمر git remote المستودعات البعيدة التي حدَّدتها مُسبقًا؛ لذا إذا استنسخت مستودعك كما فعلنا سابقًا، سترى المستودع الرئيسي origin repository على الأقل، وهو الاسم الافتراضي الذي تطلقه غيت للمجلد المستنسَخ. سنستخدم الأمر git remote إضافةً إلى الراية v عندما نكون ضمن مجلد المستودع في طرفيتنا لعرض الروابط التي خزَّنها غيت إضافةً إلى الأسماء المختصرة للمستودعات البعيدة ذات الصلة، مثل "origin": git remote -v سيبدو الخرج مشابهًا للنموذج التالي بما أننا استنسخنا مستودعًا: origin https://github.com/your-username/forked-repository.git (fetch) origin https://github.com/your-username/forked-repository.git (push) إذا أعددت أكثر من مستودع مسبقًا، سيزودك الأمر git remote -v بقائمةٍ تعرضها جميعًا. ثم سنحدد مستودعًا رئيسيًا بعيدًا جديد لنزامنه مع المستودع المُشتَق، وسيكون هذا المستودع بمثابة المستودع الأصلي الذي اشتقينا منه، وسننفِّذ ذلك بواسطة الأمر git remote add: git remote add upstream https://github.com/original-owner-username/original-repository.git تشير upstream في هذا المثال إلى الاسم المختصر المُسنَد إلى المستودع البعيد، بما أن "upstream" في مصطلحات غيت تشير إلى المستودع الذي استنسخنا منه؛ وإذا أردنا إضافة مؤشر بعيد remote pointer إلى مستودع أحد المساهمين، علينا تقديم اسم مستخدم ذلك المساهم، أو اسمًا مستعارًا مختصرًا للاسم المُختصر. للتحقق من إضافة مؤشرنا البعيد إلى المستودع الأولي كما ينبغي، استعن بالأمر git remote -v مجددًا من مجلد المستودع: git remote -v وسيكون الخرج: origin https://github.com/your-username/forked-repository.git (fetch) origin https://github.com/your-username/forked-repository.git (push) upstream https://github.com/original-owner-username/original-repository.git (fetch) upstream https://github.com/original-owner-username/original-repository.git (push) تستطيع الآن ذكر upstream في موجه الأوامر بدلًا من كتابة الرابط كاملًا، وأصبحت جاهزًا لمزامنة مستودعك المشتَق مع المستودع الأصلي. مزامنة المستودع المشتَق بعد ما ضبطنا مستودعًا بعيدًا يشير إلى المستودعين الأولي والأصلي على غيت هَب، أصبحنا جاهزين لمزامنة مستودعنا المشتق لنبقيه محدَّثًا، ولتحقيق ذلك سننفذ الأمر git fetch عندما نكون ضمن مجلد مستودعنا المحلي في الطرفية، ليجلب الفروع ورسائل الإيداع التابعة لها من المستودع الرئيسي. وبما أننا استخدمنا الاسم المختصر "upstream" للإشارة إلى المستودع الأولي، سنذكره في صيغة الأمر: git fetch upstream سيختلف الخرج الذي ستتلقاه على حسب كمية التعديلات المُجراة منذ اشتققنا المستودع، وقد يتضمن بعض الأسطر عن عدّ العناصر وضغطها وفك ضغطها، إذ سيبدو الخرج مشابهًا للنموذج التالي، لكنه قد يختلف حسب عدد الأفرع التي يتألف منها المشروع: From https://github.com/original-owner-username/original-repository * [new branch] main -> upstream/main ستُخزَّن الآن رسائل إيداع الفرع الرئيسي في فرعٍ محلي يُسمى "upstream/main". لننتقل إلى الفرع الرئيسي المحلي لمستودعنا: git checkout main Switched to branch 'main' سندمج الآن أية تعديلات أجريت في الفرع الرئيسي للمستودع الأصلي مع فرعنا الرئيسي المحلي، إذ سنصل إلى الفرع الرئيسي من خلال فرعنا الرئيسي/الأولي المحلي: git merge upstream/main سيتغير خرج هذا الأمر، لكنه سيبدأ بكلمة "updating" إذا أجريت تعديلات؛ أو "Already up-to-date" في حال عدم إجراء أية تعديلات منذ اشتقاق المستودع. أصبح الفرع الرئيسي للمستودع المشتَق متزامنًا مع المستودع الأولي، ولن تفقد أية تعديلات محلية تجريها. يمكنك تكرار مزامنة مستودعك المشتق مع الشيفرة البرمجية الأولية للمستودع الرئيسي بالقدر الذي تجده مناسبًا وذلك حسب سير عملك والوقت الذي تقضيه في إجراء التعديلات. لكن لا بُد من مزامنة مستودعك المشتق مباشرةً قبل أن تنشئ طلب سحب لتتأكد أنك لا تتسبب في تضارب الشيفرات البرمجية. إنشاء طلب سحب أصبحت في هذه المرحلة جاهزًا لإنشاء طلب سحب إلى المستودع الرئيسي. انتقل إلى مستودعك المشتق واضغط على زر طلب سحب جديد New pull request الموجود على الجانب اليساري من الصفحة. (زر طلب سحب جديد) تستطيع تعديل الفرع في الصفحة التالية، كما يمكنك اختيار المستودع والفرع الملائمَين في كلا الصفحتين من القائمة المنسدلة؛ فمثلًا عندما تختار الفرع الرئيسي من المستودع الأصلي الموجود في الجانب اليساري من الصفحة، والفرع الجديد new-branch من مستودعك المشتق الموجود على الجانب اليميني من الصفحة، ستظهر لك صفحةٌ تنص على أنك تستطيع دمج فروعك، إذا لم يوجد فيها شيفرةً برمجيةً متضاربة: (طلب سحب) أضِف عنوانًا وتعليقًا في الحقول المناسبة، ثم اضغط زر إنشاء طلب سحب Create pull request، وسيقرر المشرفون على المستودع الرئيسي في هذه المرحلة هل يقبلون طلب السحب الذي أنشأته أم لا، وقد يطلبون منك تعديل، أو تنقيح شيفرتك البرمجية قبل قبول طلب السحب. الخاتمة لقد نجحت في هذه المرحلة بإرسال طلب سحب إلى مستودع برنامج مفتوح المصدر. وعليك بعد ذلك أن تحرص على تحديث وإعادة تأسيس rebase شيفرتك البرمجية خلال فترة انتظارك مُراجعتها، واِستعد لإعادة صياغة شيفرتك البرمجية إذا طلب منك المشرفون على المشروع ذلك. قد تكون مساهمتك في المشاريع مفتوحة المصدر وارتقائك لتصبح مطورًا نشطًا للبرامج مفتوحة المصدر تجربةً مثمرةً؛ كما تتيح مساهماتك الدورية في برنامجٍ تعمل عليه باستمرار لك التأكُّد من تقديم هذا البرنامج للمستخدمين النهائيين بأمثل إصدار ممكن له. إذا كنت مهتمًا بتعلم المزيد عن نظام غيت والمساهمة في البرامج مفتوحة المصدر، فاطلع على سلسلة دروسنا التعليمية التي تحمل عنوان مقدمة عن البرامج مفتوحة المصدر، أما إذا كانت معرفتك لا بأس بها عن نظام غيت وترغب في الحصول على ورقة مرجعية عنه اطلع على المقالة كيف تستخدم نظام غيت: دليل مرجعي. ترجمة -وبتصرف- للمقال How To Create a Pull Request on GitHub لصاحبته Lisa Tagliaferri. اقرأ أيضًا كيف تساهم في مشاريع مفتوحة المصدر على Github أساسيات Git
-
تفيد المساهمات التي يقدمها مجتمع المطوّرين العام المشاريع مفتوحة المصدر المستضافة في المستودعات repositories العامة، وتُدار عادةً من خلال نظام غيت Git. غيت هو نظام التحكم بالإصدارات الموزع، وهو يساعد كلًا من الأفراد والفرق على المساهمة في المشاريع البرمجية مفتوحة المصدر وتنقيحها، ويُعد نظام غيت بحد ذاته نموذجًا عن المشاريع مفتوحة المصدر؛ فهو متاحٌ للتنزيل والاستخدام مجانًا. سنناقش في هذا الدرس التعليمي فوائد المساهمة في المشاريع مفتوحة المصدر، ونتحدث عن طريقة تثبيت نظام غيت وإعداده لتتمكن من المساهمة في المشاريع البرمجية. يُعد هذا المقال جزءًا من سلسلة مقالات حول "المساهمة في المشاريع مفتوحة المصدر": كيف تساهم في المشاريع مفتوحة المصدر: ابدأ بتعلم نظام Git إنشاء طلب سحب pull request على GitHub إعادة تأسيس طلب السحب وتحديثه الإشراف على مشاريع البرمجيات مفتوحة المصدر عبر GitHub تراخيص البرامج مفتوحة المصدر الدليل المرجعي للعمل على نظام Git المساهمة في المشاريع مفتوحة المصدر البرنامج مفتوح المصدر: هو البرنامج المُتاح استخدامه وإعادة توزيعه وتعديله مجانًا. تشجع المشاريع التي تتبع نموذج التطوير مفتوح المصدر على عملية تتسم بالشفافية وتحقق تقدمًا من خلال مراجعة النظراء الموزَّعة distributed peer review؛ ويمكن تحديث المشاريع مفتوحة المصدر بسرعة وحسب الطلب؛ كما أنها تقدِّم برنامجًا مرنًا وموثوقًا غير مبني على أنظمة مغلقة مسجَّلة الملكية. تساعد المساهمة في المشاريع مفتوحة المصدر على ضمان أن يكون إصدارها هو أفضل إصدار يمكن تقديمه، وأنها ممثلةٌ عن شريحةٍ واسعةٍ من مستخدمي التكنولوجيا النهائيين؛ إذ عندما يساهم المستخدمون النهائيون في الشيفرات البرمجية للمشاريع مفتوحة المصدر، أو توثيقها documentation، فستضيف وجهات نظرهم المتنوعة فائدةً تعود على المشروع والمستخدمين النهائيين ومجتمع المطورين العام. يُعد البدء بالمساهمة في برنامج تستخدمه أصلًا أفضل طريقة تبدأ بها في المساهمة في المشاريع مفتوحة المصدر؛ فعندما تستخدم أداةً معينةً، تكون مدركًا جيدًا للوظائف الأنفع للمشروع. وبالتالي، احرص على قراءة أي توثيق مُتاحٍ عن البرنامج أولًا، إذ ستجد ملف "CONTRIBUTING.md" عادةً في الملف الجذر root directory للعديد من المشاريع مفتوحة المصدر؛ وهو ملف ينبغي قراءته بدقة قبل المساهمة في أي مشروع، كما يُنصَح بتكوين فكرةٍ عن التفاعل بين المطوّرين الآخرين في هذه المنظومة، إذا وجدت منتديات متاحةً تتناول هذا المشروع. وأخيرًا، إذا كنت تخطو أول خطوةٍ في المساهمة في برنامج مفتوح المصدر، يستحسن أن تبدأ بتقديم مساهمات بسيطة، ولا تستخف بها؛ فكل مساهمة قيّمة مهما صغرت، ويمكنك أن تبدأ بتصحيح الأخطاء المطبعية، أو إضافة تعليقات، أو كتابة توثيق أوضح. نظام الإصدارات Git يُعد غيت أحد أكثر أنظمة إدارة إصدارات البرمجيات انتشارًا، وقد ابتُكر من قبل مبتكر نواة نظام التشغيل لينوكس لينوس تورفالدس Linus Torvalds عام 2005، إذ كان يُستخدَم في تطوير نواة نظام لينوكس، والمشرف الحالي عليه هو جونيو هامانو Junio Hamano. يحتفظ العديد من المشاريع بملفاتهم في مستودع repository غيت، كما نظمت مواقع، مثل غيت هَب GitHub وغيت لاب GitLab وبيت بَكيت Bitbucket عملية مشاركة الشيفرات البرمجية والمساهمة فيها. ويُعد كل مجلد عمل working directory في غيت مستودعًا متكاملًا، إضافةً إلى تقديمه تاريخًا وتتبعًا كاملًا بصرف النظر عن الوصول إلى الشبكة، أو الخادم المركزي. أصبحت إدارة الإصدارات أداةً لا غنى عنها في أسلوب تطوير البرامج المعاصر، لأن هذه الأنظمة تتيح لك متابعة البرنامج على مستوى المصدر، وستتمكن مع زملائك من فريق المطورين متابعة التعديلات والتراجع إلى المراحل السابقة وإصدار شيفرات فرعية عن الشيفرة البرمجية الأساسية لإنشاء إصدارات بديلة عن الملفات، أو المجلدات. تكمن فائدة نظام غيت على المشاريع مفتوحة المصدر في تنسيقه لمساهمات العديد من المطورين؛ إذ ينشئ كل مطور إصدارًا فرعيًا عن الفرع الأساسي للمستودع الرئيسي للشيفرة البرمجية، لعزل التعديلات التي طبَّقها، ثم ينشئ طلب سحب pull request لدمج هذه التعديلات في المشروع الرئيسي. حتى نستخدم نظام غيت للمساهمة في المشاريع مفتوحة المصدر، دعنا نتأكد أولًا إذا كان مثبتًا؛ وإذا لم يكن مثبتًا، دعنا نطلعك على كيفية تثبيته على جهازك المحلي. التحقق من تثبيت نظام غيت ابدأ بالتحقق إذا كانت أدوات واجهة أوامر غيت مثبتة على جهازك، إذ من المُرجح أن يكون نظام غيت مثبتًا مسبقًا على جهازك المحلي إذا كنت تنشئ مستودعات لشيفراتك البرمجية الخاصة، كما يكون نظام غيت مثبتًا افتراضيًا على بعض أنظمة التشغيل، لذا يفضَّل التحقق إذا كان مثبتًا قبل البدء بتثبيته. يمكنك التحقق ما إذا كان نظام غيت مثبتًا ومن إصداره الحالي بفتح نافذة طرفية terminal في نظامي التشغيل لينوكس أو ماك Mac، أو نافذة موجه الأوامر command prompt في نظام التشغيل ويندوز، وطباعة الأمر التالي: $ git --version إذا لم يكن نظام غيت مثبتًا، فسيرد خطأٌ مشابهٌ لما يلي: -bash: git: command not found 'git' is not recognized as an internal or external command, operable program, or batch file. وعليك في هذه الحالة تثبيت نظام غيت على جهازك، وسنستعرض في الفقرة التالية آلية التثبيت على أهم أنظمة التشغيل. تثبيت نظام غيت على نظام التشغيل لينكس إن أسهل طريقة لتثبيت نظام غيت وإعداده للعمل حتى الآن، هي استخدام الإصدار المتوفر لديك من مستودعات لينوكس الافتراضية. لنستعرض آلية تثبيت نظام غيت على نظام التشغيل لينوكس على جهازك المحلي من خلال اتباع هذه الطريقة: تثبيت نظام غيت على توزيعة أبونتو Ubuntu أو ديبيان Debian استخدم أداة APT لإدارة الحزم لتحديث دليل الحزم المحلي لديك، ثم يمكنك بعد ذلك تنزيل وتثبيت البرنامج: $ sudo apt update $ sudo apt install git بالرغم من أن هذه الطريقة هي الأسرع لتثبيت نظام غيت، قد لا يكون الإصدار المثبت من خلالها هو أحدث إصدار موجود؛ وإذا احتجت إلى تثبيت أحدث إصدار، جمّع نظام غيت من المصدر. تثبيت نظام غيت على توزيعة سينتوس CentOS سنستخدم yum؛ مدير الحزم الافتراضي في سينتوس للبحث عن أحدث حزمة غيت متوفرة في مستودعات سينتوس وتثبيتها. لنتحقق أولًا أن yum محدَّثة من خلال تنفيذ الأمر التالي: $ sudo yum -y update إذ تُستخدَم الراية y- لتنبيه النظام بأننا ندرك أنه ستجري تغييرات، فامنع الطرفية أن تطلب منا تأكيدها. يمكننا الآن المتابعة وتثبيت غيت: $ sudo yum install git بالرغم من أن هذه الطريقة هي الأسرع لتثبيت نظام غيت، قد لا يكون الإصدار المثبت من خلالها هو أحدث إصدار موجود؛ وإذا احتجت إلى تثبيت أحدث إصدار، جمّع نظام غيت من المصدر. تثبيت نظام غيت على توزيعة فيدورا Fedora إن حزم غيت متاحةٌ على توزيعة فيدورا من خلال مديري الحزم yum و dnf؛ إذ أن DNF أو دانديفايد يَم Dandified Yum استُحدث في إصدار فيدورا الثامن عشر، وأصبح مدير الحزم الافتراضي لتوزيعة فيدورا منذ إصدارها الثاني والعشرين. يمكننا تحديث مدير الحزم dnf وتثبيت نظام غيت من نافذة الطرفية على النحو التالي: $ sudo dnf update $ sudo dnf install git إذا كان إصدار فيدورا لديك أقدم، استخدم الأمر yum بدلًا عن ذلك. لنحدّث yum أولًا، ثم ثبِّت نظام غيت على النحو التالي: $ sudo yum update $ sudo yum install git ويمكنك بعد ذلك المتابعة إلى فقرة إعداد نظام غيت. تثبيت نظام غيت على نظام تشغيل ماك أو إس macOS إذا طبعت أمر Git على نافذة طرفيتك وعلى جهاز محلي مُثبّتٌ عليه نظام تشغيل ماكنتوش Macintosh، مثل الأمر git --version المذكور سابقًا، فستُوجَّه prompt إلى تثبيت نظام غيت، إذا لم يكن مثبتًا مسبقًا على جهازك؛ وعندما تتلقى هذا التوجيه يجب أن تقبل تثبيت غيت واتباع التعليمات والاستجابة للتوجيهات التي تظهر على نافذة طرفية جهازك. تستطيع تثبيت أحدث إصدار من نظام غيت على نظام ماك من خلال المثبت الثنائي binary installer. يحتفظ نظام أو إس إكس OS X بمثبت نظام غيت، وهو متاحٌ للتنزيل تلقائيًا عن طريق موقع غيت. بعد تثبيت نظام غيت بالكامل، يمكنك المتابعة إلى فقرة إعداد نظام غيت. تثبيت نظام غيت على نظام ويندوز الإصدار الرسمي لنظام غيت على نظام التشغيل ويندوز متاحٌ للتنزيل تلقائيًا عن طريق موقع غيت، كما يتوفر مشروع مفتوح المصدر يدعى نظام غيت للويندوز Git for Windows؛ وهو مستقل عن موقع غيت الرسمي، ويوفر أدواتٍ لكلٍ من واجهة الأوامر وواجهة المستخدم الرسومية من أجل استخدام غيت على نظام تشغيل ويندوز بفعالية. ويمكنك الاطلاع على موقع مشروع غيت على ويندوز لمزيدٍ من المعلومات عن هذا المشروع ومعاينة الشيفرة البرمجية وتنزيلها. بعد تثبيت نظام غيت بالكامل، يمكنك المتابعة إلى فقرة إعداد نظام غيت التالية. إعداد نظام غيت بعد تثبيت نظام غيت، ينبغي تنفيذ بعض الأمور الأخرى كي تتضمن رسائل الإيداع commit message التي ستتولد لك معلوماتك الصحيحة؛ وأسهل طريقة لتنفيذ ذلك من خلال الأمر git config، إذ لا بُد من تقديم اسمنا وبريدنا الإكتروني تحديدًا، لأن غيت يدمج هذه المعلومات في كل إيداع ننفذه. ولإضافة هذه المعلومات نكتب الأمر التالي: $ git config --global user.name "Your Name" $ git config --global user.email "youremail@domain.com" يمكننا الاطلاع على جميع عناصر الضبط المُعَدّة بكتابة الأمر التالي: $ git config --list وسيكون ضبط غيت على النحو التالي: user.name=Your Name user.email=youremail@domain.com من المُلاحظ اختلاف هذه الصياغة اختلافًا طفيفًا، فالمعلومات مخزنةٌ في ملف ضبط غيت الخاص بك، الذي تستطيع تعديله يدويًا إذا أردت بمحرر نصوص، مثل نانو nano على النحو التالي: $ nano ~/.gitconfig وستظهر لك محتويات الملف "gitconfig./~" المشابهة لما يلي: [user] name = Your Name email = youremail@domain.com عندما تنتهي من تعديل ملفك، اضغط مفتاحي "ctrl" و"x" للخروج من محرر النصوص نانو، وعندما ترد رسالة حفظ الملف اضغط على مفتاح "y". توجد العديد من الخيارات الأخرى الممكن ضبطها، لكن هذان الخياران هما الأساسيان اللذان ستحتاج إليهما لمنع ظهور رسائل تحذير في المستقبل. الخاتمة بعدما ثبّتَّ نظام غيت وأعددته على جهازك المحلي، أصبحت جاهزًا لاستخدامه في إدارة إصدارات مشاريعك البرمجية، إضافةً إلى المساهمة في المشاريع مفتوحة المصدر المُتاحة للجميع. تُعَد مساهمتك في البرامج مفتوحة المصدر طريقةً رائعةً للانخراط في مجتمع المطوّرين العام، والحرص على أن يكون البرنامج المُقدَّم للجميع مُتسمًا بالجودة العالية وممثلًا لكافة المستخدمين النهائيين. ترجمة -وبتصرف- للمقال How To Contribute to Open Source: Getting Started with Git لصاحبته Lisa Tagliaferri. اقرأ أيضًا صيانة المشاريع مفتوحة المصدر كيف تجعل الوصول إلى مشروعك مفتوح المصدر أسهل طرق التعريف بمشروعك مفتوح المصدر كيف تحول مستخدمي مشروعك مفتوح المصدر إلى مساهمين
-
تعد برمجة ووردبريس مهارة مفيدة جدًا لكن اكتسابها ليس بهذه البساطة، خاصةً إذا حاولت تناول المواضيع المتقدمة قبل التمكّن من الأساسيات. كُتِب هذا المقال ليعرفك على مبادئ عمل ووردبريس كنظام تقني. سيضعك هذا المقال على بداية طريقك في تعلم برمجة ووردبريس، وذلك لأننا سنبدأ معك من الأساسيات. 1. ما هو ووردبريس حتى تتعلم برمجة ووردبريس لا بد أن تفهم ما هو هذا النظام. ولم نجد أفضل من تشبيهه بمصنع لتقديم شرح شامل عن ماهيته ووظائفه من الناحية التقنية. لتكن نقطة انطلاقك في رحلة تعلم ووردبريس، معرفة ماهية نظام ووردبريس وبماذا يفيد، إذ نعلم أنه مبني على لغة البرمجة PHP وأنه نظام إدارة محتوى مفتوح المصدر، لكن ما هي وظيفته؟ لم نجد طريقةً لتعريفه أفضل من تشبيهه بالمصنع الذي يصنّع المواقع الإلكترونية، إذ يتلقى المواد الأولية من قاعدة البيانات ثم يعالجها في "خطوط الإنتاج" المختلفة - تبرمج نواة نظام ووردبريس نفسها بالإضافة إلى الشيفرات البرمجية التي تضاف إليها من القوالب والإضافات - ثم تتضافر جميعها لتنتج منتجًا نهائيًا جاهزًا ليرسَل إلى متصفح المستخدم. التعمق في أوجه الشبه بين نظام ووردبريس والمصنع فيما يلي نقدم تفاصيل إضافيةً توضح لك كيف تستفيد من تشبيه نظام ووردبريس بالمصنع في تعلم برمجة ووردبريس: إن بيئة العمل في مصنع ووردبريس هي الخادم، وهو حاسوب متصل بالإنترنت تخزَّن عليه كافة البيانات. (وإن الاشتراك بالاستضافة يعني حجز مساحة على هذا الخادم). يتلقى الخادم طلبات الإنتاج من العملاء - وهم المستخدمون الذين يطلبون المواقع عن طريق متصفحات الإنترنت - ومهمته تجميع منتج نهائي جاهز للعرض على متصفح المستخدم. إن المنشورات هي المواد الأولية الرئيسية المستخدمة في مصنع ووردبريس، وقاعدة البيانات من نوع MySQL هي المخزن في هذا المصنع (حيث تخزَّن هذه المواد الأولية). يستجيب نظام ووردبريس لطلب الإنتاج الذي يرده من المتصفح ("اجمع صفحة الموقع التي تقابل الرابط الذي طلبته كاملةً وأعد إرسالها")، يستدعي نظام ووردبريس المواد الأولية من قاعدة البيانات. يرسل نظام ووردبريس تلك المواد الأولية التي تشكل معظم الشيفرة البرمجية لنظام ووردبريس إلى خط التجميع في المصنع. التي تبني بدورها الأجزاء الداخلية لصفحة الموقع: أساسيات البيانات التي ستتضمنها صفحة الموقع وترتيب ظهورها. توجد خطوط تجميع خاصة للتحكم بطريقة عرض صفحات الموقع في نظام ووردبريس: كيف سيصمَّم المنتج ليعرَض على المستخدم (بغض النظر عن البيانات الأساسية التي يتكون منها). إن خطوط التجميع المعنية بمظهر صفحات المواقع هي ملفات قوالب مبينة على لغة البرمجة PHP تسمى قوالب ووردبريس wordpress themes. يستدعي المصنع متعهدين متخصصين خارجيين لتنفيذ مهام محددة، وهذا ما نسميه إضافات ووردبريس wordpress plugins، التي يمكنها التدخل في أية مرحلة من عملية التصنيع عن طريق نظام خُطافات ووردبريس hooks. يصدر المنتج النهائي بلغة HTML اللازمة لعرض صفحة الموقع، ثم يشحن المصنع هذا المنتج إلى متصفح المستخدم الذي أرسل الطلب في كل مرة تحمَّل فيها صفحة الموقع. اقرأ ما سبق بتمعن لفهم تفاصيل تشبيه نظام ووردبريس بالمصنع، فإذا استوعبت هذا التشبيه جيدًا سيتكون لديك تصور جيد استثنائي عن ماهية نظام ووردبريس، وهذه الخطوة الأولى الصحيحة لتعلم برمجة ووردبريس حتى قبل الاطلاع على الشيفرة البرمجية لهذا النظام. 2. طريقة البرمجة في نظام ووردبريس: اللغات البرمجية الأساسية الأربعة في ووردبريس إن الخطوة التالية في مسارك التدريبي في برمجة ووردبريس هي أن تعرف اللغات البرمجية التي ستستخدمها. سنقدم إليك أهم أربع لغات برمجية في ووردبريس، وهي: HTML و CSS وPHP وجافا سكريبت JavaScript، وسنوجز وظيفة كل منها. لن نتعمق في اللغات البرمجية، لكننا سنساعدك في اختيار اللغات البرمجية التي ستتعلمها ونعرفك على وظيفة كل منها. إليك اللغات البرمجية الأربعة المستخدمة في برمجة ووردبريس مرتبةً من الأهم: HTML: لغة برمجة المواقع، فهي لغة البرمجة التعريفية التي يترجمها متصفح المواقع بتحويل سلسلة من الرموز البرمجية إلى صفحة موقع واضحة تتضمن نصوصًا وصورًا وكافة محتويات الصفحة الأخرى. إذا لم تتعلم البرمجة بلغة HTML فلا بد أنك لن تستطيع التعمق في برمجة ووردبريس، لكن من ناحية أخرى ستستخدم لغة PHP معظم الوقت التي وظيفتها تحويل الشيفرة البرمجية فيها إلى لغة HTML بدلًا من البرمجة باستخدام لغة HTML مباشرةً. CSS: هي لغة البرمجة التعريفية التي تتحكم بمظهر صفحات الموقع، أي كيف ستبدو للمستخدم. تتحكم لغة CSS تقريبًا بكل النواحي المتعلقة بالمظهر، من الأحجام والهوامش والألوان والخطوط إلى أسلوب العرض المستجيب responsive لمختلف أنواع الأجهزة. عندما تريد أن تجعل الموقع على ووردبريس يبدو بمظهر معين، يبدأ عمل لغة CSS حيث تنتهي مهمة خصائص أدوات بناء الصفحة وخيارات القوالب. PHP: لغة البرمجة الأساسية في ووردبريس. هي اللغة الأساسية التي برمج بها نظام ووردبريس، وهي اللغة الأساسية لإضافات وقوالب ووردبريس، وهي أكثر لغة برمجة ستستخدمها بصفتك مبرمج ووردبريس. JavaScript: تستخدَم لبرمجة الواجهات الأمامية للموقع. هي لغة برمجية قوية تستخدم في مختلف النواحي، لكن المبرمج على ووردبريس يستخدمها غالبًا للتحكم بالجوانب الديناميكية من عرض الموقع التي تشمل التفاعلات المعقدة مع المستخدم الذي يتصفحه. بالرغم من أهميتها إلا أنك تستطيع إنجاز معظم عملك على ووردبريس بمعرفتك بالمبادئ الأساسية فقط منها، لذا ابدأ مسيرتك بتعلم اللغات البرمجية الثلاثة الأخرى أولًا، وقد حرصنا على توفير سلسلة عالية الجودة تشرح لغة جافاسكربت كاملة بعدد 90 درسًا تعليميًا بعنوان "دليل تعلم جافاسكربت" وهي ترجمة للقسم الأول من موقع javascript.info الشهير، ويمكنك البدء مع المقال الأول بعنوان "مقدمة إلى لغة جافاسكربت" وتابع تقدمك حتى الاحتراف. 3. كيف يتواصل ووردبريس مع متصفحك؟ مفهومي "من جهة المستخدم" ومن "جهة الخادم" في ووردبريس إن أحد أهم عوامل تعلم البرمجة على ووردبريس بسرعة الاستيعاب الجيد لمواضع تنفيذ العمليات في نظام ووردبريس، أيها تنفَّذ على حاسوب المستخدم ("من جهة المستخدم client-side") وأيها تنفذ على خادم الويب الذي يستضيف الموقع ("من جهة الخادم server-side"). إن فهمك لآلية تفاعل الخادم مع المستخدم في ووردبريس سيجيب على كثير من الأسئلة التي تراودك حول البرمجة في ووردبريس، مثل تساؤلك "هل يستطيع المستخدم الاطلاع على الشيفرة البرمجية التي أكتبها بلغة PHP؟". نذكرهما بإيجاز: العمليات التي تنفذ من جهة الخادم هي كل ما يجري على الخادم: هو الحاسوب المتصل بالإنترنت الذي تستضيف موقعك عليه (والذي تستأجره غالبًا من شركة استضافة مواقع). من أهم العمليات التي تنفَّذ من جهة الخادم: تخزين المعلومات في قاعدة بيانات MySQL التي تخزن معظم بيانات موقعك واستدعائها منها. كافة العمليات المرتبطة بلغة البرمجة PHP في ووردبريس: يعمل الخادم وفق النهج المنصوص عليه في آلاف ملفات ووردبريس المكتوبة بلغة PHP، إضافةً إلى ملفات PHP في إضافات ووردبريس وقوالبه. كل ما سبق ذكره ينفَّذ على الخادم، فالمتصفحات لا يمكنها قراءة الملفات المكتوبة بلغة PHP، فلا يعاد إرسال الملفات إلى المستخدم ليبني منها صفحة الموقع إلا بعد تحويلها إلى لغة HTML التي يفهمها المتصفح (إضافةً إلى ملفات جافاسكربت وCSS والقليل غيرها). العمليات التي تنفذ من جهة المستخدم تجري هذه العمليات في بيئة المستخدم: وهي الحاسوب (أو الهاتف المحمول أو أي جهاز آخر) الذي يرسل الطلبات إلى الخادم، ويحول ما يرد إليه من الخادم إلى صفحات تفاعلية وقابلة للعرض على المتصفح. من أهم العمليات التي تنفَّذ من جهة المستخدم: إرسال طلبات للحصول على موارد من صفحات HTML وصفحات تنسيق CSS وملفات جافا سكريبت بالإضافة إلى ملفات الصور وغيرها. استخراج ملفات HTML وCSS والصور وغيرها إلى صفحة موقع يفهمها المستخدم. التعامل مع كافة أنواع تفاعلات المستخدم من خلال نماذج forms HTML ومحددات العناصر الزائفة في pseudoselectors CSS وخاصةً من خلال جافا سكريبت. كلما تعلمت البرمجة في ووردبريس ستتعمق في فهم آلية التواصل المستمرة بين الخادم والعميل وكيفية تبادلهما البيانات. اقرأ المقالة الكاملة لمزيد من التفاصيل ورسم توضيحي مفصَّل. 4. المبادئ الأساسية في البرمجة على ووردبريس: نظام الخطافات في ووردبريس سترغب خلال تعلمك البرمجة على ووردبريس أن تفهم أساس نظام ووردبريس البرمجي الذي توجهه تفاعلات المستخدم event-driven: وهي خُطافات ووردبريس hooks التي تعرّف أيضًا بالإجراءات actions والمرشحات filters. أولًا عليك أن تعلم أن هذا الموضوع يصعب فهمه في البداية، فهو أكثر الأنظمة المستقلة إرباكًا لمتعلمها في ووردبريس بين الأنظمة التي يضطر المبرمج إلى التعامل معها يوميًا. باختصار، تتيح لك الخطافات الارتباط بأي جزء في نظام ووردبريس، فإن الخطافات في ووردبريس هي نوع محدد من دوال PHP التي تعني "أدرج أو عدل الشيفرة هنا". يمكنك "إضافة الخطافات" للارتباط بأي جزء من الدالات على ووردبريس وإدراج الشيفرة الخاص بك. نوعا الخطافات في ووردبريس: خطافات الإجراءات وخطافات المرشحات تتيح لك خطافات الإجراءات action إضافة خطاف للارتباط وتنفيذ أمر تحكمي مثل إضافة صفحة تنسيق CSS أو ملف جافا سكريبت أو تنفيذ أي شيفرة PHP تريده. أما خطافات المرشحات filters فتتيح لك إضافة خطاف للارتباط والتعديل مثل تعديل عنوان منشور معين قبل طباعته على صفحة الموقع. تمنحك المرشحات دومًا أمرًا تعمل عليه ثم تطلب منك تعديله وإعادة إرساله. لتتمكن من إضافة الشيفرة الخاصة بك إلى خطاف موجود مسبقًا في ووردبريس عليك كتابته بصيغة محددة. اكتب هذه الشيفرة على هيئة دالة تحتوي على نقاط ربط: وهي دالة "تربط" الشيفرة التي أضفتها. لإضافة خطافات الإجراءات نكتب دالات الإجراءات ثم نربطها من خلال دالة add_action() في ووردبريس. مثال على ذلك: add_action('wp_footer', 'wpshout_action_example'); function wpshout_action_example() { echo "WPShout was here."; } لإضافة خطافات المرشحات نكتب دالات المرشحات ثم نربطها من خلال دالة add_filter() في ووردبريس. مثال على ذلك: add_filter( 'the_title', 'wpshout_filter_example' ); function wpshout_filter_example( $title ) { return 'Hooked: ' . $title; } 5. برمجة قوالب ووردبريس أصبحت الآن مطلعًا على ماهية ووردبريس (أنه مصنع المواقع الإلكترونية) واللغات التي عليك تعلمها (أهمها PHP) وأين ينفَّذ كل نوع من العمليات على نظام ووردبريس (في جهة الخادم أو جهة المستخدم) والنظام الأساسي الذي توجهه تفاعلات المستخدم (الخطافات) والذي يربط كافة الجوانب ببعضها. يتطلب ذلك دورةً تدريبيةَ كاملةً تقدم لك مفاهيم تأسيسية مفتاحية لتعلم قوالب ووردبريس: هيكلية القوالب template hierarchy والحلقة loop ودالة functions.php، وهذا ما تقدمه دورة PHP من أكاديمية حسوب التي تشرح كيفية بناء قوالب ووردبريس من الصفر شرحًا تفصيليًا وبلغة عربية. صرت جاهزًا لتعلّم أساسيات برمجة قوالب ووردبريس، نرجو لك كل التوفيق ولا تتردد بمشاركتنا تجربتك في التعليقات. ترجمة -وبتصرف- للمقال Learn WordPress Development: The Basic Course لصاحبه Fred Meyer. اقرأ أيضًا تعلم البرمجة تطوير ووردبريس للمبتدئين: تعلم PHP ما الذي تحتاج معرفته قبل الشروع في التطوير على ووردبريس مقدمة إلى تطوير قوالب ووردبريس: تحويل صفحة HTML إلى قالب ووردبريس هل أنت جديد على عالم ووردبريس؟ إليك ما يجب عليك معرفته أوّلًا
-
توجد طابعتي في مكتبي، لكنني أعمل أحيانًا على حاسوبي المحمول في غرفة أخرى في المنزل. هذا لا يعد مشكلةً بالنسبة إلي لسببين: أولهما أنني نادرًا ما أطبع أي شيء على الورق وتمر أشهر دون أن أستعمل الطابعة. أما الثاني، أنني شاركت الطابعة على شبكة منزلي، لذا أستطيع إرسال ملف للطباعة من أي مكان في المنزل. لم ألجأ إلى استخدام أية تجهيزات خاصة لأحقق ذلك، اكتفيت فقط باستخدام نظام التشغيل لينوكس على حاسوبي و نظام الطباعة الشائع في يونيكس CUPS. تثبيت نظام الطباعة الشائع في يونيكس على نظام التشغيل لينوكس إذا كان نظام التشغيل على حاسوبك لينوكس أو BSD أو ماك أو إس macOS سيكون نظام CUPS منصبًا مسبقًا. كان نظام CUPS الحل المعتمَد مفتوح المصدر للطباعة على يونيكس منذ عام 1997. اعتمدت شركة أبل Apple عليه بدرجة كبيرة في نظام تشغيلها أو إس إكس OS X حديث العهد والمبني على يونيكس، وانتهى بها الأمر إلى شرائه في عام 2007 لتضمن الحصول على تطوير مستمر له وصيانته. إذا لم تجد نظام CUPS منصبًا على نظام تشغيل حاسوبك يمكنك تثبيته من مدير الحزم package manager. فإذا كان نظام التشغيل لديك فيدورا Fedora أو ماجيا Mageia أو سينتوس CentOS نفذ الأمر التالي: $ sudo dnf install cups أما إذا كان نظام التشغيل لديك ديبيان Debian ولينوكس مينت Linux Mint وما يشابهها، نفذ الأمر التالي: $ sudo apt install cups الوصول إلى نظام CUPS في نظامي التشغيل لينوكس وماك افتح متصفح المواقع وأدخل الرابط localhost:631، هذا يوجه حاسوبك إلى فتح أي شيء موجود عليه على هذا المنفذ (يشير حاسوبك إلى نفسه دائمًا بعبارة localhost). يفتح متصفحك صفحةً تتيح لك الوصول إلى إعدادات الطابعة على نظام التشغيل. تستطيع من هذه الصفحة إضافة الطابعات وتعديل الإعدادات الافتراضية للطابعة والتحكم بطلبات الطباعة التي تكون في وضع الانتظار والسماح بمشاركة الطابعات على شبكتك المحلية. (واجهة المستخدم في نظام CUPS) ضبط إعدادات الطابعة في نظام CUPS تستطيع إما إضافة طابعة جديدة أو تعديل طابعة موجودة ضمن واجهة نظام CUPS. لا تختلف صفحات إضافة طابعة جديدة عن صفحات تعديل طابعة موجودة مسبقًا سوى أنك عندما تضيف طابعةً تحدد خيارات جديدة، أما عندما تعدل طابعةً فإنك تعتمد أو تغير خيارات سبق تحديدها. ابدأ بالضغط على تبويبة Administration، ثم اضغط على زر Add Printer. إذا كنت تعدل طابعة موجودة اضغط على Manage Printers بدل ذلك، ثم اختر الطابعة التي تريد تعديلها، ثم اختر خيار Modify Printer من القائمة المنسدلة Administration. سواءً كنت تعدل طابعةً موجودةً أو تضيف طابعةً جديدةً، عليك إجراء ذلك بصلاحيات مدير النظام ليسمح لك نظام CUPS بالمتابعة. إما سجل الدخول بمستخدم root إذا أتيح لك ذلك، أو بمستخدمك الحالي إذا كانت لديك سماحية استخدام الأمرsudo. ستظهر بعدها قائمة تتضمن الواجهات والبروتوكولات التي تستخدمها للطابعة. إذا كانت طابعتك موصولةً مباشرةً إلى حاسوبك وكانت قيد التشغيل سيشار إليها في القائمة بعبارة Local Printer. إذا كانت طابعتك شبكيةً وموصولةً بمبدل switch أو موجه router على شبكتك، استخدم بروتوكول الطباعة عبر الإنترنت (Internet Printing Protocol اختصارًا IPP) للوصول إليها (قد تحتاج إلى الاطلاع على الإعدادات في الموجه لتحدد عنوان ip الطابعة، لكن اقرأ توثيق طابعتك لمعرفة التفاصيل). أما إذا كانت الطابعة من طراز HP يمكنك أيضًا استخدام بروتوكول HPLIP للوصول إليها. استخدم أي بروتوكول يناسب البيئة الفيزيائية لديك. إذا احترت في اختيار البروتوكول المناسب جرب أحد البروتوكولات، ثم حاول طباعة صفحة تجريبية، فإذا لم تنجح جرب استخدام بروتوكول آخر. تطلب الصفحة التالية إدخال تفاصيل بسيطة عن الطابعة، تكون غالبًا لتتمكن من الرجوع إليها. حدد اسمًا مقبولًا للطابعة (أضعه عادةً رقم الطراز لكن أحيانًا تسمي الشركات الكبرى طابعاتها على اسم سفن فضاء خيالية أو عواصم الدول)، ووصفًا عنها وموقعها. كما يمكنك أن تختار في هذه الصفحة أن تشارك طابعتك مع حواسيب أخرى موصولة على شبكتك. (واجهة مشاركة الطابعات في نظام CUPS) إذا لم تجد خيار المشاركة مفعلًا، فعّل مربع اختيار مشارَكة الطابعة. تعريفات الطابعة تتيح لك الصفحة التالية ضبط تعريف طابعتك. تجد تعريفات الطابعات مفتوحة المصدر غالبًا في موقع openprinting.org. في حال نصبت حزمة gutenprint أو نصبت حزمة التعريفات التي تأتي مع الطابعة، يوجد احتمال كبير أنك تملك التعريف المناسب على حاسوبك. إذا كانت طابعتك من نوع بوست سكريبت PostScript printer كحال معظم الطابعات الليزرية، لن تحتاج إلا إلى تحميل ملف PPD من موقع openprinting.org الذي سيغنيك عن تثبيت التعريف. بفرض أنك نصبت التعاريف، اختر طراز طابعتك (الشركة المصنِّعة) لتظهر لك قائمة بالتعريفات المتاحة لها، ثم اختر التعريف الملائم ثم تابع. الوصول إلى الطابعة المشارَكة بعد أن نجحت في تثبيت طابعتك وضبط إعداداتها تستطيع الوصول إليها من أي حاسوب على شبكتك. لنفترض أنك تريد أن تضيف طابعتك المشارَكة shared printer إلى حاسوبك المحمول المسمّى client الذي تستخدمه في مختلف أنحاء منزلك. يمكنك إضافة الطابعة على الحواسيب التي تستخدم بيئة سطح مكتب مثل جنوم GNOME وبلاسما Plasma من شاشة Printer في الإعدادات Settings: إذا كانت الطابعة موصولة على حاسوب أدخل عنوان IP هذا الحاسوب (لأنه يمكن الوصول إلى الطابعة من خلال مضيفها في هذه الحالة) إذا كانت الطابعة موصولة على موجه أو مبدل، أدخل عنوان IP الطابعة ذاتها. تجد إعدادات الطابعة على جهاز يعمل بنظام تشغيل ماك أو إس في تفضيلات النظام System Preferences. كما تستطيع أن تستخدم واجهة نظام CUPS على حاسوبك. لا تختلف عملية الوصول إلى نظام CUPS عليه: افتح شبكة ثم أدخل الرابط localhost:631. عندما تفتح واجهة ويب الخاصة بنظام CUPS اختر علامة التبويب Administration ثم اضغط على زر البحث عن طابعات جديدة Find New Printers في قسم الطابعات Printers، ثم أضف الطابعة المشتركة إلى شبكتك. كما تستطيع تحديد عنوان الطابعة IP يدويًا في نظام CUPS من خلال الخوض في عملية إضافة طابعة Add Printer المعتادة. اطبع أينما كنت لقد أصبحنا في القرن الحادي والعشرين! ضع سواقة USB جانبًا وتوقف عن إرسال الملفات إلى نفسك بالبريد الالكتروني من جهاز آخر، واجعل طابعتك متاحة في شبكتك المنزلية. ستدهشك سهولة تنفيذ ذلك وستسعدك الراحة التي سيوفرها لك، والأفضل من ذلك كله أنك ستبدو أمام جميع القاطنين في منزلك ساحر الشبكات المحترف. ترجمة -وبتصرف- للمقال Print from anywhere with CUPS on Linux لصاحبه Seth Kenlon. اقرأ أيضًا إعداد خادوم الطباعة CUPS على أوبنتو نصائح وحيل لاستخدام نظام CUPS للطباعة في لينكس
-
سواءً كنت مستخدما مبتدئًا أو مخضرمًا، نقدم إليك 20 أمرًا سيسهل عملك على نظام التشغيل لينوكس. قد يعد البعض طباعة الأوامر في طرفية Terminal سوداء أمرًا عفا عليه الزمن. لكن يختلف الحال بالنسبة للعديد من مستخدمي الحاسوب؛ إذ إن ذلك من أوضح الأساليب لتنفيذ أية مهمة يمكن أن يؤديها الحاسوب وأكثرها فعاليةً وأسهلها منالًا. في الآونة الأخيرة أصبحت طرفية الأوامر تناسب جميع المستخدمين ولم تعد تقتصر على مستخدمي نظامي لينوكس و BSD، وذلك بفضل المشاريع التي أتاحت أوامر الأنظمة مفتوحة المصدر إلى الأنظمة المحتكرَة مثل ماك أو إس macOS وويندوز. قد تدهشك معرفة وجود آلاف الأوامر المنصَّبة على حاسوب عادي نظام تشغيله يتوافق مع معايير POSIX، لكن بالطبع ليس الغرض من عدد لا بأس به من هذه الأوامر أن تستخدَم، على الأقل مباشرةً أو دوريًا. عمومًا إن بعض الأوامر مفيدة أكثر من غيرها، وحتى عدد أقل منها لا يمكن الاستغناء عنه عند استخدام الطرفية بأسلوب فعال. سنستعرض أبرز 20 أمرًا يلجأ مستخدمو الطرفية إلى استخدامه: أمر cd عندما تريد الانتقال من مجلد إلى آخر دون الاستعانة بالطرفية يكفي أن تنقر على أيقونته، أما في الطرفية نستخدم الأمر cd. إن cd اختصار لعبارة تغيير المجلد change directory، وهو وسيلة تنقلك بين مجلدات نظام التشغيل لينوكس، وهو أسرع سبل الانتقال من مكان إلى آخر وأقصرها. فمثلًا عندما تريد الانتقال من مجلدك الرئيسي home directory (حيث تحتفظ بجميع ملفاتك) على حاسوبك المكتبي إلى ملف اسمه presentations، عليك أن تفتح أولًا مجلد Documents، ثم تفتح مجلدًا اسمه work، ثم مجلد projects، وبعدها مجلد conference، ثم تفتح المجلد المنشود presentations الذي يحتوي على عرض الشرائح المبهر الذي صممته على برنامج من برامج ليبر أوفيس LibreOffice. لتنتقل إلى المجلد المطلوب نقرت الكثير من النقرات المزدوجة، وربما تجولت كثيرًا ضمن الشاشة حسب مكان ظهور النوافذ الجديدة التي تفتحها، وكبدت عقلك عناء تتبع مسار طويل. يتحايل العديد من المستخدمين على هذه المهمة البسيطة ظاهريًا بأن يحفظوا جميع ملفاتهم على سطح المكتب في أجهزتهم. أما مستخدمي الطرفية يتجنبون هذه المشكلة بطباعة السطر التالي: $ cd ~/Documents/work/projects/conference/presentations حتى أن مستخدمي الطرفية المخضرمين لا يتعبوا أنفسهم بطباعة كل هذا السطر، بل يستخدمون مفتاح Tab على لوحة مفاتيحهم ليكمل الكلمات تلقائيًا نيابةً عنهم. وفي بعض الأحيان ليس عليك أن تلجأ إلى الإكمال التلقائي حتى، إذ يمكنك استخدام محارف البدل wildcards عوضًا عن ذلك: $ cd ~/Doc*/work/*/conf*/p* أمر pwd سنعبر عن هذا الأمر بكلمات بوكارو بانزاي Buckaroo Banzai: "أينما ذهبت، ها أنت ذا". تستخدم أمر pwd عندما تريد أن تعرف في أي مجلد أنت بالتحديد. إن أمر pwd اختصار لعبارة اطبع المجلد الحالي print working directory وهذه هي مهمته. عند إضافة الوسيط physical-- (أو p- فقط في بعض التطبيقات) إلى الأمر يطبَع موقعك إضافةً إلى جميع الروابط اللينة التي عالجها. $ pwd /home/tux/presentation $ pwd --physical /home/tux/Documents/work/projects/conference/presentations لمزيد من التفاصيل حول الأمر pwd يمكنك الاطلاع على مقال كيف تستخدم أوامر cd و pwd و ls لاستكشاف نظام الملفات على نظام لينكس. أمر sed إن المحرر التدفقي stream editor الذي يعرف باسم sed هو أمر بحث واستبدال عام فعال، كما أنه محرر نصي معتمَد. إذا رغبت في التعمق في دراسة هذا الأمر اطلع على مقال استخدامات متقدمة للمحرِّر Sed في نظام لينكس ومقال أساسيات استخدام المحرر التدفقي Sed لتعديل النصوص في نظام لينكس. أمر grep إن استخدام أمر grep شائع جدًا. هو عنصر أساسي عند تحليل النصوص في shell الخاصة بك، سواءً كنت تبحث في ملفات السجل log files أو تحلل خرج بعض الأوامر الأخرى. إنه وسيلة المستخدم المنهمك في التركيز على معلومات محددة. بالنظر إلى كمية البيانات الضخمة في عالم الحوسبة، لا عجب أن يكون هذا الأمر رائجًا. في حال رغبت بالتوسُّع في دراسة هذا الأمر يمكنك الاطلاع على مقال ما الفروق بين الأوامر grep وegrep fgrep أمر file استخدم الأمر file عندما تحتاج إلى معرفة نوع البيانات ضمن ملف ما: $ file example.foo example.foo: RIFF (little-endian) data, Web/P image [...] $ file example.bar example.bar: ELF 64-bit LSB executable, x86-64 [...] لكن الأمر file ليس أداةً سحريةً طبعًا، فهو يعتمد في تحديد نتائجه على طريقة تعريف الملف لنفسه، علمًا أن الملفات قد تكون خاطئةً أو تالفةً أو مخفية. إذا أردت الحصول على نتائج أدق استخدم أداة hexdump، أما عند الاستخدام العادي فإن أمرfile يفي بالغرض. أمر awk إن Awk ليس مجرد أمر، بل هو حرفيًا لغة برمجية، إذا تعلمتها ستتمكن من كتابة نصوص برمجية scripts لم تكن لتتخيل أنك قادر على كتابتها. لتعلمها يمكنك زيارة مقالة كيفية استخدام لغة AWK للتعامل مع النصوص في لينكس والاطلاع على المحتوى الوارد حول هذا الأمر. أمر curl إن أمر curl هو متصفح مواقع غير تفاعلي على طرفيتك، فهو أداة برمجية للويب والواجهات البرمجية API. هو أمر معقد بسبب مرونته لكنه يستحق أن تتعلمه إذا أردت أن تتعامل مع خدمات الشبكة من خلال طرفيتك بسلاسة. أمر ps تتولى نواة نظام التشغيل لينوكس غالبًا إدارة موارد نظامك، لكن عندما تفضّل أو تضطر إلى معالجة أو تعديل شيء ما يدويًا يمكنك استخدام أمر ps. إذا رغبت في التعمق في دراسة هذا الأمر اطلع على مقالة إدارة العمليات (Process) في لينكس باستخدام الطرفية ومقالة مبادئ إدارة العمليات (Processes) على RedHat Enterprise Linux. أمر cat إن أمر cat اختصار لكلمة ضمّ concatenate، كان يفيد سابقًا في ضم الملفات التي جزّئَت (باستخدام أمر split) إلى عدة ملفات أصغر حجمًا بسبب محدودية الحجم. أما حاليًا صار يستخدم غالبًا لعرض محتويات الملف النصي على الطرفية للاطلاع السريع، أو يمكنك استخدام الأوامر head أو tail أوmore أو less لنفس الغرض. بالرغم من الانتقادات التي طالت مهمة الأمر cat الأساسية، ووجود عدة أوامر أخرى تؤدي مهمته الثانوية، إلا أنه لا يزال أداةً مفيدةً، فمثلًا قد يكون بديلًا لأمر النسخ (cp): $ cat myfile.ogg > /backups/myfile.ogg كما يكشف عن المحارف المضرة المخفية في الملفات، فمثلًا محرف Tab الذي يتلف الملفات المكتوبة بلغة YAML يرمّز بـ I^ عند إضافة خيار show-tabs-- إلى الأمر وفق ما يلي: $ cat --show-tabs my.yaml --- - hosts: all tasks: - name: Make sure the current version of 'sysstat' is installed. dnf: name: ^I- sysstat ^I- httpd ^I- mariadb-server state: latest أما عند إضافة الخيار show-nonprinting-- تظهر الأحرف غير المطبعية، وعند إضافة خيار show-ends-- تحدد نهايات الأسطر، وتحدد أرقام الأسطر بإضافة الخيار number--، وغيرها الكثير من الوظائف الأخرى. أمر find يساعدك الأمر find في البحث عن الملفات، وتمكنك خياراته المتعددة من تطبيق مرشحات ومعاملات بحث متنوعة خلال عملية البحث. وعندما تطلع على مرونة هذا الأمر لن تتساءل عن سبب غياب أهم الأوامر ls عن هذه القائمة، فإن الأمر find لا يمكنه إظهار الملفات في قائمة فحسب: $ find . ./bar.txt ./baz.xml ./foo.txt [...] بل يستطيع أيضًا أن يزودنا بقوائم مفصَّلة: $ find . -ls 3014803 464 -rw-rw-r-- 1 tux users 473385 Jul 26 07:25 ./foo.txt 3014837 900 -rwxrwxr-x 1 tux users 918217 Nov 6 2019 ./baz.xml 3026891 452 -rw-rw-r-- 1 tux users 461354 Aug 10 13:41 ./foo.txt [...] هذه تفاصيل ثانوية لكنها حيلة بارعة لا ضير في الاطلاع عليها. لا يزال أمامك الكثير لتتعلمه عن هذا الأمر، تجده في مقالة كيف تستخدِم أمرَي find و locate للبحث عن الملفّات على Linux. أمر tar يلقي الناس أحيانًا الدعابات حول أوامر نظام لينوكس مستشهدين بصياغة الأمر tar في نظام التشغيل BSD. لكن على الرغم من سمعته قد يصبح هذا الأمر بديهيًا جدًا. إذا رغبت بتعلمه يمكنك الاطلاع على مقال مقدمة إلى أمر tar في لينكس. أمر more أو less أو most تشبه أوامر الاستدعاء هذه الأمر cat، والفرق بينها أنها توقف خرجها مؤقتًا عند نهاية شاشتك إلى أن تنتقل للأسفل لمشاهدة المزيد. يسهل تطبيقها لكن يوجد فروق دقيقة بين كل منها عند تطبيقها؛ هل تنتقل للأعلى أو الأسفل باستخدام الأسهم في لوحة مفاتيحك أو باستخدام مفتاح المسافة؟ هل عليك الخروج يدويًا بعد انتهاء عرض الملف أم أن أمر الاستدعاء يخرج في نهاية الملف الذي يعرضه؟ ما هو أسلوبك المفضل في البحث؟ اختر أمر الاستدعاء المفضل لديك وضعه في النص البرمجي !bashrc.. أمر ssh و scp لا يساعدك برنامج OpenSSH في تأمين الاتصالات مع الأنظمة عن بعد فحسب، بل يفعّل أوامر أخرى أيضًا. فمثلًا إن مجلد .ssh هو من يتيح للعديد من المستخدمين التعامل بسلاسة مع مستودعات Git، ونشر تحديثات موقع، أو تسجيل الدخول إلى لوحة التحكم بسحابتهم cloud. لمزيد من التفاصيل حول الأمر ssh يمكنك الاطلاع على مقال أساسيات وخيارات الاتصال بخادوم عن بعد باستخدام SSH، أما مقال كيف تستخدم الأمر scp لتأمين نسخ الملفات بين الخواديم ستثري معلوماتك حول الأمر scp. أمر mv ينفذ هذا الأمر مهمتين: ينقل الملفات ويعيد تسميتها. يتضمن العديد من الخيارات الوقائية مثل خياري interactive-- و no-clobber-- لتجنب الكتابة على ملف موجود، ويضمن الأمر backup-- حفظ البيانات وعدم حذفها إلى أن يتأكد من انتقالها إلى موقعها الجديد، ويضمن الأمر update-- ألا تستبدل نسخة قديمة من الملف ملفًا أحدث منه. يمكنك زيارة مقال أساسيات إدارة الملفّات والتنقّل في لينكس لمزيد من التفاصيل. أمر sudo عندما يكون لديك مستخدم وحيد معروف اسمه user name ولديه صلاحيات كاملة على النظام، سرعان ما يصبح هذا المستخدم هدفًا للهجمات. يزيل الأمر sudo بأناقة معلومات مهمة عن نظام التشغيل من متناول العامة وذلك بإلغاء الحاجة إلى مستخدم جذر root بحد ذاته. ولا تقتصر وظيفته على ذلك فقط، فهو يتيح لك إدارة الصلاحيات بسهولة لكل أمر وللمستخدمين والمجموعات، كما يتيح لك تفعيل تنفيذ بعض الأوامر المختارة دون إدخال كلمة مرور، وتسجيل جلسات المستخدم، والتأكد من الأوامر بالتحقق من مجموعة قوانين، والكثير غير ذلك. إذا رغبت في التعمق في دراسة هذا الأمر اطلع على مقال ما قد لا تعرفه عن sudo أو مقال استخدام Sudo لتفويض الصلاحيات في Linux. أمر alias يتيح لك هذا الأمر تحويل الأوامر الطويلة إلى اختصارات يسهل حفظها: $ alias ls='ls --classify --almost-all --ignore-backups --color' يمكنك زيارة مقال مقدّمة إلى اختصارات الطرفية (Aliases) ودوالها للحصول على مزيد من التفاصيل حول هذا الأمر. أمر clear تزدحم طرفيك أحيانًا، ولا يضاهي شيء شاشةً جديدةً فارغةً تحصل عليها بعد طباعة clear (أو الضغط على ctrl+l في بعض shells). أمر setfacl عادةً يحدد الأمرين chown و chmod أذونات ملف POSIX، لكن مع زيادة تعقيد الأنظمة نحتاج إلى أمر يمنحنا مرونةً أكبر. يتيح لك الأمر setfacl إنشاء قائمة التحكم بالوصول Access Control List لتمنح الأذونات permissions للمستخدمين العشوائيين، وتضبط الأذونات الافتراضية للمجلدات وما تحتويه. أمر netcat هو أمر لا يحتاجه جميع المستخدمين، لكن القلة التي تستخدمه لا تستطيع الاستغناء عنه إطلاقًا. إن أمر nc هو أداة اتصال شبكية متعددة الاستخدامات. يمكنه الاتصال بمنفذ معين تمامًا مثل أمر telnet: $ nc -u 192.168.0.12 80 يمكنه تنفيذ أمر ping على منفذ معين، تمامًا مثل أمر ping : $ nc -zvn 192.168.0.12 25 يمكنه تقصي المنافذ المفتوحة تمامًا مثل أمر nmap : $ nc -zv 192.168.0.12 25-80 وهذا نموذج بسيط عن وظائفه. أوامرك أنت إن إحدى أهداف تصميم طرفية نظام التشغيل لينوكس هي ابتكار حلول للمشكلات، فعندما تتعلم الأوامر أنت تتعلم أيضًا بناء كتل يمكنك استخدامها لإنشاء أوامرك الخاصة. إن العديد من الأوامر المحفوظة في سجل الصدفة الخاص بي shell history هي نصوص برمجية على الصدفة shell كتبتها بنفسي، ليكون مسار عملي متوافقًا مع أسلوبي في العمل. فيمكن أن تكون الأوامر الرئيسية في shell لديك هي ذاتها التي صممتها أنت لتحقق الكفاءة والراحة خلال عملك. لذا امض بعض الوقت في تعلم بعض الأوامر الرائعة ثم ابنِ أوامرك الخاصة، وعندما تجد أوامر فعالةً اجعلها مفتوحة المصدر لتشارك أفكارك مع الجميع. ترجمة -وبتصرف- للمقال 20 essential Linux commands for every user لصاحبه Seth Kenlon اقرأ أيضًا عشرون أمرا في لينكس يفترض أن يعرفها كل مدير نظم دليل استخدام الأمر grep في لينكس دليل الربط الشبكي في ترميز CIDR وضبطه في لينكس
-
أصبحت الحاويات Containers جزءًا رئيسيًا من عمليات تكنولوجيا المعلومات. تحتوي صورة الحاوية container image على تطبيق جاهز packaged application إضافةً إلى اعتمادياتها dependencies ومعلومات حول الخدمات التي تشغلها عند إقلاعها. يمكنك إنشاء صور الحاويات عن طريق تحديد مجموعة من الأوامر المصاغة بطريقة خاصة، إما بإيداعها في سجل أو كملف دوكر Dockerfile. على سبيل المثال: ينشئ ملف دوكر أدناه حاويةً تتضمن تطبيق ويب مبني بلغة PHP: FROM registry.access.redhat.com/ubi8/ubi:8.1 RUN yum --disableplugin=subscription-manager -y module enable php:7.3 \ && yum --disableplugin=subscription-manager -y install httpd php \ && yum --disableplugin=subscription-manager clean all ADD index.php /var/www/html RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \ && sed -i 's/listen.acl_users = apache,nginx/listen.acl_users =/' /etc/php-fpm.d/www.conf \ && mkdir /run/php-fpm \ && chgrp -R 0 /var/log/httpd /var/run/httpd /run/php-fpm \ && chmod -R g=u /var/log/httpd /var/run/httpd /run/php-fpm EXPOSE 8080 USER 1001 CMD php-fpm & httpd -D FOREGROUND يضيف كل أمر في هذا الملف طبقةً إلى صورة الحاوية، وتضيف كل طبقة الاختلافات عن الطبقات التي تسبقها فقط، ثم تتكدس هذه الطبقات معًا لتشكل صورة حاوية قابلة للقراءة فقط. آلية تنفيذ تلك الخطوات عليك أن تتعلم بعض المفاهيم عن صورة الحاوية، ومن الضروري أن تفهمها وفق الترتيب التالي: أنظمة الملفات الموحدة UnionFS. النسخ عند الكتابة أنظمة ملفات أوفرلاي Overlay اللاقطات Snapshotters أنظمة ملفات يونيون Aufs يكون نظام ملفات يونيون UnionFS مدمج في نواة نظام لينوكس. يسمح بدمج محتويات نظام ملفات مع محتويات نظام ملفات آخر مع إبقاء محتواهما "الفيزيائي" منفصلًا، لينتج نظام ملفات موحَّد رغم أن البيانات منظَّمة فعليًا في فروع. إن الغاية منها هي في حال كان لديك عدة صور تحتوي على بعض البيانات المتطابقة، تشارَك هذه البيانات بين الصور باستخدام ما يسمى الطبقة، بدل أن تنسَخ عدة مرات. نظام ملفات يونيون تكون كل طبقة عبارة عن نظام ملفات يمكن مشاركته بين حاويات متعددة، فمثلًا الطبقة الأساسية base layer لخدمة httpd هي الصورة الرسمية لخادم الويب أباتشي Apache ويمكن لأي عدد من الحاويات أن تستخدمها. سيوفر ذلك كثيرًا من مساحة القرص الصلب لأننا نستخدم نفس الطبقة الأساسية في جميع الحاويات. تكون طبقات هذه الصورة قابلة للقراءة فقط، لكن عندما ننشئ حاويةً جديدةً من هذه الصورة نضيف طبقةً رقيقةً قابلةً للكتابة فوقها. يمكنك في هذه الطبقة القابلة للكتابة إنشاء/تعديل/حذف أو إجراء أية تغييرات لازمة لكل حاوية على حدة. النسخ عند الكتابة عندما تشغل حاويةً يبدو لك بأن للحاوية نظام ملفات كامل خاص بها، أي أن كل حاوية تشغلها على نظام التشغيل يخصَّص لها نسخة من نظام الملفات. لكن ألن يستهلك ذلك مساحةً كبيرةً من القرص الصلب ويطيل مدة إقلاع الحاوية؟ لا، وذلك لعدم احتياج كل حاوية إلى نسخة نظام ملفات خاصة بها! تعمل الحاويات والصور بآلية النسخ عند الكتابة لتحقيق ذلك، فبدلًا من نسخ الملفات تشارك استراتيجية النسخ عند الكتابة Copy-on-write نسخة البيانات ذاتها مع عدة عمليات، ولا تنسخها إلا عندما تحتاج إحدى هذه العمليات إلى تعديل أو كتابة البيانات. قبل أن تنفَّذ أية عملية كتابة ضمن حاوية قيد التشغيل، توضع نسخة من الملف الذي سيعدَّل عليه على الطبقة القابلة للكتابة في هذه الحاوية. هنا تجري عملية الكتابة ولهذا تسمى بآلية النسخ عند الكتابة. تحقق هذه الاستراتيجية أقصى استفادة من مساحة القرص الصلب ومن أداء مدة إقلاع الحاوية، وتعمل بالتزامن مع نظام ملفات يونيون. أنظمة ملفات أوفرلاي Overlay يتوضّع نظام ملفات أوفرلاي فوق نظام ملفات موجود مسبقًا، ويجمع بين شجرة المجلدات الأعلى والأدنى، ويقدمها بأنها مجلد واحد، وتسمى هذه المجلدات طبقات. تبقى الطبقة الأدنى دون تعديل، ولا تضيف كل طبقة إلا الاختلافات (يطلق عليها في مصطلحات الحوسبة اختصارًا diff) عن الطبقة الأدنى منها، ويشار إلى عملية التوحيد هذه بالوصل الموحد union mount. يطلَق على أدنى مجلد أو طبقة الصورة lowerdir، أما المجلد الأعلى يدعى upperdir. أما آخر طبقة مركبة overlayed أو موحدة unified تدعى مدمَجة merged. نظام الملفات متعدد الطبقات تتضمن المصطلحات الموحّدة تعاريف الطبقات التالية: الطبقة الأساسية Base layer: توجد فيها ملفات نظام ملفاتك، وبالنسبة لصور الحاويات ستكون هذه الطبقة الصورة الأساسية لديك base image. الطبقة المركّبة Overlay layer: تدعى غالبًا طبقة الحاوية لأن كل التغييرات التي تجري على الحاوية قيد التشغيل مثل إضافة ملفات أو حذفها أو تعديلها تكتَب على هذه الطبقة القابلة للكتابة. تخزن كافة التغييرات التي أجريت على هذه الطبقة على الطبقة التي تليها، وهي المنظور الموحَّد للطبقة الأساسية وطبقة الاختلافات. طبقة الاختلافات Diff layer: تحتوي على كافة التغييرات التي أجريت في الطبقة المركبة. فإذا كتبت شيئًا موجودًا مسبقًا في الطبقة الأساسية ينسخ نظام ملفات أوفرلاي الملف إلى طبقة الاختلافات ويجري التعديلات التي أردت كتابتها، وهذا ما يدعى بالنسخ عند الكتابة. اللاقطات تستطيع الحاويات إجراء التغييرات وإدارتها وتعميمها بأنها جزء من نظام ملفاتها باستخدام الطبقات وبرامج المخططات graph drivers، لكن العمل على برامج المخططات معقد ويحتمَل ظهور أخطاء فيه. تختلف اللاقطات SnapShotters عن برامج المخططات لأنها لا تكون على دراية بالصور أو الحاويات. تشابه طريقة عمل اللاقطات طريقة عمل Git في نواحٍ مثل مفهوم الأشجار وتتبع التغيرات على الأشجار لكل إيداع commit. تمثل اللقطة snapshot حالة نظام الملفات. تتضمن اللاقطات علاقات من نوع أب-ابن باستخدام مجموعة من المجلدات. تتخذ الاختلافات diff مكانها بين أب ولقطته لإنشاء طبقة. توفر اللاقطات واجهة برمجية API لتخصيص وتحميل وإجراء لقطة لأنظمة الملفات التجريدية متعددة الطبقات. الخاتمة تكونت لديك الآن فكرة جيدة عن ماهية صور الحاويات، وكيف يجعل نهجها متعدد الطبقات الحاويات قابلة للنقل. ترجمة -وبتصرف- للمقال ?What is a container image لصاحبه Nived V اقرأ أيضًا تعرف على Docker نظرة عامّة على إعداد الحاويّات containerization على Docker التعامل مع حاويات Docker
-
تعد مراقبة الموارد التكنولوجية IT assets مهمة أساسية لأي قسم تكنولوجيا معلومات، لكن العدد المتزايد من الأجهزة المتصلة بشبكات الشركات الكبرى جعل مهمة البحث عن نهج مرن لمراقبة مختلَف الأنظمة مراقبةً محكمةً مهمةً شديدة التعقيد، لذا لا بد من وجود أداة مراقبة مرنة وقابلة للتوسيع وسهلة الاستخدام. سأوضح لك في هذه المقالة كيف تثبت أداة المراقبة Checkmk المقدَّمة من شركة tribe29، وكيف تستفيد منها في مراقبة الخوادم وتجهيزات الشبكة. تثبيت أداة Checkmk على نظام التشغيل لينوكس استخدمت في هذه المقالة نسخة Checkmk Raw Edition والمرخصة برخصة جنو العمومية الإصدار الثاني community GPLv2 edition (يتضمن إصدار الشركات enterprise edition من هذه الأداة خصائص إضافيةً ويوفر دعمًا مدفوعًا)، وثبتها على خادم لينوكس. تعمل أداة Checkmk على معظم توزيعات نظام التشغيل لينوكس مثل توزيعات ريدهات RHEL وسينتوس CentOS وديبيان Debian وغيرها، كما تعمل على الحاوية container أو كأداة افتراضية virtual appliance. يمكنك تحميل أحدث إصدار لأداة Checkmk لجميع المنصات من الموقع الرسمي Checkmk website. الشروع في العمل لن يستغرق الشروع في العمل وقتًا طويلًا لأن أداة Checkmk تدعم معظم حالات المراقبة بفضل إضافاتها plug-ins التي يقارب عددها 2000 إضافة. كما توفر عتبات thresholds معدَّة مسبقًا للتنبيهات والتحذيرات كي لا تضيع وقتك في إعدادها بنفسك، أو يمكنك بالطبع ضبطها وفق ما يناسبك. إضافةً إلى هذه التجميعات الرسمية، تستطيع أيضًا استخدام توسيعات المراقبة التي أنشأها مستخدمون آخرون وشاركوها على منصة Checkmk Exchange. يمكنك معرفة المزيد من التفاصيل حول أداة Checkmk أو المساهمة فيها على مستودعات جت هَب GitHub repository. لا تتطلب هذه المقالة التعليمية أية خبرة سابقة في المراقبة. لكن إذا أردت اتباع الإجراءات يجب أن تكون لديك صلاحيات المستخدم الجذر root على الخادم الذي ستستخدمه مضيفًا. تنزيل نسخة Checkmk Raw Edition أولًا، إما نزّل نسخة Checkmk Raw Edition (المجانية ومفتوحة المصدر)، أو الإصدار المجاني من نسخة Enterprise Edition. ثانيًا، ثم أرسل ملف التثبيت إلى الخادم الذي تريد استضافة الأداة Checkmk عليه. أستخدم لتنفيذ ذلك أمر scp، وسيكون عنواني في هذه المقالة 10.0.2.15. $ scp check-mk-raw-X.Y.Zp8_0.focal_amd64.deb tux@10.0.2.15:/tmp ستنفَّذ جميع الإجراءات التالية في هذه المقالة التعليمية على الخادم المضيف. ثالثًا، سجل الدخول إلى الخادم المضيف باستخدام أمر ssh. $ ssh tux@10.0.2.15 ثبت حزمة Checkmk عليك الآن تثبيت الحزمة متضنةً جميع مستودعاتها dependencies من خلال مدير الحزم في توزيعة نظام التشغيل لديك مثل apt أو dnf: $ sudo apt install /tmp/check-mk-raw-X.Y.Zp8_0.focal_amd64.deb بعد اكتمال عملية التثبيت اجرِِ اختبارًا بتنفيذ الأمر omd: $ omd version إن الأمر omd هو اختصار لعبارة توزيعة المراقبة المفتوحة Open Monitoring Distribution وهو مشروع مفتوح المصدر أنشأه ماثياس كيتنر مبتكر أداة Checkmk، يساعدك في تثبيت أداة مراقبة مجمَّعة من مكونات متنوعة مفتوحة المصدر. إنشاء موقع مراقبة Checkmk تعد الخطوة التالية هي إنشاء موقع مراقبة أولي ("الموقع" هو نسخة instance). نفذ الأمر omd create لإنشاء موقع Checkmk جديد وسمه ما شئت. سأسميه في هذا المثال checkmk_demo. $ sudo omd create checkmk_demo ستتلقى في الرد معلومات مساعِدة عن طريقة إنشاء موقع Checkmk والوصول إليه. اتبع الخطوات لتغيير كلمة المرور الآن لكنني أفضل أن أغيرها في واجهة الويب الخاصة بأداة Checkmk. لذا حاليًا انسخ كلمة المرور المولَّدة عشوائيًا (ستستخدمها في الخطوات التالية) وشغّل موقع المراقبة الخاص بك: $ sudo omd start checkmk_demo ينبغي أن تتعمق في أداة Checkmk لاحقًا، فمن المهم أن تفهم ما حدث توًا. أنشأتَ مستخدمًا جديدًا يعرَف باسم site user، ومجموعةً بنفس اسم الموقع على خادمك. أنشِئ مجلد للموقع في المسار /omd/sites (مثل /omd/sites/checkmk_demo). كما تنسخ أداة Checkmk إعداداتها الافتراضية إلى المجلد الجديد. أنشِئ مستخدم باسم cmkadmin لواجهة الويب لأداة Checkmk. ابدأ عملية المراقبة بأداة Checkmk حان وقت الانتقال إلى واجهة المستخدم لأداة Checkmk في متصفح الانترنت الخاص بك. يكون لكل موقع Checkmk رابط URL خاص به، يتكون من العنوان IP أو اسم المضيف لخادمك المخصص لعملية المراقبة واسم موقع Checkmk. توجد ملفات تثبيت Checkmk في هذا المثال في المسار monitoring-host-server/checkmk_demo/. افتح رابط موقع Checkmk في متصفح جهازك. يمكنك فتح الرابط الظاهر على طرفية حاسوبك. سجل الدخول بمستخدم cmkadmin باستخدام كلمة المرور التي نسختها من الطرفية. عندما تسجل الدخول ستجد لوحة تحكم فارغة. اضغط على فئة المستخدم User في الشريط الجانبي sidebar على اليسار، ثم اضغط على تغيير كلمة المرور change password في فئة Profile. إعداد خدمة المراقبة تدعم أداة Checkmk عدة وسائل من خوادم المراقبة، وأفضل أسلوب لمراقبة الخوادم استخدام وكلاء agents لأداة Checkmk. عليك أن تثبت الوكيل قبل إضافة خادم. أولًا، اضغط على إعداد Setup في الشريط الجانبي اليساري (الزر على شكل عجلة مسننة)، هذه لوحة التحكم التي تضبط فيها كافة الإعدادات وتجد فيها وكلاء المراقبة. جميع الصور في هذه المقالة مأخوذة من نسخة Raw Edition مفتوحة المصدر، لكن توجد بينها وبين واجهة المستخدم في نسخة Enterprise Edition بعض الاختلافات. ثانيًا، اضغط على وكلاء Agents واختر الحزمة التي تناسب نظام التشغيل لديك. إن حزم الوكلاء في لينوكس متوفرة بصيغتي الملفات RPM و DEB. (اختيار وكيل) ثالثًا، حمّل الوكيل agent وثبته على الخادم المضيف لأداة المراقبة، وبعد ذلك اختبر أداء الوكيل بتنفيذ أمر check_mk_agent في طرفية خادمك. إضافة مضيف بعدما ثبتّ الوكيل، ارجع إلى شاشة Setup واختر المضيفين Hosts ثم اضغط على إضافة مضيف Add host وأضف اسم خادمك إلى جانب خيار اسم المضيف Hostname. إذا كان لديك خادم DNS معد في شبكتك، ستجد Checkmk العنوان IP لاسم المضيف الذي حددته تلقائيًا. وإلا أضف العنوان من خلال الضغط على مربع الاختيار إلى جانب خيار IPv4 Address. إذا أضفت عنوانًا اختر أي اسم مضيف تريده، ولا تعدّل بقية الخيارات. (إضافة مضيف) اضغط بعدها على حفظ التغييرات والانتقال إلى ضبط الخدمة Save & go to service configuration. تعمل الآن Checkmk على الاكتشاف التلقائي لأية خدمات مناسبة تحتاج إلى المراقبة على ذلك المضيف ويصنفها بفئة خدمات معلَّقة Undecided services. كما تضيف Checkmk تلقائيًا تصنيفات حسب نوع الجهاز كما هو موضح في الصورة. بعدها، اضغط على معالجة الجميع Fix all لمراقبة جميع هذه الخدمات. يضيف ذلك جميع الخدمات وتصنيفات المضيف التي رُصدَت إلى لوحة تحكم المراقبة لديك، ويزيل الخدمات التي اختفت. تستطيع بالطبع إدارة الخدمات بنفسك لكن خيار Fix all تسهل هذه العملية كثيرًا. (خيار Fix all لمراقبة المضيف) أخيرًا، ثم اضغط على الحقل المحدَّد الذي يتضمن إشارة تعجب صفراء (!) في الزاوية اليمنى في الأعلى، لتفعيل التعديلات التي أجريتها. اضغط على التفعيل على المواقع المختارة Activate on selected sites، وبهذا ستكون نجحت في إضافة أول خادم إلى عملية المراقبة لديك. إن لزوم التأكيد على تفعيل التعديلات هو آلية وقائية، فكل التعديلات التي أجريتها تصنف ضمن قائمة التعديلات المعلَّقة Pending changes أولًا حتى تراجع أي تعديل قبل أن تفعله ويؤثر على عملية المراقبة. تختلف Checkmk بين عملية الإعداد باعتبارها بيئة ضبط الإعدادات التي تدير فيها المضيفين والخدمات والإعدادات، ومنطقة المراقبة Monitor التي تجري فيها عملية المراقبة الفعلية. لا تؤثر إضافة المضيفين الجدد وإجراء أية تعديلات أخرى في الإعدادات على عملية المراقبة في البداية، عليك أن تفعلها حتى تطبَّق عليها المراقبة. المراقبة باستخدام بروتوكول SNMP إن مراقبة الشبكة هي مهمة أساسية أخرى إلى جانب مراقبة الخادم. وسأعرض عليك في مثال على ذلك كيف تراقب مبدلًا switch عن طريق بروتوكول SNMP. كل ما عليك فعله هو التأكد من تفعيل وكيل SNMP على الجهاز الذي تريد مراقبته، ومن إمكانية وصول خادمك الذي ثبتّ عليه Checkmk إلى ذلك الجهاز. توجه إلى Setup ثم Hosts ثم اضغط على Add host. أدخل اسم المضيف والعنوان (إذا تطلب الأمر). تفترض Checkmk افتراضيًا أنك تستخدم وكيل Checkmk، لذا عليك تعديل ذلك في منطقة Monitoring agents. فعل مربع الاختيار الموجود إلى جانب SNMP وعدّل إصدار SNMP (سيكون غالبًا SNMP v2 أو SNMP v3). كما تفترض Checkmk افتراضيًا أن منظومة SNMP لديك متاحة Public لأن هذا الخيار هو الافتراضي على معظم أجهزة SNMP. إذا كان الحال كذلك لا تحدد صندوق إضافة بيانات SNMP (كما فعلت أنا)، أما في حالة أخرى حدد هذا الصندوق وأضف بيانات SNMP فيه. (إضافة مضيف SNMP) اضغط على Save & go to service configuration وستكتشف Checkmk جميع المنافذ المتاحة حاليًا ووقت التشغيل والتحقق من معلومات SNMP. إذا وجِدت إضافة plug-in مراقبة لنوع محدد من الأجهزة، تكتشف Checkmk المزيد من خدمات المراقبة تلقائيًا. اضغط على Fix all واقبل جميع التعديلات. مراقبة ممتعة أصبح موقع Checkmk الخاص بك الآن يعمل وأضفت إليه مضيفين، وهنا تنتهي هذه المقالة التعليمية، لكن تجربتك الحقيقية في المراقبة بدأت لتوها. ربما قد لاحظت أن Checkmk توفر وكلاء لجميع أنظمة التشغيل تقريبًا حتى تتمكن من إضافة مزيد من المضيفين، وهذه العملية مشابهة لبقية الأنظمة. كما تدعم Checkmk بروتوكول SNMP وIPMI وHTML والكثير من الخدمات المعيارية الأخرى، وذلك ليتوفر دومًا لديك طريقة فعالة لمراقبة نظام معين. نتمنى لك مراقبة ممتعة. ترجمة -وبتصرف- للمقال Monitor your Linux server with Checkmk لصاحبه Ferdinand. اقرأ أيضًا ما هو نظام التشغيل لينكس؟ عشرون أمرا في لينكس يفترض أن يعرفها كل مدير نظم ما الفرق بين نسخة الخادم ونسخة المستخدم من أوبنتو لينكس تثبيت لينكس مع نظام ويندوز