أساسيات الحاسب والبرمجة الأدلة التقنية

بيئة البرمجة للمبتدئين: المحرر VS Code والطرفية Terminal

نجهز المحرر والطرفية وPython وNode على جهاز نظيف، ونفهم كل رسالة خطأ تظهر في الأيام الأولى مثل command not found وPATH وpython3 قبل أن نكتب أول برنامج.

بيئة البرمجة للمبتدئين: المحرر VS Code والطرفية Terminal

قررت أن تتعلم البرمجة، وفتحت أول درس فوجدته يطلب منك شيئاً يبدو سهلاً: اكتب السطر print("Hello") في ملف اسمه hello.py، ثم شغله بالأمر python hello.py. فكتبت الأمر كما هو، فظهرت لك رسالة باللون الأحمر تقول command not found، أو فتح لك Windows متجر التطبيقات بدل أن يشغل برنامجك، أو ظهرت رسالة أخرى تقول إن الملف غير موجود وأنت تراه أمامك في المجلد. وفي هذه اللحظة يتوقف كثير من المبتدئين ويظنون أن البرمجة ليست لهم، والحقيقة أنهم لم يكتبوا سطراً واحداً خاطئاً بعد، فالمشكلة ليست في البرمجة وإنما في الأدوات التي حولها: المحرر الذي تكتب فيه، والطرفية التي تشغل منها، والبرنامج الذي يفهم لغتك، وكيف يجد كل واحد منها الآخر.

وهذا المقال يجهز لك هذه الأدوات ويشرح لك كيف تعمل معاً، حتى تفهم كل رسالة خطأ تظهر لك في الأيام الأولى بدل أن تنسخها في محرك البحث وتجرب الحلول عشوائياً. ولن نكتفي بخطوات التثبيت، فخطوات التثبيت تتغير كل سنة، وإنما سوف نثبت Python وNode على جهاز Linux نظيف تماماً ونسجل كل خطأ يظهر في الطريق كما هو، ثم نفهم سببه. وإذا أردت أن تعرف ما الذي يحدث داخل الجهاز بعد أن يبدأ البرنامج في العمل فقد شرحنا ذلك في مقال ماذا يحدث عندما تشغل برنامج Hello World، وهنا سوف نقف قبل ذلك بخطوة: كيف تصل إلى اللحظة التي يعمل فيها البرنامج أصلاً.

وسوف نناقش في هذا المقال ما يلي:

  • ما هي بيئة البرمجة Development Environment، وما الأجزاء الثلاثة التي تتكون منها.
  • المحرر Editor: الفرق بين محرر النصوص ومحرر الكود وبيئة التطوير المتكاملة IDE، ولماذا ننصح بـ VS Code للبداية.
  • الطرفية Terminal والـ Shell، والمجلد الحالي الذي يسبب نصف أخطاء المبتدئين.
  • لماذا يوجد أمر اسمه python وآخر اسمه python3، وكيف تجد الطرفية أي أمر عبر المتغير PATH.
  • تجربة عملية على جهاز نظيف: تثبيت Python وNode، وأول برنامج بكل لغة، وكل رسالة خطأ ظهرت مع شرحها.
  • المكتبات والبيئة الافتراضية Virtual Environment، ولماذا يرفض النظام أن تثبت مكتبة بالأمر pip.
  • حرف نهاية السطر الذي لا تراه ويوقف السكربت، ثم أول برنامج داخل VS Code.
  • جدول بأخطاء البداية ومن يكتبها وكيف تصلحها، وخطوات كل نظام تشغيل، وقائمة تحقق قبل أن تبدأ الدروس.

ما هي بيئة البرمجة Development Environment؟

عندما تكتب برنامجاً فأنت في الحقيقة تكتب ملفاً نصياً عادياً، لا يختلف عن ملف ملاحظات إلا في أن محتواه مكتوب بقواعد لغة برمجة. وهذا الملف وحده لا يفعل شيئاً، فهو مثل وصفة طبخ مكتوبة على ورقة، تحتاج من يقرؤها وينفذها. ولذلك تحتاج ثلاثة أشياء على جهازك حتى يتحول النص إلى برنامج يعمل، وهذه الثلاثة معاً هي ما نسميه بيئة البرمجة Development Environment، والصورة التالية تبينها:

أجزاء بيئة البرمجة: المحرر Editor يحفظ الكود في ملف hello.py على القرص، والطرفية Terminal تشغل الأمر python3 hello.py فتبحث عن مشغل اللغة في مجلدات PATH، ومشغل اللغة مثل python3 أو node يقرأ الملف وينفذه ويعيد المخرج إلى الطرفية
ثلاثة أجزاء حول ملف واحد: تكتب، ثم تشغل، ثم ترى النتيجة

الجزء الأول هو المحرر Editor، وهو البرنامج الذي تكتب فيه الكود وتحفظه. والجزء الثاني هو الطرفية Terminal، وهي النافذة النصية التي تكتب فيها الأوامر للجهاز، ومنها تطلب تشغيل ملفك. والجزء الثالث هو مشغل اللغة Runtime، وهو البرنامج الذي يفهم لغتك فعلاً: في Python هو المفسر Interpreter المسمى python3، وفي JavaScript خارج المتصفح هو node. ولاحظ في الصورة أن المحرر لا يشغل شيئاً بنفسه، فحتى زر التشغيل الأخضر في VS Code يفتح طرفية مدمجة ويكتب فيها نفس الأمر الذي كنت ستكتبه أنت، ولذلك فإن فهم الطرفية هو المفتاح لفهم كل ما يحدث عند الضغط على الزر.

وقد يتساءل البعض: لماذا لا يكون هناك برنامج واحد يكتب ويشغل ويعرض النتيجة؟ والإجابة على ذلك أن هذه البرامج موجودة، ومنها مواقع تكتب فيها الكود في المتصفح وترى النتيجة فوراً، وهي مفيدة لأول ساعة، لكنها تخفي عنك الأجزاء الثلاثة، فإذا انتقلت إلى مشروع حقيقي على جهازك أو على سيرفر وجدت نفسك أمام نفس الأسئلة التي هربت منها: أين المفسر، وأي إصدار هو، ومن أي مجلد تشغل الملف. والفصل بين الأجزاء الثلاثة له فائدة أخرى، وهي أن كل جزء يمكن أن يتغير وحده: تستطيع أن تغير المحرر دون أن تغير اللغة، وأن تغير إصدار Python دون أن تغير المحرر، وأن تشغل نفس الملف على جهازك وعلى سيرفر لا يوجد فيه محرر أصلاً.

وفي اللغات التي تحتاج ترجمة Compilation قبل التشغيل، مثل C وGo وRust، يكون الجزء الثالث مترجماً Compiler يحول الملف إلى برنامج تنفيذي أولاً ثم تشغله، أما Python وJavaScript فتمرر الملف مباشرة إلى المفسر فيقرؤه وينفذه، وقد شرحنا الفرق بين الطريقتين بالتفصيل في مقال Hello World. وسوف نعمل في هذا المقال بلغتي Python وJavaScript، والسبب أنهما أكثر لغتين يبدأ بهما المبتدئون اليوم، وأنهما لا تحتاجان خطوة ترجمة، فتبقى البيئة في أبسط صورها.

المحرر Editor: من محرر النصوص إلى بيئة التطوير المتكاملة IDE

تستطيع نظرياً أن تكتب برنامجاً كاملاً في Notepad، فالملف في النهاية نص. ولكنك سوف تكتشف بسرعة لماذا لا يفعل ذلك أحد: لا يوجد تلوين يفرق بين الكلمات المحجوزة والنصوص والأرقام، ولا ترقيم للأسطر حتى تجد السطر الذي تشير إليه رسالة الخطأ، ولا تنبيه عندما تنسى قوساً، ولا إكمال تلقائي لأسماء المتغيرات التي كتبتها قبل خمس دقائق. ولذلك ظهرت عدة فئات من المحررات، كل فئة تضيف مساعدة أكثر مقابل حجم أكبر ووقت تعلم أطول:

فئات المحررات من الأبسط إلى الأكثر مساعدة: محرر نصوص بسيط مثل Notepad وnano وvim، ثم محرر كود مثل VS Code وSublime Text وZed، ثم بيئة تطوير متكاملة IDE مثل PyCharm وIntelliJ IDEA وVisual Studio، ثم محرر في المتصفح مثل Codespaces وopenvscode-server
كلها تكتب نفس الملف، والفرق في المساعدة التي تقدمها أثناء الكتابة
  • محرر النصوص البسيط Text Editor: مثل Notepad في Windows، وnano وvim في Linux. يفتح الملف ويحفظه، وبعضها يلون الكود، لكنه لا يفهم المشروع. ولا تستهين بهذه الفئة، فعندما تدخل إلى سيرفر عبر SSH لتعديل ملف إعدادات فغالباً لن تجد غير nano أو vim، ومن المفيد أن تعرف كيف تحفظ وتخرج من كل منهما.
  • محرر الكود Code Editor: مثل VS Code وSublime Text وZed. خفيف ويفتح أي لغة، ويضيف تلوين الكود والإكمال التلقائي وطرفية مدمجة، وكل لغة تحصل على دعم أعمق عبر إضافة Extension تثبتها عند الحاجة.
  • بيئة التطوير المتكاملة Integrated Development Environment واختصاراً IDE: مثل PyCharm لـ Python وIntelliJ IDEA لـ Java وVisual Studio لـ C#. كل شيء مدمج من البداية للغة أو لعائلة لغات: تحليل عميق للكود، وإعادة الهيكلة Refactoring بأمان، ومصحح أخطاء Debugger متقدم، وأدوات للاختبارات وقواعد البيانات، مقابل حجم أكبر واستهلاك أعلى للذاكرة.
  • المحرر في المتصفح: البيئة كلها تعمل على سيرفر وأنت تكتب من المتصفح، مثل GitHub Codespaces أو openvscode-server الذي سوف نستخدمه في هذا المقال لالتقاط الصور. ولا تثبت شيئاً على جهازك، لكنك تحتاج اتصالاً دائماً بالإنترنت.

وأي محرر تختار للبداية؟ الحل الأنسب لأغلب المبتدئين هو VS Code، والسبب ليس أنه الأفضل في كل شيء، وإنما أنه مجاني ويعمل على Windows وmacOS وLinux، ويدعم كل لغة تقريباً، وهو أكثر بيئة تطوير يستخدمها المطورون حالياً، حيث اختاره 75.9% من المشاركين في استبيان Stack Overflow للمطورين لعام 2025، والرقم التالي له Visual Studio بنسبة 29%. وهذا الانتشار يعني شيئاً عملياً لك: أي درس أو فيديو تشاهده غالباً سوف يستخدم VS Code، وأي سؤال تبحث عنه سوف تجد له إجابة.

ولكل اختيار نقاط قوة ونقاط ضعف. فنقاط القوة في VS Code أنه يبدأ خفيفاً وتضيف له ما تحتاجه فقط، وأنه ينقلك من لغة إلى أخرى دون أن تغير الأداة، وأن الطرفية المدمجة فيه هي نفس الطرفية التي ستستخدمها في كل مكان. ونقاط الضعف أن إعداده للغة معينة يحتاج إضافة أو اثنتين، وأن كثرة الإضافات تبطئه وتفتح باباً أمنياً، فالإضافة برنامج يعمل على جهازك بصلاحياتك، ولذلك لا تقم بتثبيت إضافة لا تعرف ناشرها. أما الـ IDE فنقاط قوته في المشاريع الكبيرة بلغة واحدة، حيث يفهم الكود فهماً أعمق، ونقاط ضعفه للمبتدئ أن كثرة الأزرار والنوافذ تشغلك عن الشيء الذي تتعلمه، وهو اللغة نفسها.

تثبيت VS Code وأول إعداداته Settings

التثبيت نفسه لا يحتاج شرحاً طويلاً، فتنزل البرنامج من صفحة الإعداد الرسمية لنظامك وتثبته مثل أي برنامج. ولكن هناك ثلاثة أشياء تظهر لك في أول ساعة وتحتاج أن تفهمها:

  1. عند فتح ملف بامتداد .py لأول مرة يقترح عليك VS Code تثبيت إضافة Python من Microsoft. وهذه الإضافة هي التي تعطيك الإكمال التلقائي وكشف الأخطاء أثناء الكتابة واختيار المفسر وزر التشغيل، ونعم، ثبتها. أما JavaScript فدعمها مدمج في VS Code من البداية ولا تحتاج إضافة لتشغيل ملف بسيط.
  2. عند فتح مجلد لأول مرة يسألك VS Code هل تثق في أصحاب الملفات الموجودة فيه، وهذه ميزة الثقة في مساحة العمل Workspace Trust. والسبب أن المجلد قد يحتوي إعدادات تشغل أوامر تلقائياً بمجرد فتحه، فإذا رفضت عمل المحرر في الوضع المقيد Restricted Mode، وهو يسمح لك بالقراءة والتعديل لكنه يمنع الطرفية والمهام التلقائية وبعض الإضافات. والقاعدة بسيطة: مجلداتك أنت ثق بها، ومشروع نزلته من مكان لا تعرفه افتحه أولاً في الوضع المقيد واقرأه.
  3. في أسفل النافذة شريط الحالة Status Bar، وفيه معلومات سوف تحتاجها عند أول مشكلة: ترميز الملف (مثل UTF-8)، ونوع نهاية السطر (LF أو CRLF، وسوف نرى لاحقاً لماذا يهم ذلك)، واللغة التي يظن المحرر أن الملف مكتوب بها، وإصدار Python الذي اختاره.

والصورة التالية من تجربتنا عندما فتحنا مجلد المشروع وطلبنا الطرفية لأول مرة، فظهر سؤال الثقة لأن إنشاء الطرفية يعني تشغيل أوامر على الجهاز:

نافذة VS Code تسأل: هل تثق في أصحاب الملفات في هذا المجلد؟ مع سبب السؤال: إنشاء طرفية يتطلب تشغيل كود، وأزرار Trust Folder & Continue وManage وCancel، وفي شريط الحالة عبارة Restricted Mode، وفي الزاوية اقتراح بتثبيت إضافة Python
سؤال الثقة في مساحة العمل، واقتراح إضافة Python في الزاوية، وعبارة Restricted Mode في شريط الحالة

ومن الإعدادات المفيدة للمبتدئ أن تفعل الحفظ التلقائي من قائمة File ثم Auto Save، والسبب أن أكثر خطأ مضحك ومزعج في الأسبوع الأول هو أن تعدل الكود ثم تشغله وترى النتيجة القديمة، لأنك لم تحفظ الملف، والطرفية تشغل ما على القرص وليس ما تراه على الشاشة. وكل إعدادات VS Code مكتوبة في ملف JSON يمكنك فتحه وتعديله مباشرة، وقد شرحت صفحة الإعدادات الرسمية الفرق بين إعدادات المستخدم التي تطبق على كل المشاريع وإعدادات مساحة العمل التي تحفظ داخل مجلد المشروع في .vscode/settings.json وتطبق عليه وحده.

الطرفية Terminal والـ Shell: النافذة التي تخيف المبتدئين

