Node.js: وحدتا os و process

آخر تحديث: 2026-08-26

أليس هي مهندسة DevOps مسؤولة عن إدارة عشرات الخوادم. في كل مرة تقوم فيها بنشر تطبيق جديد، يتعين عليها تسجيل الدخول يدويًّا إلى الخوادم للتحقق من القيم العددية لنوى وحدة المعالجة المركزية (CPU) والذاكرة المتاحة وإصدار نظام التشغيل، ثم تغيير الإعدادات بناءً على متغيرات البيئة. خلال عملية نشر طارئة في الساعة 3 صباحًا في أحد الأيام، فاتتها مشكلة نقص الذاكرة أثناء فحوصاتها اليدوية، مما تسبب في فشل عملية النشر. لذلك قررت كتابة برنامج نصي للكشف التلقائي بلغة Node.js لاسترداد معلومات موارد الخادم والبيئة بنقرة واحدة، لضمان سير عمليات النشر المستقبلية بسلاسة.

1. ما ستتعلمه



2. الوحدة النمطية os: جمع معلومات النظام

(1) معلومات عن وحدة المعالجة المركزية والذاكرة

تُرجع الدالة os.cpus() مصفوفة تحتوي على تفاصيل نوى وحدة المعالجة المركزية (CPU)؛ بينما تُرجع الدالتان os.totalmem() وos.freemem() إجمالي الذاكرة والذاكرة المتاحة، على التوالي (بالبايت).

▶ مثال: التحقق من وحدة المعالجة المركزية (CPU) والذاكرة في الخادم

JAVASCRIPT
const os = require('os');

const cpus = os.cpus();
console.log(`CPU Number of cores: ${cpus.length}`);
console.log(`CPU Model: ${cpus[0].model}`);

const totalMem = os.totalmem();
const freeMem = os.freemem();
const usedPercent = ((totalMem - freeMem) / totalMem * 100).toFixed(1);

console.log(`Total Memory: ${(totalMem / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Available memory: ${(freeMem / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Memory Usage: ${usedPercent}%`);
▶ جرّب الكود
TEXT 📖 للعرض فقط
CPU Number of cores: 8
CPU Model: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
Total Memory: 15.88 GB
Available memory: 6.23 GB
Memory Usage: 60.7%

(2) معرّف نظام التشغيل

تُرجع os.platform() معرّف النظام الأساسي (على سبيل المثال، win32، linux، darwin)؛ وتُرجع os.type() اسم نظام التشغيل؛ وتُرجع os.arch() بنية وحدة المعالجة المركزية؛ وتُرجع os.hostname() اسم المضيف.

▶ مثال: استرداد معلومات نظام التشغيل

JAVASCRIPT
const os = require('os');

console.log(`Platform: ${os.platform()}`);
console.log(`System Type: ${os.type()}`);
console.log(`CPU Architecture: ${os.arch()}`);
console.log(`Hostname: ${os.hostname()}`);
console.log(`System Version: ${os.version()}`);
▶ جرّب الكود
TEXT 📖 للعرض فقط
Platform: linux
System Type: Linux
CPU Architecture: x64
Hostname: web-server-01
System Version: #1 SMP Thu Jan 1 00:00:00 UTC 2026

(3) معلومات المستخدم والدليل

os.userInfo() تُرجع معلومات المستخدم الحالي؛ os.homedir() تُرجع الدليل الرئيسي للمستخدم؛ os.tmpdir() تُرجع دليل الملفات المؤقتة.

▶ مثال: استرداد معلومات المستخدم والدليل

JAVASCRIPT
const os = require('os');

const userInfo = os.userInfo();
console.log(`Username: ${userInfo.username}`);
console.log(`Home Directory: ${os.homedir()}`);
console.log(`Shell: ${userInfo.shell}`);
console.log(`Temporary Directory: ${os.tmpdir()}`);
▶ جرّب الكود
TEXT 📖 للعرض فقط
Username: alice
Home Directory: /home/alice
Shell: /bin/bash
Temporary Directory: /tmp

