Skip to content

متغيرات البيئة و PATH

💡 دليل التعلم: في كل مرة تكتب فيها git أو python في الطرفية، يجب على النظام البحث عن مكان هذا البرنامج. وكلما استدعى كودك واجهة برمجة تطبيقات نموذج لغوي كبير، يحتاج البرنامج لمعرفة أي مفتاح يستخدم. كلتا المسألتين تعتمدان على نفس الآلية — متغيرات البيئة.


0. كل برنامج يحمل معه مجموعة من الإعدادات

كل برنامج قيد التشغيل يحمل مجموعة إعدادات على شكل «مفتاح=قيمة» تُسمى متغيرات البيئة. يمكن للبرنامج قراءة هذه الإعدادات في أي وقت لفهم بيئة التشغيل الحالية.

انقر على أي متغير في القائمة أدناه لـ "عرض" قيمته في الطرفية:

Environment Variable BrowserClick any variable row to inspect its value and purpose in the terminal
VariableExample value
HOME/Users/alice
USERalice
SHELL/bin/zsh
PATH/usr/local/bin:/usr/bin:/bin
PWD/Users/alice/projects
LANGen_US.UTF-8
NODE_ENVdevelopment
OPENAI_API_KEYsk-••••••••••••••••
bash
← Click any variable on the left to inspect it
$
Core concept:Environment variables are key=value configuration owned by each process. A program inherits a copy from its parent process at startup. You can inspect them with echo $VARIABLE and set them with export KEY=value.

1. PATH: كيف يجد Shell الأوامر التي تكتبها

PATH هو متغير بيئة خاص يخزن قائمة مسارات أدلة (مفصولة بنقطتين). عند كتابة git، يمر Shell عبر هذه الأدلة بالترتيب بحثاً عن ملف تنفيذي اسمه git — ويتوقف عند إيجاد الأول.

bash
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

اختر أمراً ولاحظ عملية البحث دليلاً بدليل:

PATH Search ProcessEnter a command name and see how the shell searches directories
Choose command:
Current PATH:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
/usr/local/bin
Waiting
/usr/bin
Waiting
/bin
Waiting
/usr/sbin
Waiting
/sbin
Waiting
Core mechanism:After the shell receives a command name, it searches directories in PATH order. The first match wins and the search stops. That makes PATH order important: earlier directories have higher priority.

ثلاث قواعد أساسية:

  • الدليل الأقرب لبداية PATH له الأولوية الأعلى
  • يتوقف عند إيجاد التطابق الأول دون إكمال البحث
  • إذا لم يوجد في أي دليل ← command not found

2. لماذا يجب إعادة تشغيل الطرفية بعد تثبيت أداة؟

عند تثبيت أدوات مثل nvm أو Homebrew أو conda، يضيف سكربت التثبيت تلقائياً سطراً في ~/.zshrc لإدراج دليله في PATH:

bash
# محتوى يُكتب تلقائياً بواسطة سكربت التثبيت (مثال)
export PATH="/usr/local/opt/python@3.12/bin:$PATH"

هذا السطر يُنفذ فقط عند بدء Shell جديد. نوافذ الطرفية المفتوحة لا تتأثر، لذا:

bash
# بدون إعادة تشغيل يمكن جعله سارياً فوراً
source ~/.zshrc

مواقف شائعة مع أدوات تطوير الذكاء الاصطناعي:

bash
# Ollama / pipx مثبتان لكن تعطي command not found
which ollama          # عرض موقع التثبيت الفعلي

# مسار أدوات CLI المثبتة بـ pip (أضف إلى PATH)
# macOS: ~/Library/Python/3.x/bin
# Linux: ~/.local/bin
export PATH="$PATH:$HOME/.local/bin"

# يُنصح باستخدام pipx لتثبيت أدوات سطر الأوامر، يدير PATH تلقائياً
pipx install aider-chat

3. نطاق المتغيرات: من يمكنه رؤية هذا المتغير؟

متغيرات البيئة لا تُبث لجميع البرامج — كل عملية تمتلك نسختها الخاصة، موروثة من العملية الأصلية. تعديل نسختك لا يؤثر على العملية الأصلية.

المخطط التالي يوضح ثلاث مستويات. على "مستوى المستخدم"، صدّر متغيراً جديداً وتحقق من ظهوره على "مستوى العملية":