كلمة الطرفية Terminal تأتي من زمن كانت فيه الحواسيب الكبيرة في غرفة واحدة، والمستخدمون يجلسون أمام أجهزة طرفية فيها شاشة ولوحة مفاتيح فقط، يكتبون الأوامر ويرسلونها إلى الحاسب المركزي. واليوم الطرفية برنامج على جهازك يحاكي ذلك الجهاز القديم: نافذة نصية تأخذ ما تكتبه وتعرض ما يرجع. أما البرنامج الذي يفهم ما تكتبه فعلاً فاسمه الـ Shell، وهو الذي يقرأ السطر ويقسمه إلى كلمات، ويبحث عن البرنامج المطلوب ويشغله، ويعرض لك النتيجة. ولذلك يمكن أن تفتح نفس الطرفية مع Shell مختلف:

  • في Linux غالباً bash، وهو الذي سوف تراه في كل أمثلة هذا المقال.
  • في macOS الـ Shell الافتراضي zsh، وأوامره الأساسية مثل bash تقريباً.
  • في Windows يوجد PowerShell وموجه الأوامر القديم cmd، وكلاهما يعمل داخل تطبيق Windows Terminal. ويوجد أيضاً WSL، وهو Linux كامل يعمل داخل Windows، ونصيحتنا إذا كنت ستعمل في تطوير الويب أو السيرفرات أن تتعلم على WSL من البداية، لأن السيرفرات التي ستنشر عليها برامجك تعمل بـ Linux غالباً.

ولا تحتاج في البداية إلا عدداً قليلاً من الأوامر، وكلها تدور حول سؤال واحد: أين أنا الآن؟ فكل طرفية مفتوحة لها مجلد حالي Current Directory، وكل اسم ملف تكتبه بدون مسار كامل يبحث عنه البرنامج في هذا المجلد. والأمر pwd يطبع المجلد الحالي، وls يعرض ما فيه (dir في cmd)، وcd ينقلك إلى مجلد آخر، وcd .. يرجعك خطوة إلى الأعلى. وقد شرحنا هذه الأوامر وغيرها بالتفصيل في مقال سطر الأوامر في Linux للمبتدئين، والمهم هنا أن تفهم لماذا يسبب المجلد الحالي نصف أخطاء الأسبوع الأول، وسوف ترى ذلك بعينك في التجربة بعد قليل.

وقد يبدو لك أن الطرفية خطوة إلى الخلف في زمن الواجهات الرسومية، لكنها في الحقيقة أسرع طريقة لتكرار نفس العمل، فالأمر الذي كتبته مرة تستطيع أن تعيده بالسهم الأعلى، وأن تضعه في سكربت، وأن ترسله لزميلك فيحصل على نفس النتيجة، وهذا مستحيل مع سلسلة نقرات في واجهة رسومية. وكل أدوات المطور التي سوف تقابلها لاحقاً، من Git إلى Docker إلى مديري الحزم، تعمل من الطرفية أولاً.

لماذا يوجد أمر python وأمر python3؟ قصة إصدارين Versions

قبل أن نبدأ التجربة تحتاج أن تعرف قصة صغيرة تفسر أكثر رسالة خطأ يقابلها مبتدئو Python. ففي عام 2008 صدر Python 3، وكان مختلفاً عن Python 2 بشكل لا يسمح للبرامج القديمة أن تعمل عليه دون تعديل، ومن أشهر الفروق أن print أصبحت دالة تحتاج أقواساً. ولأن ملايين السكربتات كانت مكتوبة لـ Python 2، عاش الإصداران معاً على نفس الأجهزة أكثر من عشر سنوات، فأصبح الأمر python يشغل الإصدار 2 والأمر python3 يشغل الإصدار 3، حتى لا يتعطل أي سكربت قديم.

ثم أعلن فريق Python نهاية دعم Python 2 في الأول من يناير 2020، وبدأت أنظمة التشغيل تحذفه. ففي macOS 12.3 كتبت Apple في ملاحظات الإصدار أن Python 2.7 حذف من النظام وأن على المطورين استخدام Python 3، فاختفى الأمر python من أجهزة كثيرة بين ليلة وضحاها. وفي Debian وUbuntu لا يوجد أمر اسمه python أصلاً بعد التثبيت، وإنما python3 فقط، ومن أراد الاسم القصير يثبت حزمة صغيرة اسمها python-is-python3 كل وظيفتها أن تنشئ الاسم python وتجعله يشير إلى python3. أما في Windows فالأمر المعتاد هو python أو py، ويشرح دليل Microsoft تحت عنوان Why does running python.exe open the Microsoft Store? لماذا يفتح لك Windows متجر التطبيقات إذا كتبت python ولم يكن Python مثبتاً: أضافت Microsoft اختصاراً يوجه المبتدئ إلى تثبيت Python من المتجر بدل أن يرى رسالة خطأ.

والنتيجة العملية لك: إذا قال لك درس python وأنت على Linux أو macOS فاكتب python3، وإذا قال python3 وأنت على Windows فجرب python أو py، والمهم أن تتأكد دائماً من الإصدار الذي يعمل بالأمر --version قبل أن تبحث عن أي خطأ آخر.

التجربة العملية: جهاز نظيف من الصفر Lab

أفضل طريقة لفهم أخطاء التثبيت هي أن تراها بعينك على جهاز لم يثبت عليه شيء بعد. ولكي تكون النتيجة واحدة عند كل قارئ استخدمنا Container من Debian 13 بالنسخة المصغرة debian:trixie-slim، وهي تأتي بدون Python وبدون Node، فتشبه جهازاً جديداً اشتريته للتو. وإذا لم يكن Docker مثبتاً لديك فقد شرحناه في دليل تثبيت Docker على Ubuntu، ويمكنك أيضاً أن تتابع نفس الأوامر على أي جهاز Linux أو داخل WSL. والتجارب كلها في سكربت واحد اسمه run.sh يطبع كل أمر، ثم مخرجه، ثم رمز الخروج Exit Code، وتشغيله كما يلي:

mkdir devenv-lab && cd devenv-lab
# ضع الملف run.sh في هذا المجلد ثم:
docker run --rm --name devenv-lab -v "$PWD":/lab debian:trixie-slim bash /lab/run.sh > run.out 2>&1

ورمز الخروج رقم يعيده كل برنامج عند انتهائه، والرقم 0 يعني أنه انتهى بنجاح وأي رقم آخر يعني مشكلة، وسوف ترى أن هذا الرقم وحده يخبرك أحياناً من الذي فشل. والآن لنبدأ من أول سؤال يسأله أي شخص أمام جهاز جديد: هل يوجد Python أو Node هنا؟

$ cat /etc/debian_version
13.7
$ python --version
bash: line 1: python: command not found
[exit 127]
$ python3 --version
bash: line 1: python3: command not found
[exit 127]
$ node --version
bash: line 1: node: command not found
[exit 127]
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

في المخرج أعلاه لاحظ التالي:

  • الرسالة تبدأ بكلمة bash، وهذا يعني أن الذي كتبها هو الـ Shell وليس Python، فـ Python لم يعمل أصلاً لأنه غير موجود.
  • رمز الخروج 127 هو الرقم الذي يعيده bash عندما لا يجد الأمر، وسوف تراه كثيراً.
  • آخر سطر هو قيمة المتغير PATH، وهو قائمة مجلدات مفصولة بنقطتين، ومنها يبحث الـ Shell عن أي أمر تكتبه، وهذا موضوع القسم التالي.

كيف تجد الطرفية الأمر؟ متغير البيئة PATH

عندما تكتب python3 hello.py فالـ Shell يعتبر الكلمة الأولى اسم برنامج، وبقية الكلمات معاملات Arguments يسلمها لهذا البرنامج. ولكن أين يجد ملف البرنامج نفسه على القرص؟ الحل البسيط أن تكتب المسار الكامل في كل مرة، مثل /usr/bin/python3 hello.py، وهذا يعمل لكنه متعب ويختلف من جهاز لآخر. لذلك يوجد متغير بيئة Environment Variable اسمه PATH يحتوي قائمة مجلدات، والـ Shell يمر عليها بالترتيب من اليسار إلى اليمين ويشغل أول ملف قابل للتنفيذ يحمل نفس الاسم، وهذا السلوك موصوف في معيار POSIX لمتغيرات البيئة الذي تتبعه أنظمة Linux وmacOS. والصورة التالية تبين البحث عن python3 بعد تثبيته:

الـ Shell يبحث عن python3 في مجلدات PATH بالترتيب: /usr/local/sbin ثم /usr/local/bin ثم /usr/sbin غير موجود فيها، ثم يجده في /usr/bin فيتوقف ولا يصل إلى /sbin و/bin، ويشغل /usr/bin/python3 الذي يشير إلى python3.13، وقبل التثبيت لا يجده في أي مجلد فتظهر رسالة command not found برمز خروج 127
أول مجلد فيه الاسم يفوز، وإذا لم يوجد في أي مجلد ظهرت command not found

ومن هذه القاعدة البسيطة تخرج ثلاث نتائج سوف تحتاجها كثيراً. الأولى أن تثبيت برنامج لا يكفي ليعمل باسمه، وإنما يجب أن يكون في مجلد داخل PATH، وهذا سبب الخيار الذي يسألك عنه مثبت Python في Windows عن إضافته إلى PATH. والثانية أن الترتيب مهم، فإذا كان على جهازك نسختان من نفس البرنامج فالتي في المجلد الأسبق هي التي تعمل، حتى لو كانت الأقدم. والثالثة أن الملفات في المجلد الحالي لا تعمل باسمها وحده، لأن المجلد الحالي ليس في PATH، ولذلك تكتب ./greet وليس greet، وهذا مقصود لأسباب أمنية، فلو كان المجلد الحالي في PATH لاستطاع أي شخص أن يضع في مجلد مشترك ملفاً اسمه ls فيعمل بدلاً من الأمر الحقيقي عندما تدخل ذلك المجلد.

وفي Windows الفكرة نفسها مع فروق في الشكل: المجلدات مفصولة بفاصلة منقوطة بدل النقطتين، والمجلد الحالي يبحث فيه موجه الأوامر cmd قبل PATH، وتعدل PATH من إعدادات النظام بالبحث عن Edit environment variables for your account، وهو المسار الذي يذكره دليل Python الرسمي على Windows عند الحديث عن إضافة مجلد Python إلى PATH. ولاحظ أن أي تعديل على PATH من الإعدادات لا يظهر في نافذة طرفية مفتوحة مسبقاً، فيجب أن تغلقها وتفتح نافذة جديدة، وهذا وحده يفسر عدداً كبيراً من رسائل «ثبته ولكنه لا يعمل».

تثبيت Python من التوزيعة Distribution

نعود إلى الجهاز النظيف، ونثبت Python من مستودع التوزيعة نفسها بالأمر apt، وهي الطريقة الأبسط على Linux:

$ apt-get update -qq && apt-get install -y -qq python3 > /dev/null && echo installed
installed
$ python3 --version
Python 3.13.5
$ type python3
python3 is /usr/bin/python3
$ ls -l /usr/bin/python3
lrwxrwxrwx 1 root root 10 Jun 30  2025 /usr/bin/python3 -> python3.13
$ python --version
bash: line 1: python: command not found
[exit 127]
$ apt-get install -y -qq python-is-python3 > /dev/null && python --version
Python 3.13.5

في المخرج أعلاه لاحظ التالي:

  • الأمر type python3 يخبرك أين وجد الـ Shell البرنامج، وهو /usr/bin/python3، أي في رابع مجلد من PATH كما في الصورة السابقة. وهذا الأمر هو أول ما تكتبه عندما تشك أن نسخة أخرى هي التي تعمل.
  • الحرف l في أول سطر ls -l والسهم -> يعنيان أن python3 رابط رمزي Symbolic Link يشير إلى الملف الحقيقي python3.13، وبهذه الطريقة يمكن أن تثبت عدة إصدارات معاً ويبقى الاسم العام يشير إلى أحدها.
  • بعد تثبيت Python بقي الأمر python غير موجود، وهذه ليست مشكلة في التثبيت وإنما قرار من Debian كما شرحنا، والحزمة python-is-python3 أضافت الاسم القصير.

والإصدار الذي حصلنا عليه هو Python 3.13.5، وهو الإصدار الذي اختارته Debian 13 وتبقى عليه طوال عمر التوزيعة مع إصلاحات الأمان فقط. وقد تجد على صفحة التنزيل الرسمية إصداراً أحدث، وهذا طبيعي، فالتوزيعات تفضل الثبات على الجديد، وللتعلم أي إصدار من سلسلة 3 حديث يكفيك.

أول برنامج، والمجلد الحالي Current Directory

الآن نكتب أول ملف ونشغله، ثم نشغله مرة ثانية من مجلد آخر لنرى أشهر خطأ في الأسبوع الأول:

$ cat hello.py
print("Hello, ArabRoot")
print(2 + 3)
$ python3 hello.py
Hello, ArabRoot
5
$ cd / && python3 hello.py
python3: can't open file '//hello.py': [Errno 2] No such file or directory
[exit 2]
$ pwd; ls
/work
hello.py

في المخرج أعلاه لاحظ التالي:

  • السطر الثاني من البرنامج طبع 5 وليس 2 + 3، لأن المفسر حسب العبارة قبل أن يطبعها، أما النص بين علامتي التنصيص فطبع كما هو. وهذا الفرق بين النص والرقم سوف نعود إليه في مقال أساسيات البرمجة.
  • عندما انتقلنا إلى المجلد الرئيسي / وكتبنا نفس الأمر، بدأ Python فعلاً، والدليل أن الرسالة تبدأ بكلمة python3 وليس bash، لكنه بحث عن hello.py في المجلد الحالي فلم يجده. ورمز الخروج هنا 2 وليس 127، وهو رمز يختلف لأن الذي فشل برنامج آخر.
  • الحل ليس إعادة تثبيت Python كما يفعل بعض المبتدئين، وإنما pwd لتعرف أين أنت، وls لترى الملفات، ثم cd إلى مجلد الملف أو تكتب مساره الكامل.

وفي VS Code يحدث نفس الشيء بشكل أخفى: الطرفية المدمجة تفتح في مجلد المشروع الذي فتحته، فإذا فتحت ملفاً وحده بدل أن تفتح مجلده، أو كان الملف في مجلد فرعي، ثم كتبت python3 hello.py ظهرت نفس الرسالة. ولذلك عود نفسك من اليوم الأول أن تفتح المجلد كاملاً من File ثم Open Folder.

خطأ من الدروس القديمة: SyntaxError

كثير من الدروس المنتشرة كتبت في زمن Python 2، ونسخ مثال منها ينتج هذا:

$ python3 old.py
  File "/work/old.py", line 1
    print "Hello"
    ^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
[exit 1]

وهذه أول رسالة من المفسر نفسه تقول إن المشكلة في الكود وليس في البيئة: اسم الملف، ورقم السطر، والسطر نفسه، وعلامات ^ تحت الجزء الخاطئ، ثم نوع الخطأ واقتراح للحل. ولاحظ أن Python الحديث يقترح الحل بنفسه في كثير من الأخطاء الشائعة، فاقرأ آخر سطر في الرسالة دائماً قبل أي شيء آخر. وإذا وجدت درساً يكتب print بدون أقواس فهو درس قديم، وابحث عن غيره.

الوضع التفاعلي REPL: جرب سطراً قبل أن تكتب ملفاً

إذا كتبت python3 وحده بدون اسم ملف دخلت الوضع التفاعلي، واسمه REPL اختصاراً لـ Read-Eval-Print Loop، أي اقرأ السطر ثم احسبه ثم اطبع النتيجة ثم كرر. وهو مكان ممتاز لتجربة سطر واحد قبل أن تضعه في برنامجك، وقد شغلناه في التجربة بإدخال ثلاثة أسطر:

$ printf "1 + 1\n\"ab\" * 3\nexit()\n" | python3 -i -q
>>> 2
>>> 'ababab'
>>>