(4) معلومات واجهة الشبكة

os.networkInterfaces() يعرض معلومات تفصيلية عن جميع واجهات الشبكة، بما في ذلك عناوين IP وعناوين MAC ومجموعات العناوين.

▶ مثال: عرض واجهات الشبكة

JAVASCRIPT
const os = require('os');

const interfaces = os.networkInterfaces();
for (const [name, addrs] of Object.entries(interfaces)) {
  for (const addr of addrs) {
    if (addr.family === 'IPv4' && !addr.internal) {
      console.log(`${name}: ${addr.address} (${addr.family})`);
    }
  }
}
▶ جرّب الكود
TEXT 📖 للعرض فقط
eth0: 192.168.1.100 (IPv4)
wlan0: 10.0.0.5 (IPv4)

(5) مرجع سريع لأساليب نظام التشغيل الشائعة

الطريقة نوع القيمة المرجعة الغرض
os.cpus() object[] مصفوفة معلومات نوى وحدة المعالجة المركزية
os.totalmem() number إجمالي الذاكرة (بايت)
os.freemem() number الذاكرة المتاحة (بايت)
os.platform() string معرّف النظام الأساسي (win32/linux/darwin)
os.type() string اسم نظام التشغيل
os.arch() string بنية وحدة المعالجة المركزية (x64/arm64)
os.hostname() string اسم المضيف
os.userInfo() object معلومات المستخدم الحالي
os.homedir() string مسار الدليل الرئيسي للمستخدم
os.tmpdir() string مسار دليل الملفات المؤقتة
os.networkInterfaces() object معلومات واجهة الشبكة
os.uptime() number مدة تشغيل النظام (بالثواني)
os.loadavg() number[] متوسط حمل النظام (1/5/15 دقيقة)
os.EOL string ثابت فاصل الأسطر
os.devNull string مسار الجهاز فارغ


3. وحدة process: التحكم في العمليات

(1) معلمات سطر الأوامر process.argv

process.argv عبارة عن مصفوفة؛ وargv[0] هو المسار إلى الملف القابل للتنفيذ لـ Node.js؛ وargv[1] هو المسار إلى البرنامج النصي الذي يتم تنفيذه؛ أما العناصر التالية فهي معلمات سطر الأوامر التي تم تمريرها.

100%
flowchart TD
    A["Command-Line Input<br/>node app.js --env prod --port 3000"] --> B["process.argv Array"]
    B --> C["argv[0]: Node.js Path<br/>/usr/local/bin/node"]
    B --> D["argv[1]: Script Path<br/>/home/alice/app.js"]
    B --> E["argv[2]: --env"]
    B --> F["argv[3]: prod"]
    B --> G["argv[4]: --port"]
    B --> H["argv[5]: 3000"]
    E --> I["Parameter Parsing Logic"]
    G --> I
    I --> J["{ env: 'prod', port: '3000' }"]

▶ مثال: تحليل معلمات سطر الأوامر

JAVASCRIPT
function parseArgs(argv) {
  const args = {};
  for (let i = 2; i < argv.length; i++) {
    if (argv[i].startsWith('--')) {
      const key = argv[i].slice(2);
      const value = argv[i + 1] && !argv[i + 1].startsWith('--')
        ? argv[++i]
        : true;
      args[key] = value;
    }
  }
  return args;
}

const config = parseArgs(process.argv);
console.log(config);
▶ جرّب الكود
BASH
node cli.js --env production --port 8080 --verbose
TEXT 📖 للعرض فقط
{ env: 'production', port: '8080', verbose: true }

(2) متغير البيئة process.env

process.env يحتوي على جميع أزواج المفاتيح والقيم الخاصة بمتغيرات البيئة، ويُعد الأساس الرئيسي الذي يعتمد عليه برنامج النص البرمجي الخاص بالنشر لتحديد بيئة التشغيل.

▶ مثال: قراءة متغيرات البيئة وتعيينها