Three Levels of Environment VariablesVariables flow one way from outer scopes to inner scopes; child processes inherit a copy from parents
🖥️
System level /etc/environment
Visible to all users and processes; configured by an administrator
PATH=/usr/local/bin:/usr/bin:/bin
LANG=zh_CN.UTF-8
TZ=Asia/Shanghai
▼ Child process inherits the parent environment
👤
User level ~/.zshrc
Affects only the current user and is loaded when the login shell starts
HOME=/Users/alice
SHELL=/bin/zsh
NVM_DIR=$HOME/.nvm
=
▼ Start a child process, such as node app.js
⚙️
Process level (currently running program)
Inherits variables from upper levels, disappears on exit, and does not modify the parent process
PATH=/usr/local/bin:/usr/bin:/bin
LANG=zh_CN.UTF-8
TZ=Asia/Shanghai
HOME=/Users/alice
SHELL=/bin/zsh
NVM_DIR=$HOME/.nvm
NODE_ENV=development
PORT=3000
One-way flow:Variables are inherited downward only. Changing a variable in a child process does not affect its parent. Variables set with export in a terminal also disappear when that terminal closes.

4. export: يحدد ما إذا كانت العملية الفرعية يمكنها قراءة هذا المتغير

عند تعيين متغير، إضافة export أو عدم إضافتها تحدث فرقاً جوهرياً:

export Decides Whether Child Processes Can See a VariableToggle the switch and observe whether the child process can read a variable set by the parent
Parent process (Shell)
$MY_VAR="hello"
$echo $MY_VAR
hello
$bash -c 'echo $MY_VAR'
Start child process
Variable not inherited
Child process (bash -c ...)
$echo $MY_VAR
(empty output)
#A child process cannot modify parent variables
Without export: The variable exists only in the current shell, so the child process reads an empty string.

لجعل المتغير دائماً بين الجلسات، اكتب export في ملف التهيئة:

bash
# macOS (zsh)
echo 'export MY_VAR="value"' >> ~/.zshrc
source ~/.zshrc       # يسري فوراً دون إعادة فتح الطرفية

# Linux (bash)
echo 'export MY_VAR="value"' >> ~/.bashrc
source ~/.bashrc

5. مفاتيح API: لا تكتبها أبداً في الكود

عند استدعاء واجهات برمجة التطبيقات مثل OpenAI و Anthropic و DeepSeek، المفتاح هو "هويتك + بطاقتك الائتمانية". في حالة تسربه، يمكن للآخرين استخدام حصتك وأنت تدفع الفاتورة.

الخطأ الأكثر شيوعاً هو كتابة المفتاح مباشرة في الكود:

Hard-coded Keys vs Environment VariablesThe same feature, two implementations, completely different security outcomes
Dangerous: key written in code
# Python
import openai
 
client = openai.OpenAI(
api_key="sk-proj-abc123..."
)
💀After git push, the key is public on GitHub
💀Crawlers can find it quickly and generate costs
💀GitHub Secret Scanner may revoke the key automatically
💀Deleting the commit is not enough because Git history keeps it
Correct: read from environment variable
# Python
import openai, os
 
client = openai.OpenAI(
api_key=os.environ.get("OPENAI_API_KEY")
)
The code contains no secret and can be open-sourced safely
Development, testing, and production can use different keys
If a key leaks, regenerate it without changing code
Team members can use separate keys without affecting each other
Golden rule:A secret string in code means the secret is already leaked. GitHub Secret Scanner can detect prefixes such as sk- shortly after a push and notify providers to revoke them. Even if you delete the commit, Git history still contains it.

6. التطوير المحلي: استخدم ملف .env لإدارة المفاتيح

في التطوير المحلي، ضع المفاتيح في ملف .env في جذر المشروع؛ يقرأ الكود المفاتيح عبر مكتبة dotenv. يجب إضافة .env إلى .gitignore ولا يجب رفعه أبداً إلى Git.

اكتب الإعدادات على اليمين واقرأها على اليسار — بدّل اللغة لمشاهدة كلتا الطريقتين:

.env File + Code ReadingConfiguration on the left, code on the right; the variable name is the only link
📄 .env Do not commit
# Local development config, do not commit to Git
OPENAI_API_KEY=sk-proj-abc123...
DATABASE_URL=postgresql://localhost/dev
PORT=3000
NODE_ENV=development
📋 .env.example Can commit
# Copy to .env and fill in real values
OPENAI_API_KEY=(leave empty)
DATABASE_URL=(leave empty)
PORT=(leave empty)
NODE_ENV=(leave empty)
💻 main.py
# pip install python-dotenv openai
from dotenv import load_dotenv
import os, openai
 