والعلامة >>> هي محث Python الذي ينتظر سطرك، ولاحظ أن الوضع التفاعلي يطبع قيمة كل عبارة دون أن تكتب print، ولذلك يبدو للمبتدئ أن 1 + 1 في ملف سوف تطبع 2 أيضاً، وهي لا تطبع شيئاً في الملف إلا إذا وضعتها داخل print. وتخرج من الوضع التفاعلي بـ exit(). وفي Node نفس الفكرة بكتابة node وحده، والخروج بـ .exit. وقد شرحت وثائق Python الرسمية طرق تشغيل المفسر كلها في صفحة واحدة.

سكربت يعمل كأمر: الـ Shebang والصلاحيات Permissions

بعد أسابيع سوف تكتب سكربتاً صغيراً وتريد أن تشغله كأي أمر آخر، دون أن تكتب python3 قبله. ولهذا يوجد سطر خاص في أول الملف اسمه الـ Shebang، يبدأ بـ #! ويخبر النظام أي برنامج يجب أن يقرأ هذا الملف. وكتبنا الملف التالي باسم greet بدون امتداد:

#!/usr/bin/env python3
print("Hello from a command")

ثم حاولنا تشغيله على أربع مراحل، وكل مرحلة أظهرت خطأ مختلفاً:

$ ls -l greet
-rw-r--r-- 1 root root 53 Oct 30 22:09 greet
$ ./greet
bash: line 1: ./greet: Permission denied
[exit 126]
$ chmod +x greet && ./greet
Hello from a command
$ greet
bash: line 1: greet: command not found
[exit 127]
$ mkdir -p $HOME/bin && cp greet $HOME/bin/ && export PATH="$HOME/bin:$PATH" && greet && type greet
Hello from a command
greet is hashed (/root/bin/greet)
$ greet
bash: line 1: greet: command not found
[exit 127]

في المخرج أعلاه لاحظ التالي:

  • الصلاحيات -rw-r--r-- فيها حرف r للقراءة وw للكتابة ولا يوجد x للتنفيذ، فرفض النظام التشغيل برسالة Permission denied ورمز 126، وهو رمز يعني أن الأمر موجود لكنه لا يمكن تشغيله. وقد شرحنا هذه الحروف في مقال صلاحيات الملفات Permissions في Linux.
  • بعد chmod +x عمل الملف بالمسار ./greet، لكنه لم يعمل باسمه وحده لأن المجلد الحالي ليس في PATH، وهي نفس القاعدة التي شرحناها.
  • عندما نسخناه إلى المجلد $HOME/bin وأضفنا هذا المجلد إلى أول PATH عمل باسمه، والأمر type أكد أنه وجده هناك.
  • آخر سطر هو المفاجأة: نفس الأمر فشل مرة أخرى. والسبب أن كل سطر في السكربت يعمل في Shell جديد، وexport يغير PATH في الـ Shell الحالي فقط، فإذا أغلقته ضاع التعديل. ولكي يبقى التعديل دائماً تضيف سطر export إلى ملف ~/.bashrc (أو ~/.zshrc في macOS) فيقرؤه كل Shell جديد عند بدايته.

تثبيت Node: نسخة التوزيعة Distribution أم النسخة الرسمية؟

الآن نثبت Node بنفس الطريقة البسيطة من مستودع Debian، ونشغل أول برنامج JavaScript:

console.log("Hello, ArabRoot");
console.log(2 + 3);
console.log("2" + 3);
$ apt-get install -y -qq nodejs > /dev/null && node --version
v20.19.2
$ node hello.js
Hello, ArabRoot
5
23
$ npm --version
bash: line 1: npm: command not found
[exit 127]

في المخرج أعلاه لاحظ التالي:

  • السطر الثالث طبع 23 وليس 5، لأن JavaScript عندما ترى نصاً وعلامة + تحول الرقم إلى نص وتلصقهما، وسوف نرى في مقال أساسيات البرمجة أن Python في نفس الموقف ترفض وتظهر خطأ، وكلا السلوكين له منطقه.
  • الإصدار هو 20.19.2، وسلسلة Node 20 انتهى دعمها من مشروع Node نفسه في 30 أبريل 2026 بحسب جدول الإصدارات الرسمي، أما الإصدار طويل الدعم LTS الحالي على صفحة التنزيل فهو 26.13.0. وهذا مثال واضح على أن نسخة التوزيعة قد تكون قديمة جداً على لغة تتحرك بسرعة.
  • مدير الحزم npm غير موجود، لأن Debian يفصله في حزمة مستقلة، بينما يعتبره أغلب المبتدئين جزءاً من Node، وكل درس JavaScript تقريباً يبدأ بأمر npm install.

لذلك نجرب الطريقة الثانية: النسخة الرسمية من موقع Node مباشرة. وهذه الطريقة تريك كيف يعمل التثبيت تحت أي مثبت رسومي، فالمثبت في النهاية ينسخ ملفات إلى مجلد ثم يضيف هذا المجلد إلى PATH:

$ curl -fsSLO https://nodejs.org/dist/v26.13.0/node-v26.13.0-linux-x64.tar.xz && ls -lh node-v26.13.0-linux-x64.tar.xz
-rw-r--r-- 1 root root 33M Oct 30 22:18 node-v26.13.0-linux-x64.tar.xz
$ curl -fsSL https://nodejs.org/dist/v26.13.0/SHASUMS256.txt | grep linux-x64.tar.xz | sha256sum -c -
node-v26.13.0-linux-x64.tar.xz: OK
$ tar -xJf node-v26.13.0-linux-x64.tar.xz -C /opt && ls /opt/node-v26.13.0-linux-x64/bin
node
npm
npx
$ node --version; which -a node
v20.19.2
/usr/bin/node
/bin/node
$ export PATH="/opt/node-v26.13.0-linux-x64/bin:$PATH"; node --version; which -a node; npm --version
v26.13.0
/opt/node-v26.13.0-linux-x64/bin/node
/usr/bin/node
/bin/node
11.20.0

في المخرج أعلاه لاحظ التالي:

  • السطر الثاني يتحقق من سلامة الملف قبل استخدامه، حيث ينشر مشروع Node بصمة SHA-256 لكل ملف في صفحة الإصدار، والكلمة OK تعني أن الملف الذي نزلته هو نفس الملف الذي نشره المشروع ولم يتغير في الطريق. وهذه عادة جيدة مع أي برنامج تنزله يدوياً.
  • بعد فك الضغط أصبح Node 26 موجوداً على القرص، ومع ذلك أعطى node --version الإصدار القديم 20، لأن المجلد الجديد ليس في PATH. والأمر which -a يعرض كل نسخة يجدها في PATH بالترتيب، ولم يجد الجديدة.
  • بعد إضافة المجلد إلى أول PATH أصبحت النسخة الجديدة هي الأولى في قائمة which -a، فعمل Node 26 ومعه npm 11.20.0 الذي يأتي مع النسخة الرسمية دائماً.

والتجربة التالية تثبت أن الترتيب هو الذي يقرر، فنفس النسختين على نفس الجهاز، والفرق فقط في أي مجلد يأتي أولاً:

$ export PATH="/usr/bin:/opt/node-v26.13.0-linux-x64/bin"; node --version
v20.19.2
$ export PATH="/opt/node-v26.13.0-linux-x64/bin:/usr/bin"; node --version
v26.13.0

وهذا هو سبب المشكلة المشهورة «ثبت الإصدار الجديد ولكن الأمر ما زال يعطي القديم»: نسختان على الجهاز، والقديمة في مجلد أسبق في PATH. والحل ليس إعادة التثبيت، وإنما which -a (أو where في Windows) لترى كل النسخ وترتيبها، ثم تحذف القديمة أو تغير الترتيب. وفي الواقع العملي لا يثبت أغلب المطورين Node يدوياً بهذه الطريقة، وإنما يستخدمون المثبت الرسمي أو مدير إصدارات Version Manager مثل nvm أو fnm، وهو أداة تحفظ عدة إصدارات في مجلد خاص وتغير PATH لك عندما تنتقل من مشروع لآخر، وكل الخيارات موجودة في صفحة التنزيل الرسمية. ولكن الفكرة تحت كل هذه الأدوات واحدة: ملفات في مجلد، والمجلد في PATH.