JAVASCRIPT
console.log(`NODE_ENV: ${process.env.NODE_ENV || 'development'}`);
console.log(`PATH: ${process.env.PATH}`);

process.env.APP_MODE = 'production';
console.log(`APP_MODE: ${process.env.APP_MODE}`);
▶ جرّب الكود
TEXT 📖 للعرض فقط
NODE_ENV: development
PATH: /usr/local/bin:/usr/bin:/bin
APP_MODE: production

(3) إنهاء العملية ودليل العمل

process.exit(code) إنهاء العملية (تشير القيمة 0 إلى النجاح؛ أما القيم غير الصفرية فتشير إلى الفشل)، process.cwd() العودة إلى دليل العمل الحالي.

▶ مثال: الخروج المشروط والتحقق من الدليل

JAVASCRIPT
const requiredEnv = ['DATABASE_URL', 'APP_SECRET'];
const missing = requiredEnv.filter(key => !process.env[key]);

if (missing.length > 0) {
  console.error(`Missing required environment variables: ${missing.join(', ')}`);
  process.exit(1);
}

console.log(`Working Directory: ${process.cwd()}`);
console.log(`Process ID: ${process.pid}`);
console.log(`Runtime: ${process.uptime().toFixed(0)} seconds`);
▶ جرّب الكود
TEXT 📖 للعرض فقط
Missing required environment variables: DATABASE_URL, APP_SECRET

(4) تدفقات قياسية: stdin / stdout / stderr

process.stdout وprocess.stderr هما تياران قابلان للكتابة، في حين أن process.stdin هو تيار قابل للقراءة يُستخدم للتفاعل مع جهاز الطرفي.

▶ مثال: استخدام المدخلات والمخرجات القياسية

JAVASCRIPT
process.stdout.write('Please enter your name: ');

process.stdin.once('data', (data) => {
  const name = data.toString().trim();
  process.stdout.write(`Hello, ${name}!\n`);
  process.exit(0);
});
▶ جرّب الكود
TEXT 📖 للعرض فقط
Please enter your name: Alice
Hello, Alice!

(5) process.nextTick()

process.nextTick() يضع دالة الاستدعاء في قائمة انتظار المهام الصغيرة، حيث يتم تنفيذها بعد اكتمال العملية الحالية ولكن قبل حدوث أي أحداث إدخال/إخراج. وغالبًا ما يُستخدم هذا لضمان سير العمليات غير المتزامنة بالترتيب المتوقع.

▶ مثال: ترتيب تنفيذ nextTick

JAVASCRIPT
console.log('1 - Synchronize Code');

process.nextTick(() => {
  console.log('3 - nextTick callback');
});

console.log('2 - Synchronize Code');

setImmediate(() => {
  console.log('5 - setImmediate');
});

Promise.resolve().then(() => {
  console.log('4 - Promise then');
});
▶ جرّب الكود
TEXT 📖 للعرض فقط
1 - Synchronize Code
2 - Synchronize Code
3 - nextTick callback
4 - Promise then
5 - setImmediate

(6) مرجع سريع لخصائص العمليات وأساليبها الشائعة

الخاصية/الطريقة النوع الغرض
process.argv string[] مصفوفة معلمات سطر الأوامر
process.env object كائن متغير بيئي
process.exit(code) الطريقة إنهاء العملية
process.cwd() الطريقة العودة إلى دليل العمل الحالي
process.pid number معرّف العملية الحالية
process.uptime() الطريقة مدة تنفيذ العملية (بالثواني)
process.stdin ReadStream دفق الإدخال القياسي
process.stdout WriteStream دفق الإخراج القياسي
process.stderr WriteStream تيار الخطأ المعياري
process.nextTick(cb) الطريقة جدولة المهام الصغيرة
process.platform string منصة التشغيل
process.version string إصدار Node.js
process.versions object معلومات إصدار المكون
process.kill(pid) الطريقة إرسال إشارة إلى عملية
process.title string عنوان العملية