load_dotenv() # Read .env file
 
client = openai.OpenAI(
api_key=os.environ.get("OPENAI_API_KEY")
)
 
db = os.environ.get("DATABASE_URL")
port = int(os.environ.get("PORT", 8000))
Values actually read by the program
OPENAI_API_KEYsk-proj-abc123...
DATABASE_URLpostgresql://localhost/dev
PORT3000
Workflow:load_dotenv() / import 'dotenv/config' reads the .env file at startup, injects its key-value pairs into the process environment, and the code reads them with os.environ or process.env. The two sides are connected only by variable names.

7. بيئة الإنتاج: دع منصة التشغيل تحقن المفاتيح

.env هي أداة ملائمة لمرحلة التطوير. على الخوادم والمنصات السحابية، يجب أن تتحمل بيئة التشغيل مسؤولية حقن المفاتيح؛ الكود نفسه لا يحتاج لمعرفة مكان تخزينها:

How Production Injects Secrets.env is a development convenience; servers should not rely on it
/etc/systemd/system/myapp.service
# Recommended: use a separate secret file with controlled permissions
[Service]
EnvironmentFile=/etc/myapp/secrets.env
ExecStart=/usr/bin/node /app/index.js
# Set file permissions so only the owner can read it
sudo chmod 600 /etc/myapp/secrets.env
sudo chown deploy:deploy /etc/myapp/secrets.env
# Reload configuration and restart the service
sudo systemctl daemon-reload
sudo systemctl restart myapp
After chmod 600, only the deploy user can read the secret file; other accounts cannot access it
Secrets are separated from code, so rotating a key does not require redeploying code
Avoid writing Environment="KEY=val" directly in the systemd file; it requires reloads and leaves plaintext in config
Principle:.env files are convenient for local development. In production, the runtime platform should inject environment variables, while application code stays unaware of where secrets live or how they arrived.

8. استكشاف الأخطاء العملي

command not found

bash
# الخطوة 1: تأكد من وجوده في PATH
which python3         # إذا ظهر ناتج فقد وُجد

# الخطوة 2: ابحث عن الموقع الفعلي للبرنامج (macOS)
brew list python | grep bin

# الخطوة 3: أضف الدليل إلى PATH
export PATH="/المسار/الموجود:$PATH"
source ~/.zshrc       # تذكر source بعد الكتابة في ملف التهيئة

مثبت إصداران لكنه لا يستخدم الذي أريده

bash
which python
# /usr/bin/python ← الإصدار القديم من النظام، أقرب في PATH

# ضع دليل الإصدار الجديد في بداية PATH
export PATH="/usr/local/bin:$PATH"

which python
# /usr/local/bin/python ← الإصدار الجديد، أصبح له الأولوية الآن

المتغير معين لكن البرنامج لا يقرأه

السببالحل
نسيت exportأضف export وحاول مجدداً
عدّلت ~/.zshrc لكن لم يُسريsource ~/.zshrc
تستخدم .env لكن dotenv غير مثبتpip install python-dotenv / npm install dotenv
على الخادم يعمل فقط في جلسة SSHاستخدم EnvironmentFile من systemd

مسرد المصطلحات

المصطلحالمعنى
PATHيخزن قائمة الأدلة حيث يبحث Shell عن الملفات التنفيذية، مفصولة بنقطتين، الترتيب يحدد الأولوية
exportيحدد المتغير كقابل للتوريث؛ العمليات الفرعية تحصل تلقائياً على نسخة عند البدء
sourceيُعيد تنفيذ ملف التهيئة في Shell الحالي، مما يجعل التغييرات سارية فوراً
whichيعرض مسار الملف التنفيذي المقابل لأمر (نتيجة البحث في PATH)
.envملف تهيئة محلي للمشروع، يخزن مفاتيح التطوير؛ يجب إضافته إلى .gitignore
.env.exampleقالب بأسماء متغيرات كاملة وقيم فارغة؛ يمكن رفعه إلى Git بأمان
chmod 600صلاحيات الملف: فقط المالك يمكنه القراءة والكتابة؛ مناسب لحماية ملفات المفاتيح
Secret Scannerفحص تلقائي لتسريبات المفاتيح على GitHub وغيرها؛ يُبلغ الموردين للإلغاء