Linux: متغيرات البيئة وPATH — ضبط بيئة التطوير الخاصة بك
متغيرات البيئة هي أزواج مفتاح-قيمة يستخدمها نظام التشغيل لتخزين الإعدادات. هي تحدد أين تبحث الصدفة عن الأوامر (PATH)، وما اللغة المستخدمة (LANG)، وأي محرر يُستخدم (EDITOR).
📋 المتطلبات المسبقة: يجب إكمال
- الدرس 9: إدارة المستخدمين والمجموعات
1. ما ستتعلمه
- دور متغيرات البيئة
- كيف يعمل PATH
- عمليات export وunset
- ترتيب تحميل ملفات إعدادات Shell
- إضافة أدوات جديدة إلى PATH
2. قصة "command not found"
(1) الألم: ثبّت برنامجًا لكن لا يجده
ثبّت شياو مينغ أداة Python httpie بـpip install --user، لكن كتابة http أعطت:
http example.com
# Command 'http' not found
تساءل شياو مينغ: "ثبّته، فلماذا لا يجده النظام؟"
(2) PATH — إخبار Shell أين يبحث عن البرامج
شرح بوب: "البرنامج مثبت، لكن Shell لا يعرف أين يبحث. متغير البيئة PATH هو 'خريطة كنز' Shell."
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ~/.local/bin ليس في PATH، لذا Shell لا يجد http
ls ~/.local/bin/http*
# /home/charlie/.local/bin/http
# أضف ~/.local/bin إلى PATH
export PATH="$PATH:$HOME/.local/bin"
http example.com # يعمل الآن
(3) الفائدة: فهم الآلية الكامنة وراء كل شيء
تعلّم شياو مينغ أن وضع export PATH="$PATH:~/bin" في .bashrc يجعله دائمًا. الآن كلما ثبّت أداة جديدة، يعرف أن يفحص إن كان دليل التثبيت في PATH.
3. نقاط المعرفة
(1) ما هي متغيرات البيئة
متغيرات البيئة هي أزواج مفتاح-قيمة مخزّنة في نظام التشغيل يرثها كل العمليات الفرعية.
# عرض كل متغيرات البيئة
printenv
# عرض متغيرات فردية
echo $HOME
echo $USER
echo $SHELL
echo $LANG
echo $PWD
متغيرات البيئة الشائعة:
| المتغير | المعنى | القيمة النموذجية |
|---|---|---|
HOME |
الدليل المنزلي للمستخدم الحالي | /home/alice |
USER |
اسم المستخدم الحالي | alice |
SHELL |
مسار Shell الحالي | /bin/bash |
PATH |
مسار بحث الأوامر | /usr/bin:/bin:/usr/local/bin |
LANG |
اللغة والترميز | en_US.UTF-8 |
PWD |
دليل العمل الحالي | /home/alice/projects |
OLDPWD |
دليل العمل السابق | /etc |
EDITOR |
المحرر الافتراضي | vim |
(2) PATH — مسار بحث الأوامر
عندما تكتب ls، يبحث Shell عن برنامج ls في كل دليل مُدرج في PATH، بالترتيب. إذا وجده، ينفذه؛ إذا لم يجده، يُبلغ عن command not found.
# عرض PATH الحالي
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# إيجاد أي دليل يحتوي الأمر
which ls
# /usr/bin/ls
# عرض كل المواقع المحتملة لأمر (بما فيها الأسماء المستعارة والدوال)
type ls
# ls is aliased to `ls --color=auto'
(3) تعيين وإلغاء متغيرات البيئة
# تعيين مؤقت (فعّال في Shell الحالي فقط)
MY_VAR="hello"
# تصدير كمتغير بيئة (العمليات الفرعية يمكنها الوصول إليه)
export MY_VAR="hello"
# تعيين وتصدير في أمر واحد
export MY_VAR="hello"
# إلغاء متغير بيئة
unset MY_VAR
# تعيين مؤقت لأمر واحد (بدون تلويث البيئة الحالية)
LANG=ja_JP.UTF-8 date
(4) ترتيب تحميل ملفات إعدادات Shell
فهم ترتيب التحميل مهم — يفسر لماذا أحيانًا لا تسري تغييرات ~/.bashrc:
Login Shell (ولوج SSH، ولوج tty):
/etc/profile
~/.bash_profile (إذا كان موجودًا، يُتجاوز التاليان)
~/.bash_login
~/.profile
Non-login Shell (فتح طرفية جديدة):
/etc/bash.bashrc
~/.bashrc
ℹ️ ملاحظة:
.bashrcو.profileيُحمَّلان في أوقات مختلفة — ولوج SSH يحمّل.profile، بينما فتح طرفية جديدة يحمّل.bashrc. أفضل ممارسة هي إضافةsource ~/.bashrcفي.profileووضع كل الإعدادات في.bashrc، لكي يعمل ذلك بغض النظر عن طريقة الولوج.
أفضل ممارسة: أضف هذا إلى .bash_profile:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
ثم ضع كل الإعدادات المخصصة في .bashrc.
(5) ▶ مثال: عرض وتعيين متغيرات البيئة
# عرض متغيرات البيئة
echo "My home directory is: $HOME"
echo "Current user: $USER"
echo "My Shell: $SHELL"
# تعيين متغير مؤقت
export GREETING="Hello from Linux"
echo $GREETING
# افتح نافذة طرفية جديدة وتحقق هل $GREETING لا يزال موجودًا
# الجواب: لا — المتغيرات المؤقتة موجودة في Shell الحالي فقط
الإخراج:
TEXTMy home directory is: /home/alice Current user: alice My Shell: /bin/bash Hello from Linux
(6) ▶ مثال: فهم PATH
# عرض PATH الحالي
echo $PATH | tr ':' '\n' # عرض مسار واحد في كل سطر
# إيجاد من أي دليل يُحمَّل ls
which ls
# /usr/bin/ls
# ماذا يحدث إذا كان PATH خاطئًا؟
PATH="" # إفراغ PATH (خطير!)
ls
# bash: ls: No such file or directory
# استعادة PATH
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
الإخراج:
TEXT/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/bin/ls
(7) ▶ مثال: إضافة ~/scripts إلى PATH (دائم)
# إنشاء دليل سكريبتات خاص بك
mkdir -p ~/scripts
# إضافة ~/scripts إلى PATH (اكتب في .bashrc)
echo 'export PATH="$PATH:$HOME/scripts"' >> ~/.bashrc
> 💡 نصيحة: لجعل متغيرات البيئة دائمة، يجب كتابة أمر `export` في `~/.bashrc` (أو `~/.profile`). بعد التعديل، شغّل `source ~/.bashrc` للتطبيق الفوري؛ وإلا ستُحمَّل الإعدادات الجديدة في الطرفيات المفتوحة حديثًا فقط.
# إعادة التحميل
source ~/.bashrc
# التحقق
echo $PATH | tr ':' '\n' | grep scripts
# /home/alice/scripts
الإخراج:
TEXT/home/alice/scripts
(8) ▶ مثال: إعدادات متغيرات بيئة التطوير الشائعة
# أضف ما يلي إلى ~/.bashrc
# المحرر الافتراضي
export EDITOR=vim
# اللغة
export LANG=en_US.UTF-8
# تطوير Python
export PYTHONSTARTUP=~/.pythonrc # سكريبت بدء Python التفاعلي
export PIP_REQUIRE_VIRTUALENV=true # pip يتطلب بيئة افتراضية
# تطوير Node.js
export NODE_ENV=development
export npm_config_prefix=~/.npm-global
# تطوير Go
export GOPATH=$HOME/go
export PATH="$PATH:$GOPATH/bin"
# سكريبتاتك الخاصة
export PATH="$PATH:$HOME/scripts"
export PATH="$PATH:$HOME/.local/bin"
الإخراج:
TEXTEDITOR=vim LANG=en_US.UTF-8 PYTHONSTARTUP=/home/alice/.pythonrc PIP_REQUIRE_VIRTUALENV=true NODE_ENV=development GOPATH=/home/alice/go
(9) ▶ مثال: التحقق إن كان يمكن إيجاد أمر
# استخدم which لإيجاد مسار الأمر
which python3
# /usr/bin/python3
# استخدم type لفحص نوع الأمر (اسم مستعار/دالة/مدمج/خارجي)
type ls
# ls is an alias for `ls --color=auto'
type cd
# cd is a shell builtin
type node
# node is /usr/bin/node
# استخدم command -v (الطريقة الأكثر موثوقية)
command -v python3
# /usr/bin/python3
الإخراج:
TEXT/usr/bin/python3 ls is an alias for `ls --color=auto' cd is a shell builtin node is /usr/bin/node /usr/bin/python3
(10) ▶ مثال شامل: تصحيح مشكلة "command not found"
#!/bin/bash
# debug-path.sh - تصحيح مشاكل command-not-found
CMD="${1:-http}"
echo "=== 1. What is the command ==="
type "$CMD" 2>/dev/null || echo "type: $CMD not found"
echo ""
echo "=== 2. Which PATH directories contain this command ==="
IFS=':' read -ra PATHS <<< "$PATH"
for dir in "${PATHS[@]}"; do
if [ -f "$dir/$CMD" ]; then
echo "Found: $dir/$CMD"
fi
done
echo ""
echo "=== 3. Global search with find ==="
find /usr /opt $HOME -name "$CMD" -type f 2>/dev/null | head -5
echo ""
echo "=== 4. If found but not in PATH ==="
echo "Run: export PATH=\"\$PATH:/found/directory\""
❓ أسئلة شائعة
س: هل ترتيب PATH مهم؟ ج: جدًا! يبحث Shell في دلائل PATH بالترتيب ويتوقف عند أول تطابق. إذا كان
/usr/local/binأولًا، يتقدم على/usr/bin. لهذا البرامج المثبتة حديثًا أحيانًا تشغّل إصدارًا أقدم — تحقق من ترتيب PATH.
س: هل تختفي متغيرات البيئة بعد إعادة التشغيل؟ ج: المتغيرات المؤقتة المعينة بـ
exportستُفقد بعد إعادة التشغيل. لجعلها دائمة، اكتب أوامرexportفي ملف إعدادات Shell (~/.bashrcأو~/.bash_profile).
س: أيهما يُنفَّذ أولًا،
.bashrcأم.bash_profile؟ ج: Shell الولوجي:/etc/profile→~/.bash_profile→~/.bash_login→~/.profile(إذا لم تكن الملفات السابقة موجودة). Shell غير الولوجي:/etc/bash.bashrc→~/.bashrc.
س: كيف أضبط متغيرات بيئة عامة (لكل المستخدمين)؟ ج: اكتب في
/etc/environment(أزواج مفتاح-قيمة بسيطة، بدون سكريبت) أو/etc/profile.d/custom.sh(يدعم صياغة Shell، يتطلب صلاحيات جذر).
س: ما الفرق بين
printenvوset؟ ج:printenvيعرض فقط متغيرات البيئة (المُصدَّرة).setيعرض كل المتغيرات بما فيها المتغيرات المحلية لـShell والدوال. استخدمprintenvلعرض البيئة الكاملة، وsetلتصحيح السكريبتات.
📖 ملخص
- متغيرات البيئة أزواج مفتاح-قيمة على مستوى النظام؛ العمليات الفرعية ترث متغيرات بيئة العملية الأم
export VAR=valueيعيّن ويصدر؛unset VARيزيل- PATH يحدد مسارات بحث الأوامر؛ الترتيب يحدد أي إصدار له الأولوية
which cmd/type cmdلإيجاد مواقع الأوامر- الإعدادات توضع في
~/.bashrc(Shell غير الولوجي) أو~/.profile(Shell الولوجي) - بعد تعديل ملفات الإعدادات، شغّل
source ~/.bashrcللتطبيق الفوري
📝 تمارين
- أساسي (صعوبة ⭐): اعرض PATH الحالي (استخدم
tr ':' '\n'لعرض أوضح سطرًا بسطر)، واستخدمwhich python3وtype cdلفهم أنواع الأوامر - متوسط (صعوبة ⭐⭐): أنشئ دليل
~/scripts، اكتب سكريبتhello.shبسيط، أضفه إلى PATH وشغّله مباشرة؛ اضبطEDITOR=vim(أوnano) في.bashrcوتحقق بـsource - متقدم (صعوبة ⭐⭐⭐): اكتب سكريبت
debug-path.shيأخذ اسم أمر كمعامل ويتحقق تلقائيًا إن كان في PATH، وأي دليل يحتويه، ويقترح إصلاحًا إن لم يكن في PATH