4. الثوابت عبر الأنظمة الأساسية ومعالجة المسارات

(1) فواصل الأسطر وفواصل المسارات

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

▶ مثال: استخدام os.EOL و os.sep

JAVASCRIPT
const os = require('os');
const path = require('path');

const lines = ['First line', 'Second line', 'Third line'].join(os.EOL);
console.log('Escaping Line Breaks:', JSON.stringify(os.EOL));
console.log('Path separator:', os.sep);
console.log('path.join Results:', path.join('src', 'utils', 'index.js'));
▶ جرّب الكود
TEXT 📖 للعرض فقط
Escaping Line Breaks: "\n"
Path separator: /
path.join Results: src/utils/index.js

(2) مقارنة المسارات وثوابت فواصل الأسطر عبر الأنظمة الأساسية المختلفة

الثابت القيمة في نظام ويندوز القيمة في POSIX الغرض
os.EOL \r\n \n علامة نهاية السطر
os.sep \ / فاصل المسار
path.sep \ / فاصل المسار (وحدة المسار)
os.devNull nul /dev/null مسار الجهاز فارغ
path.delimiter ; : فاصل متغيرات بيئة PATH


5. إدارة متغيرات البيئة: .env و dotenv

(1) الاستخدام الأساسي لمكتبة dotenv

dotenv يعد تحميل متغيرات البيئة من الملف .env إلى الملف process.env النهج المتبع في هذا المجال لإدارة تكوينات المشاريع.

▶ مثال: استخدام dotenv لتحميل ملف .env

قم بإنشاء الملف .env:

TEXT 📖 للعرض فقط
NODE_ENV=production
DATABASE_URL=postgresql://db.example.com:5432/myapp
APP_SECRET=my-super-secret-key
APP_PORT=3000

قم بتحميل الكود:

JAVASCRIPT
require('dotenv').config();

console.log(`Environment: ${process.env.NODE_ENV}`);
console.log(`Database: ${process.env.DATABASE_URL}`);
console.log(`Port: ${process.env.APP_PORT}`);
TEXT 📖 للعرض فقط
Environment: production
Database: postgresql://db.example.com:5432/myapp
Port: 3000

(2) مقارنة بين طرق تعيين متغيرات البيئة

الطريقة النطاق الاستمرارية حالات الاستخدام
الإعدادات المؤقتة لـ Shell (export KEY=val) جلسة المحطة الطرفية الحالية تختفي عند انتهاء الجلسة تصحيح الأخطاء المؤقت
.env ملف + dotenv عملية Node الحالية استمرارية الملف تطوير المشروع
متغيرات بيئة النظام عامة للمستخدم/النظام دائمة نشر الخادم
بيئة Docker / ملف البيئة داخل الحاوية دورة حياة الحاوية النشر باستخدام الحاويات
إعداد منصة CI/CD مسار CI/CD داخل المسار التكامل المستمر

(3) قراءة متغيرات البيئة بأمان

▶ مثال: قراءة متغيرات البيئة مع التحقق من صحتها

JAVASCRIPT
function getEnv(key, options = {}) {
  const value = process.env[key];

  if (value === undefined) {
    if (options.required) {
      throw new Error(`Environment Variables ${key} It is necessary`);
    }
    return options.default ?? null;
  }

  if (options.type === 'number') {
    const num = Number(value);
    if (isNaN(num)) throw new Error(`Environment Variables ${key} It must be a number`);
    return num;
  }

  if (options.type === 'boolean') {
    return value === 'true' || value === '1';
  }

  return value;
}

const port = getEnv('APP_PORT', { default: 3000, type: 'number' });
const debug = getEnv('DEBUG', { default: false, type: 'boolean' });
const dbUrl = getEnv('DATABASE_URL', { required: true });
▶ جرّب الكود

6. مثال شامل: أداة CLI لتشخيص النظام

إنشاء أداة CLI كاملة: تحديد نظام التشغيل/الذاكرة/وحدة المعالجة المركزية → قراءة متغيرات البيئة → تنسيق تقرير المخرجات.

