🚧 القبو — حلول مرجعية
text███████████████████████████████████████████████████████████████ █ █ █ قف. لا تقرأ أبعد من هذا السطر إن لم تكن قد كتبتَ كل █ █ سكربتٍ بيدك وكافحتَه بجدّية. █ █ █ █ فتحُ هذا القبو قبل الكفاح يسرق منك لحظة "آها" — وهي السبب █ █ الوحيد الذي بنيتُ هذا المنهج من أجله. القرار لك وحدك. █ █ █ ███████████████████████████████████████████████████████████████
هذه ليست «الحلول الوحيدة الصحيحة» — هي حلولٌ مرجعية مع تبريرها. إن اختلف حلّك وعمِل واجتاز shellcheck، فهو صحيح. قارن المنطق، لا الحروف.
تذكير بقواعد هولبرتون لكل سكربت: السطر الأول #!/usr/bin/env bash بالضبط، السطر الثاني تعليقٌ يشرح الوظيفة، ينتهي الملف بسطرٍ جديد، قابلٌ للتنفيذ (chmod +x)، يجتاز shellcheck بلا أخطاء.
basics_0 — الأسئلة الاختيارية (0–3): الأجوبة وتبريرها
لن أكتفي بالأرقام — لكلٍّ لماذا الصحيح صحيح ولماذا الخطأ خطأ. (راجع المراحل 04, 02, 01, 03.)
0-OSI_model
- ما الـ OSI؟ → 2. نموذجٌ مفاهيميٌّ يصف وظائف الاتصال «دون اعتبارٍ لبنيتها الداخلية وتقنيتها». الخيار 3 خطأ لأنه يقول «باعتبارٍ قويٍّ للبنية الداخلية» — وهذا يناقض جوهر التجريد (المرحلة 04: الفصل بين الطبقات يخفي البنية عمداً). الخيار 1 خطأ: OSI ليس إلزاماً على المصنّعين، بل إطارٌ مرجعي.
- كيف يُنظَّم؟ → 2. من الأدنى (الفيزياء) للأعلى (المعنى الإنساني). ليس أبجدياً ولا عشوائياً — إنه سُلّم تجريدٍ من المادة للمعنى.
1-types_of_network
- حاسب محلّي → 3 (LAN). على نسيجٍ يبلغه جيرانه بالـ MAC مباشرةً (المرحلة 01).
- مكتب لمكتب عبر شوارع → 2 (WAN). LANان متباعدان موصولان (المرحلة 02).
- Google من الجوّال على بياناته → 1 (Internet). شبكتك تعبر شبكاتٍ عامّةً كثيرة (المرحلة 02).
2-MAC_and_IP_address
- ما الـ MAC؟ → 2. المعرّف الفريد لواجهة شبكة (المرحلة 01: اسمٌ مسطّحٌ محروقٌ في العتاد). الخياران الآخران يصفان الواجهة لا معرّفها.
- ما الـ IP؟ → 1. «هو للأجهزة كالعنوان البريدي للمنازل». الخيار 2 (المعرّف الفريد لواجهة) هو تعريف الـ MAC لا الـ IP — مصيدةٌ كلاسيكية. الفرق كله في المرحلة 02: MAC اسم، IP عنوانٌ هرمي.
3-UDP_and_TCP
- صندوق TCP → 1. «ينقل ببطءٍ لكن بثقة» (مصافحة+إقرار+إعادة، المرحلة 03).
- صندوق UDP → 2. «ينقل بسرعةٍ وقد يفقد».
- عامل TCP → 1. «هل استلمتَ الصناديق x, y, z؟» = الـ ACK حرفياً.
صيغة ملف الإجابة: رقم الجواب في سطر، سطرٌ جديد لكل جواب (كما في تعليمات هولبرتون). لِسؤالٍ واحدٍ في الملف: رقمٌ واحد. لأسئلةٍ متعدّدة في نفس الملف: رقمٌ في كل سطر بالترتيب.
4-TCP_and_UDP_portsbash#!/usr/bin/env bash # Displays listening sockets with the PID and name of the owning program netstat -lp
التبرير (استنتاج الرايات من المخرَج):
-l= listening فقط، ولكل العائلات (tcp/udp/unix) — لهذا يظهر «only servers» في العنوانين، وتظهر unix sockets في مخرَج هولبرتون.-p= PID/program (يتطلّب صلاحية ← يُشغَّل بـsudo).- لا
-n— لأن المخرَج المتوقّع يُظهر أسماء خدماتٍ (*:ssh,*:sunrpc) لا أرقاماً. وضع-nكان سيحوّلها لأرقام. - لا
-t/-u— لأنهما يقصران على Internet sockets ويخفيان unix sockets التي تظهر في المخرَج المطلوب.
التشغيل: sudo ./4-TCP_and_UDP_ports. (netstat من حزمة net-tools؛ ثبّتها إن لزم: sudo apt-get install net-tools.)
5-is_the_host_on_the_networkbash#!/usr/bin/env bash # Pings an IP address (first argument) 5 times; prints usage if none given if [ -z "$1" ]; then echo "Usage: 5-is_the_host_on_the_network {IP_ADDRESS}" else ping -c 5 "$1" fi
التبرير:
[ -z "$1" ]= «الوسيط الأول فارغ/غائب؟» → اطبع الاستخدام بالضبط كما طلب التاسك (انتبه للنص الحرفي والأقواس{IP_ADDRESS}).ping -c 5= خمس طلباتٍ فقط (-c= count، المرحلة 05)."$1"مقتبس → يُرضي shellcheck (SC2086) ويمنع word splitting (المرحلة 07).- بديلٌ مكافئ:
if [ "$#" -eq 0 ]; then ...— كلاهما يكشف غياب الوسيط.
0-change_your_home_IP (basics_1)النسخة الجراحية (تطبّق درس «استبدل لا تكدّس» من المرحلة 06):
bash#!/usr/bin/env bash # Resolves localhost to 127.0.0.2 and facebook.com to 8.8.8.8 via /etc/hosts sed -i 's/^127\.0\.0\.1.*localhost.*/127.0.0.2\tlocalhost/' /etc/hosts echo -e "8.8.8.8\tfacebook.com" >> /etc/hosts
التبرير:
sed -iيعدّل الملف في مكانه. النمط يطابق سطر IPv4 الذي يحوي localhost ويستبدله بـ127.0.0.2 localhost— استبدالٌ لا إضافة، فلا يبقى تعيينان متعارضان (مصيدة المرحلة 06).- ثم نُلحق سطر facebook.com.
- يُشغَّل بـ
sudo(ملف نظامٍ يملكه root).
بديلٌ أبسط (لكنه يمسح بقية الملف — اعرف ما تفعل):
bashecho -e "127.0.0.2\tlocalhost\n8.8.8.8\tfacebook.com" > /etc/hosts
يجتاز فحص هولبرتون لأنه يحقّق الحلّين المطلوبين، لكنه يحذف سطر اسم الجهاز و ::1. الجراحي أنظف وأقرب لروح «لا تكسر شيئاً آخر».
تذكير: على جهازٍ تستعمله، أعِد 127.0.0.1 localhost بعد التجربة، أو جرّبه في VM.
1-show_attached_IPsbash#!/usr/bin/env bash # Displays all active IPv4 IPs on the machine ifconfig | grep "inet " | awk '{print $2}'
التبرير:
ifconfigيُخرج كل الواجهات؛grep "inet "(بمسافةٍ بعد inet) يصطفي أسطر IPv4 ويستبعدinet6تلقائياً (لا مسافة بعد «inet» في «inet6»).awk '{print $2}'يأخذ الحقل الثاني = العنوان (10.0.2.15).- ترتيب المخرَج (الواجهة الفعلية ثم
lo) يطابق مخرَج هولبرتون، ويشمل127.0.0.1كما هو مطلوب.
بديلٌ بـ ip (مضمونٌ على Ubuntu 22.04 دون تثبيت net-tools):
baship -4 -o addr show | awk '{print $4}' | cut -d/ -f1
-o يجعل كل واجهةٍ سطراً واحداً، الحقل الرابع هو العنوان/CIDR، وcut -d/ -f1 يقصّ الـ CIDR. (قد يختلف الترتيب: lo أولاً.) إن لم يكن ifconfig مثبّتاً: sudo apt-get install net-tools.
2-port_listening_on_localhostbash#!/usr/bin/env bash # Listens on port 98 (TCP) nc -l 98
التبرير:
nc -l 98ينشئ خادم TCP يستمع على المنفذ 98. ما يُكتب من العميل يظهر هنا (أنبوب TCP خام، المرحلة 03/07).- يُشغَّل بـ
sudoلأن 98 < 1024 (منفذٌ مميَّز، المرحلة 03). - الاختبار من طرفٍ آخر:
telnet localhost 98ثم اكتب نصّاً — يظهر في طرف الخادم.
ملاحظة على اختلاف إصدارات nc: صيغة الاستماع تختلف: netcat-openbsd (افتراضي Ubuntu): nc -l 98. إصدارات أخرى: nc -l -p 98 أو nc -lp 98. ثبّت الموصى به: sudo apt-get install netcat-openbsd. لربطٍ صريحٍ على localhost في بعض الإصدارات: nc -l localhost 98.
بعد القبو
إن قارنتَ وفهمتَ كل فرقٍ بين حلّك والمرجع، فقد أغلقتَ الدائرة. لم تَعُد «تحفظ أوامر» — صرتَ تشتقّها. عُد متى شئتَ لـ reference-cards.md كذاكرةٍ خارجية، لا كبديلٍ عن الفهم.