ماذا يحدث إذا أصبح PATH فارغاً؟

لنكمل الفكرة إلى نهايتها ونرى ماذا يحدث إذا مسحنا PATH تماماً، وهو ما يحدث فعلاً عندما يكتب أحدهم في ملف الإعدادات PATH=$HOME/bin وينسى :$PATH في آخر السطر:

$ PATH= ; ls
bash: line 1: ls: No such file or directory
[exit 127]
$ PATH= ; /bin/ls /work
crlf
greet
hello.js
hello.py
node-v26.13.0-linux-x64.tar.xz
old.py

حتى الأمر ls الذي يبدو جزءاً من النظام توقف، لأنه في الحقيقة برنامج عادي في المجلد /bin، والـ Shell لم يعد يعرف أين يبحث. ولكنه عمل فوراً عندما كتبنا مساره الكامل، وهذا يثبت أن كل أوامر الطرفية تقريباً برامج مثل برنامجك تماماً، والفرق الوحيد أن مجلداتها في PATH. وإذا حدث لك هذا بعد تعديل ملف ~/.bashrc فلا تقلق، افتح الملف بمساره الكامل مثل /usr/bin/nano ~/.bashrc وأصلح السطر، ثم افتح طرفية جديدة.

المكتبات Libraries والبيئة الافتراضية Virtual Environment

بعد أيام من التعلم سوف تحتاج مكتبة لا تأتي مع اللغة، مثل مكتبة requests للتعامل مع مواقع الإنترنت. وأي درس سوف يقول لك: اكتب pip install requests. ولكن على Debian وUbuntu الحديثة سوف ترى سلسلة من الأخطاء، وكل خطأ منها له سبب منطقي:

$ python3 -m pip --version
/usr/bin/python3: No module named pip
[exit 1]
$ apt-get install -y -qq python3-pip > /dev/null && python3 -m pip install requests
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.
    ...
hint: See PEP 668 for the detailed specification.
[exit 1]

الخطأ الأول بسيط: pip وهو مدير حزم Python غير مثبت، لأن Debian يفصله في حزمة مستقلة مثل npm. أما الخطأ الثاني فهو الأهم، والسبب فيه قرار مقصود وصفه مقترح PEP 668: Python الموجود في /usr/bin ليس لك وحدك، فأدوات النظام نفسها مكتوبة به وتعتمد على إصدارات محددة من المكتبات تثبتها التوزيعة بـ apt. فإذا ثبت pip مكتبة فوقها بإصدار آخر قد يتعطل برنامج من برامج النظام دون أن تعرف لماذا. لذلك تضع التوزيعة علامة تمنع pip من الكتابة في مكتبات النظام، وتقترح عليك في نفس الرسالة الحل الصحيح: بيئة افتراضية.

والبيئة الافتراضية Virtual Environment مجلد داخل مشروعك فيه نسخة خفيفة من المفسر تشير إلى نفس Python، ومعه مجلد مكتبات خاص بهذا المشروع وحده، والصورة التالية تبين الفرق:

مقارنة بين Python النظام في /usr/bin/python3 حيث يرفض pip التثبيت برسالة externally-managed-environment، والبيئة الافتراضية للمشروع في /work/.venv/bin/python حيث يعمل pip install ويطبع إصدار requests 2.34.2، والنتيجة أن المكتبة غير موجودة خارج البيئة فيظهر ModuleNotFoundError
مكتبات النظام للنظام، ومكتبات المشروع في مجلده

وإنشاء البيئة يكون بالأمر python3 -m venv .venv، ولكن على Debian ظهر خطأ ثالث قبل أن ننجح:

$ python3 -m venv .venv
The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt install python3.13-venv
...
$ apt-get install -y -qq python3-venv > /dev/null && python3 -m venv .venv && echo created
created
$ . .venv/bin/activate && which python && python -m pip install -q requests && python -c "import requests; print(requests.__version__)"
/work/.venv/bin/python
2.34.2
$ python3 -c "import requests"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'
[exit 1]
$ du -sh .venv
16M	.venv

في المخرج أعلاه لاحظ التالي:

  • رسالة ensurepip is not available تعني أن الأداة التي تضع pip داخل البيئة الجديدة غير موجودة، لأن Debian يفصلها أيضاً في حزمة python3-venv، والرسالة نفسها تقول لك ماذا تثبت. وعلى Windows وmacOS مع Python من الموقع الرسمي لن ترى هذا الخطأ لأن كل شيء يأتي معاً.
  • الأمر . .venv/bin/activate يفعل البيئة، وكل ما يفعله في الحقيقة أنه يضع مجلد .venv/bin في أول PATH، ولذلك أصبح which python يشير إلى نسخة البيئة. وهي نفس فكرة PATH التي رأيناها مع Node، ولا يوجد سحر آخر. وفي Windows يكون التفعيل بالأمر .venv\Scripts\activate.
  • داخل البيئة استخدمنا python -m pip وليس pip وحده، والسبب أن python -m pip يضمن أن المكتبة تثبت لنفس المفسر الذي سوف يشغل برنامجك، بينما pip وحده قد يكون من نسخة أخرى في PATH.
  • بعد الخروج إلى Python النظام لم يجد المكتبة، فظهر ModuleNotFoundError. وهذا هو المقصود من العزل، وهو أيضاً سبب أن VS Code قد يضع خطاً أحمر تحت import requests بينما البرنامج يعمل من الطرفية: المحرر اختار مفسراً غير مفسر البيئة، والحل من الأمر Python: Select Interpreter في VS Code.
  • حجم البيئة 16M مع مكتبة واحدة، ولذلك لا تضعها في Git أبداً، وإنما تكتب أسماء المكتبات في ملف مثل requirements.txt وكل شخص ينشئ بيئته منه، وقد شرحنا الملف .gitignore في مقال إدارة النسخ وGit للمبتدئين.

وفي JavaScript نفس الفكرة لكنها مبنية في الأداة من البداية: الأمر npm install يثبت المكتبات في مجلد node_modules داخل المشروع، وأسماء المكتبات وإصداراتها تكتب في ملف package.json، فكل مشروع معزول بطبيعته دون أن تفعل شيئاً. ولذلك تجد المبتدئين في JavaScript أقل اصطداماً بهذه المشكلة، وتجد مجلد node_modules في كل مشروع ضخماً لنفس السبب. وتفاصيل البيئات الافتراضية كلها في وثائق الوحدة venv.

المشكلة التي لم نتوقعها: نهاية السطر Line Ending بصيغة CRLF

هذه المشكلة لا يذكرها أي درس للمبتدئين، ومع ذلك سوف تصطدم بها غالباً إذا كتبت سكربتاً على Windows ثم شغلته على Linux أو داخل Container. فكل سطر في ملف نصي ينتهي بحرف خاص لا تراه، وLinux وmacOS ينهيان السطر بحرف واحد اسمه LF (Line Feed)، أما Windows فينهيه بحرفين: CR (Carriage Return) ثم LF، وهذه بقايا من زمن الآلات الكاتبة، حيث كان يجب إرجاع العربة إلى أول السطر ثم إنزال الورقة سطراً. والمحرر يعرض الحالتين بنفس الشكل، لكن البرامج تقرأ البايتات كما هي. وقد كتبنا نفس سكربت الـ Shebang بنهايات Windows، ثم شغلناه:

$ od -c crlf | head -2
0000000   #   !   /   u   s   r   /   b   i   n   /   e   n   v       p
0000020   y   t   h   o   n   3  \r  \n   p   r   i   n   t   (   "   s
$ ./crlf
env: 'python3\r': No such file or directory
env: use -[v]S to pass options in shebang lines
[exit 127]
$ python3 crlf
saved on Windows
$ sed -i "s/\r$//" crlf && ./crlf
saved on Windows

الأمر od -c يعرض كل بايت في الملف كحرف، وفيه ترى \r قبل \n في آخر السطر الأول. وعندما قرأ النظام سطر الـ Shebang أخذ كل ما بعد env حتى \n كاسم البرنامج، فطلب برنامجاً اسمه python3\r، ولا يوجد برنامج بهذا الاسم، فظهرت رسالة غريبة تقول إن ملفاً غير موجود، وأنت ترى Python مثبتاً وتشغله بيدك. ولاحظ أن نفس الملف عمل عندما شغلناه بـ python3 crlf، لأن Python نفسه يتعامل مع نهايتي السطر في الكود، والمشكلة فقط في سطر الـ Shebang الذي يقرؤه النظام. والصورة التالية تلخص ذلك:

مقارنة بين ملف محفوظ بنهاية LF حيث يجد env البرنامج python3، وملف محفوظ بنهاية CRLF حيث يصبح اسم البرنامج python3\r فيظهر خطأ No such file or directory، مع مخرج od -c الذي يظهر \r قبل \n، والحل في VS Code بالضغط على CRLF في شريط الحالة واختيار LF، وفي Git بالسطر * text=auto eol=lf في ملف .gitattributes
حرف \r واحد في آخر السطر الأول كان كافياً ليمنع السكربت من العمل

والحل في هذه الحالة حذف حرف \r من آخر كل سطر بالأمر sed كما في التجربة، أو من VS Code بالضغط على CRLF في شريط الحالة واختيار LF ثم الحفظ. أما الحل الدائم للفريق كله فهو ملف .gitattributes في المستودع فيه السطر * text=auto eol=lf، فيحفظ Git كل الملفات النصية بنهاية LF مهما كان نظام الشخص الذي كتبها، والتفاصيل في وثائق gitattributes.

أول برنامج داخل VS Code

بعد أن فهمت ما يحدث في الطرفية، يصبح العمل في VS Code مفهوماً أيضاً، لأنه نفس الأجزاء في نافذة واحدة. والخطوات كما يلي:

  1. أنشئ مجلداً للمشروع، وافتحه من File ثم Open Folder، ولا تفتح الملف وحده.
  2. أنشئ ملف hello.py من زر الملف الجديد في الشريط الجانبي Explorer، واكتب فيه السطرين.
  3. افتح الطرفية المدمجة من View ثم Terminal، أو بالاختصار Ctrl+`، وستجدها مفتوحة في مجلد المشروع نفسه.
  4. اكتب python3 hello.py (أو python hello.py في Windows)، أو node hello.js لملف JavaScript.

والصورة التالية من تجربتنا داخل openvscode-server، وهي نسخة VS Code مفتوحة المصدر تعمل في المتصفح على Container فيه Python فقط، ولذلك ترى نفس الخطأ الذي رأيناه في التجربة ثم النجاح:

نافذة VS Code فيها مجلد work بملفي hello.js وhello.py، والملف hello.py مفتوح في المحرر بسطري print، وفي الطرفية المدمجة الأمر python hello.py يعطي bash: python: command not found، ثم الأمر python3 hello.py يطبع Hello, ArabRoot ثم 5
الطرفية المدمجة هي نفس الطرفية: نفس الأمر، ونفس الخطأ، ونفس الحل

ولاحظ في الصورة أن العلامة الحمراء بجانب أول أمر في الطرفية والعلامة الزرقاء بجانب الثاني هي طريقة VS Code في إخبارك أن الأمر فشل أو نجح، وهي مبنية على رمز الخروج الذي رأيناه في كل التجارب. أما زر التشغيل ▷ الذي يظهر في أعلى المحرر بعد تثبيت إضافة Python فيكتب في الطرفية أمراً فيه المسار الكامل للمفسر الذي اختاره المحرر، ولذلك إذا اختار المحرر مفسراً خارج البيئة الافتراضية فسوف ترى ModuleNotFoundError عند الضغط على الزر بينما الأمر اليدوي يعمل. والأدلة الرسمية Python في VS Code والطرفية المدمجة تشرح كل زر في هذه النافذة.

من الذي يشتكي؟ خريطة أخطاء البداية Errors

إذا جمعت كل الأخطاء التي ظهرت في التجربة ستجد أن أهم مهارة هي أن تعرف من الذي كتب الرسالة، لأن ذلك يحدد أين تبحث. فرسالة تبدأ بـ bash تعني أن المشكلة قبل أن يبدأ برنامجك، ورسالة تبدأ بـ python3 تعني أن المفسر بدأ ولم يجد شيئاً، ورسالة فيها Traceback أو SyntaxError تعني أن البيئة سليمة والمشكلة في الكود:

ست بطاقات لأخطاء البداية بحسب من يكتبها: الـ Shell لا يجد الأمر command not found برمز 127، والنظام يرفض التشغيل Permission denied برمز 126، وسطر الـ Shebang يشير إلى python3\r غير موجود، والمفسر لا يجد الملف can't open file برمز 2، والمفسر يرفض الكود SyntaxError برمز 1، والمكتبة غير مثبتة في البيئة ModuleNotFoundError
الكلمة الأولى في الرسالة تقول لك من كتبها، ورمز الخروج يؤكد ذلك

والجدول التالي يجمعها مع السبب والحل، وكلها رسائل حقيقية من التجربة:

الرسالةرمز الخروجمن كتبهاالسبب الأكثر شيوعاًالحل
command not found127الـ Shellالبرنامج غير مثبت، أو اسمه مختلف، أو مجلده ليس في PATHwhich -a أو type، ثم التثبيت أو تعديل PATH وفتح طرفية جديدة
Permission denied126الـ Shell بعد رفض النظامالملف بدون صلاحية التنفيذchmod +x أو التشغيل عبر المفسر
env: 'python3\r'127الأمر envالملف محفوظ بنهاية CRLFتحويله إلى LF من المحرر أو بـ sed
can't open file ... [Errno 2]2Pythonأنت في مجلد آخرpwd وls ثم cd
SyntaxError1Pythonخطأ في كتابة الكود، أو درس قديم لـ Python 2اقرأ السطر المشار إليه وآخر سطر في الرسالة
externally-managed-environment1pipمحاولة تثبيت مكتبة في Python النظامبيئة افتراضية python3 -m venv .venv
ensurepip is not available1Pythonحزمة python3-venv غير مثبتة على Debian وUbuntuapt install python3-venv
ModuleNotFoundError1Pythonالمكتبة في بيئة أخرى أو لم تثبتفعل البيئة الصحيحة، واختر نفس المفسر في المحرر
الإصدار القديم يعمل بعد التثبيت0لا أحدنسختان على الجهاز والقديمة أسبق في PATHwhich -a أو where، ثم ترتيب PATH

وعندما تصل إلى رسائل من النوع الأخير في الخريطة، أي أخطاء الكود نفسه، تبدأ مهارة أخرى هي قراءة الـ Traceback وتتبع الخطأ، وسوف نخصص لها مقالاً كاملاً في هذه المرحلة.

خطوات التثبيت بحسب نظام التشغيل Operating System

التجربة كانت على Linux لأن نتائجها ثابتة ويمكن لأي قارئ أن يكررها، ولكن أغلب المبتدئين يبدؤون على Windows أو macOS. والجدول التالي يلخص أنسب طريقة لكل نظام، مع ما يجب أن تتأكد منه بعد التثبيت:

النظامPythonNodeالطرفيةانتبه إلى
WindowsPython install manager من python.org أو من متجر Microsoft، ثم الأمر py أو pythonالمثبت الرسمي من nodejs.orgWindows Terminal مع PowerShell، أو WSLأمر python قد يفتح المتجر إذا لم يكن Python مثبتاً، وتعديل PATH يحتاج طرفية جديدة، ونهاية السطر CRLF
macOSالمثبت الرسمي من python.org، أو Homebrewالمثبت الرسمي، أو nvmTerminal مع zshالأمر هو python3، ولا يوجد python بعد حذف Python 2.7
Ubuntu وDebianapt install python3 python3-venv python3-pipالنسخة الرسمية أو nvm بدل نسخة التوزيعة القديمةأي طرفية مع bashلا تثبت مكتبات بـ pip خارج بيئة افتراضية
WSL داخل Windowsمثل Ubuntuمثل UbuntuWindows Terminalاعمل على ملفات داخل نظام ملفات Linux وليس في /mnt/c لأن الوصول هناك أبطأ بحسب توصية Microsoft

وبعد أي تثبيت، وعلى أي نظام، نفذ نفس الفحص الذي بدأنا به التجربة: python3 --version أو python --version، وnode --version، وnpm --version، ثم which -a لكل منها (أو where في Windows) لتعرف من أين يأتي كل أمر. فإذا ظهرت لك الأرقام التي تتوقعها فبيئتك جاهزة.

أخطاء شائعة في الأيام الأولى

  • إعادة تثبيت اللغة عند كل خطأ: أغلب الأخطاء التي رأيتها في هذا المقال لا علاقة لها بالتثبيت، وإنما بالمجلد الحالي أو PATH أو البيئة الافتراضية، وإعادة التثبيت قد تضيف نسخة ثالثة تزيد المشكلة.
  • تشغيل الكود قبل حفظه: الطرفية تشغل الملف المحفوظ على القرص، والنقطة التي تظهر بجانب اسم الملف في تبويب VS Code بدل علامة الإغلاق تعني أن فيه تعديلات لم تحفظ.
  • نسخ أوامر sudo pip install من الإنترنت: هذا يتجاوز الحماية التي رأيناها في PEP 668 وقد يعطل أدوات النظام، والخيار --break-system-packages الذي تقترحه الرسالة اسمه وحده تحذير.
  • تثبيت عشرات الإضافات في VS Code من اليوم الأول: كل إضافة برنامج يعمل بصلاحياتك ويستهلك من الذاكرة، وابدأ بإضافة اللغة التي تتعلمها فقط.
  • تعلم البرمجة داخل مجلدات فيها مسافات وحروف عربية في الاسم: أغلب الأدوات تتعامل معها اليوم، ولكن بعض السكربتات القديمة تفشل بسببها برسائل غامضة، واختيار اسم مثل projects/hello يوفر عليك ذلك.
  • الاعتماد الكامل على زر التشغيل: إذا لم تعرف الأمر الذي يكتبه الزر فلن تعرف ماذا تفعل عندما يفشل، أو عندما تحتاج تشغيل نفس البرنامج على سيرفر لا يوجد فيه محرر.

قائمة التحقق قبل أن تبدأ الدروس Checklist

الفحصالأمرالنتيجة المطلوبة
إصدار Pythonpython3 --version أو py --versionإصدار من سلسلة 3
إصدار Node وnpmnode --version وnpm --versionإصدار LTS حالي، وnpm موجود
من أين يأتي كل أمرwhich -a python3 node أو where python nodeنسخة واحدة لكل أمر، أو تعرف لماذا توجد اثنتان
المجلد الحاليpwd ثم lsترى ملف البرنامج في القائمة
البيئة الافتراضيةpython3 -m venv .venv ثم التفعيل ثم which pythonالمسار داخل .venv
المحررVS Code مع إضافة اللغة، والمجلد مفتوح كاملاًالمفسر في شريط الحالة هو مفسر البيئة
نهاية السطرشريط الحالة في VS CodeLF للسكربتات التي ستعمل على Linux
الحفظ التلقائيFile ثم Auto Saveمفعل

تدريب عملي

  1. اكتب سكربت greet بالـ Shebang على جهازك، واجعله يعمل باسمه من أي مجلد، ثم أغلق الطرفية وافتح غيرها وتأكد أنه ما زال يعمل. إذا لم يعمل فراجع قسم الـ Shebang وملف ~/.bashrc.
  2. أنشئ مشروعين، في كل منهما بيئة افتراضية، وثبت في الأول requests وفي الثاني لا شيء، ثم افتح كل مشروع في VS Code وتأكد أن الخط الأحمر تحت import requests يظهر في الثاني فقط.
  3. اكتب على جهازك الأمر which -a python3 node (أو where python node في Windows)، واكتب بجانب كل سطر من أين أتت هذه النسخة.

حذف المختبر Cleanup

التجربة عملت داخل Container بالخيار --rm، فيحذف نفسه عند انتهائه بكل ما ثبتناه فيه، ولا يبقى إلا الـ Image الأساسية التي نزلها Docker، واحذفها إذا لم تكن تحتاجها:

docker rmi debian:trixie-slim

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • بيئة البرمجة ثلاثة أجزاء حول ملف نصي: محرر تكتب فيه، وطرفية تشغل منها، ومشغل اللغة الذي يقرأ الملف وينفذه، والمحرر لا يشغل شيئاً بنفسه.
  • VS Code اختيار مناسب للبداية لأنه مجاني ويعمل على كل الأنظمة ويستخدمه 75.9% من المطورين بحسب استبيان Stack Overflow لعام 2025، وأضف إليه إضافة لغتك فقط.
  • الطرفية تبحث عن كل أمر في مجلدات PATH بالترتيب، فإذا لم تجده كتبت command not found برمز 127، وإذا وجدت نسختين شغلت الأسبق.
  • الأمر python3 هو الاسم الآمن على Linux وmacOS لأسباب تاريخية، وفي Windows python أو py، وتأكد دائماً بـ --version.
  • المجلد الحالي يحدد أين يبحث البرنامج عن ملفك، وpwd وls يحلان أغلب أخطاء الأسبوع الأول.
  • مكتبات Python تثبت في بيئة افتراضية لكل مشروع، والتفعيل ليس إلا إضافة مجلدها إلى أول PATH.
  • حرف \r الذي يضيفه Windows في نهاية السطر يوقف سكربتات Linux، واحفظ ملفاتك بنهاية LF.

وفي المقالات التالية من هذه المرحلة سوف نستخدم هذه البيئة لنكتب أول برامج حقيقية: كيف تفكر في المشكلة قبل أن تكتب الكود، ثم المتغيرات والشروط والحلقات والدوال بلغتي Python وJavaScript جنباً إلى جنب، ثم كيف تقرأ رسالة الخطأ وتصحح برنامجك. أما إذا أردت أن تعرف ما يحدث داخل الجهاز بعد أن يبدأ برنامجك فهذه مقالات مرتبطة:

دليلماذا يحدث عندما تشغل برنامج Hello World؟نتتبع برنامج C صغيراً من المحرر إلى الشاشة، فترى كل طبقة يمر بها في الجهاز حتى تظهر الجملة أمامك.دليلسطر الأوامر في Linux للمبتدئين: أول ما تحتاجه على السيرفركيف تتنقل بين الملفات على السيرفر، وتربط الأوامر ببعضها، وتتحكم في العمليات Processes دون أن تحذف شيئاً بالخطأ.دليلإدارة النسخ وGit للمبتدئين: لماذا نحتاجها وكيف تعمللماذا تضيع الملفات بأسماء final_v2 ويمسح الزملاء عمل بعضهم، وكيف يحل Git ذلك على مشروع حقيقي من أول commit.

سجل التحديثات

  • أكتوبر 2026: كتابة المقال، وتنفيذ التجربة داخل Container من Debian 13.7 (trixie) مع Python 3.13.5 من التوزيعة وrequests 2.34.2، وNode 20.19.2 من التوزيعة وNode 26.13.0 مع npm 11.20.0 من الموقع الرسمي، وصور VS Code من openvscode-server 1.109.5، على Docker Engine 29.8.0.
Could not load content
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.