▶ مثال: syscheck.js

JAVASCRIPT 📖 للعرض فقط
const os = require('os');

function parseArgs(argv) {
  const args = {};
  for (let i = 2; i < argv.length; i++) {
    if (argv[i].startsWith('--')) {
      const key = argv[i].slice(2);
      const value = argv[i + 1] && !argv[i + 1].startsWith('--')
        ? argv[++i] : true;
      args[key] = value;
    }
  }
  return args;
}

function formatBytes(bytes) {
  const units = ['B', 'KB', 'MB', 'GB'];
  let i = 0;
  let size = bytes;
  while (size >= 1024 && i < units.length - 1) {
    size /= 1024;
    i++;
  }
  return `${size.toFixed(2)} ${units[i]}`;
}

function getSystemInfo() {
  const cpus = os.cpus();
  const totalMem = os.totalmem();
  const freeMem = os.freemem();
  return {
    hostname: os.hostname(),
    platform: os.platform(),
    arch: os.arch(),
    osType: os.type(),
    cpuModel: cpus[0].model,
    cpuCores: cpus.length,
    totalMemory: formatBytes(totalMem),
    freeMemory: formatBytes(freeMem),
    memUsage: ((totalMem - freeMem) / totalMem * 100).toFixed(1) + '%',
    uptime: (os.uptime() / 3600).toFixed(1) + ' hours'
  };
}

function getEnvInfo(keys) {
  const result = {};
  for (const key of keys) {
    result[key] = process.env[key] || '(Not set)';
  }
  return result;
}

function printReport(sys, env) {
  const sep = '='.repeat(48);
  console.log(`\n${sep}`);
  console.log('  System Diagnostic Report');
  console.log(`${sep}`);
  console.log(`  Hostname     : ${sys.hostname}`);
  console.log(`  Platform       : ${sys.platform} / ${sys.arch}`);
  console.log(`  Operating System   : ${sys.osType}`);
  console.log(`  CPU        : ${sys.cpuModel}`);
  console.log(`  CPU Number of cores : ${sys.cpuCores}`);
  console.log(`  Total Memory     : ${sys.totalMemory}`);
  console.log(`  Available memory   : ${sys.freeMemory}`);
  console.log(`  Memory Usage : ${sys.memUsage}`);
  console.log(`  Runtime   : ${sys.uptime}`);
  console.log(`${sep}`);
  console.log('  Environment Variables');
  console.log('-'.repeat(48));
  for (const [key, val] of Object.entries(env)) {
    console.log(`  ${key.padEnd(20)} : ${val}`);
  }
  console.log(`${sep}\n`);
}

const args = parseArgs(process.argv);
const envKeys = args.envKeys
  ? args.envKeys.split(',')
  : ['NODE_ENV', 'HOME', 'PATH', 'SHELL'];
const sys = getSystemInfo();
const env = getEnvInfo(envKeys);
printReport(sys, env);
76 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)
BASH
node syscheck.js --envKeys NODE_ENV,APP_PORT,DATABASE_URL
TEXT 📖 للعرض فقط
================================================
  System Diagnostic Report
================================================
  Hostname     : web-server-01
  Platform       : linux / x64
  Operating System   : Linux
  CPU        : Intel(R) Xeon(R) CPU E5-2680 v4
  CPU Number of cores : 8
  Total Memory     : 15.88 GB
  Available memory   : 6.23 GB
  Memory Usage : 60.7%
  Runtime   : 72.5 hours
================================================
  Environment Variables
------------------------------------------------
  NODE_ENV             : production
  APP_PORT             : (Not set)
  DATABASE_URL         : (Not set)
================================================


❓ أسئلة شائعة

س ما المقصود بـ process.argv[0] و process.argv[1] على التوالي؟
ج argv[0] هو المسار إلى الملف القابل للتنفيذ لـ Node.js (على سبيل المثال، /usr/local/bin/node)، و argv[1] هو المسار إلى ملف البرنامج النصي الذي يتم تنفيذه (على سبيل المثال، /home/alice/app.js). أما الوسيطات الفعلية التي يقدمها المستخدم فتبدأ من argv[2].
س كيف يمكنني قراءة متغيرات البيئة بأمان؟
ج احرص دائمًا على توفير قيمة افتراضية أو التحقق من وجود المتغير؛ وقم بتحويل الأنواع الرقمية والتحقق من صحتها؛ واستخدم dotenv لإدارة ملف .env؛ ولا تقم أبدًا بإدراج ملف .env في نظام التحكم في الإصدارات.
س ما هي الوحدات التي تُرجعها الدالة os.freemem()؟
ج تُرجع عدد البايتات. لعرض النتيجة بالجيجابايت، يجب عليك القسمة يدويًّا على 1073741824 (أي 1024 × 1024 × 1024)، أو يمكنك استخدام دالة تنسيق لتحويل القيمة تلقائيًّا.
س كيف يمكنني قراءة مدخلات المستخدم في Node.js؟
ج يمكنك استخدام دفق القراءة process.stdin بالاقتران مع مستمع الأحداث data، أو استخدام واجهة القراءة سطراً سطراً التي توفرها الوحدة النمطية readline؛ وتُعد readline أكثر ملاءمة لسيناريوهات الأسئلة والأجوبة التفاعلية.
س لماذا يجب توخي الحذر عند استخدام process.exit()؟
ج تقوم process.exit() بإنهاء العملية على الفور، متخطيةً جميع عمليات الاستدعاء المعلقة وعمليات الإدخال/الإخراج ومنطق التنظيف، مما قد يؤدي إلى فقدان البيانات أو بقاء الموارد غير مُحررة. يجب أن تُعطى الأولوية للسماح لحلقة الأحداث بالانتهاء بشكل طبيعي.
س ما الفرق بين process.nextTick() وsetImmediate()؟
ج توجد دالة الاستدعاء nextTick في قائمة انتظار المهام الصغيرة؛ حيث يتم تنفيذها فور انتهاء العملية الحالية، ولها الأولوية على جميع عمليات الإدخال/الإخراج. أما setImmediate فهي موجودة في قائمة انتظار المهام الكبيرة وتُنفَّذ خلال مرحلة حلقة أحداث الإدخال/الإخراج؛ وتتمتع nextTick بأولوية أعلى.
س أين يجب وضع ملف .env الخاص بـ dotenv؟
ج بشكل افتراضي، يتم وضعه في الدليل الجذري للمشروع. يمكنك تحديد مسار باستخدام config({ path: 'custom/path' }). تأكد من إضافة .env إلى .gitignore لمنع الكشف عن المعلومات الحساسة.

📖 ملخص


📝 تمارين

  1. اكتب برنامجًا نصيًّا يعرض عدد نوى وحدة المعالجة المركزية (CPU)، وإجمالي الذاكرة (بالجيجابايت)، والذاكرة المتاحة (بالجيجابايت)، ونسبة استخدام الذاكرة في النظام الحالي.
  2. استخدم process.argv لإنشاء آلة حاسبة بسيطة تعمل عبر سطر الأوامر وتدعم ثلاث عمليات حسابية: --add و--sub و--mul.
  3. إنشاء ملف .env لتخزين معلومات الاتصال بقاعدة البيانات، وتحميله باستخدام dotenv، وقراءته بأمان في البرنامج النصي (مع توفير قيم افتراضية)
  4. قم بتنفيذ دالة تتحقق مما إذا كانت المنصة الحالية هي Windows؛ وإذا كان الأمر كذلك، فاستخدم حرف فاصل الأسطر \r\n؛ وإلا، فاستخدم \n.
  5. اكتب برنامجًا نصيًّا لمراقبة استخدام الذاكرة وعرض رسالة تحذير على stderr عندما يتجاوز استخدام الذاكرة نسبة 90%.
Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%