Node.js: وحدتا os و process
آخر تحديث: 2026-08-26
أليس هي مهندسة DevOps مسؤولة عن إدارة عشرات الخوادم. في كل مرة تقوم فيها بنشر تطبيق جديد، يتعين عليها تسجيل الدخول يدويًّا إلى الخوادم للتحقق من القيم العددية لنوى وحدة المعالجة المركزية (CPU) والذاكرة المتاحة وإصدار نظام التشغيل، ثم تغيير الإعدادات بناءً على متغيرات البيئة. خلال عملية نشر طارئة في الساعة 3 صباحًا في أحد الأيام، فاتتها مشكلة نقص الذاكرة أثناء فحوصاتها اليدوية، مما تسبب في فشل عملية النشر. لذلك قررت كتابة برنامج نصي للكشف التلقائي بلغة Node.js لاسترداد معلومات موارد الخادم والبيئة بنقرة واحدة، لضمان سير عمليات النشر المستقبلية بسلاسة.
1. ما ستتعلمه
- الطرق الأساسية في وحدة
os: استرداد معلومات مثل وحدة المعالجة المركزية (CPU) والذاكرة واسم المضيف ونظام التشغيل - الخصائص الأساسية لوحدة
process:argv،env،exit،cwd، إلخ. - عمليات التدفق القياسية: stdin / stdout / stderr
- متى يتم تشغيل
process.nextTick()والغرض منه - إدارة متغيرات البيئة: ملفات .env ومكتبة dotenv
- نصائح عملية لإنشاء أدوات واجهة سطر الأوامر (CLI) متعددة المنصات
2. الوحدة النمطية os: جمع معلومات النظام
(1) معلومات عن وحدة المعالجة المركزية والذاكرة
تُرجع الدالة os.cpus() مصفوفة تحتوي على تفاصيل نوى وحدة المعالجة المركزية (CPU)؛ بينما تُرجع الدالتان os.totalmem() وos.freemem() إجمالي الذاكرة والذاكرة المتاحة، على التوالي (بالبايت).
▶ مثال: التحقق من وحدة المعالجة المركزية (CPU) والذاكرة في الخادم
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}%`);
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() اسم المضيف.
▶ مثال: استرداد معلومات نظام التشغيل
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()}`);
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() تُرجع دليل الملفات المؤقتة.
▶ مثال: استرداد معلومات المستخدم والدليل
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()}`);
Username: alice
Home Directory: /home/alice
Shell: /bin/bash
Temporary Directory: /tmp
(4) معلومات واجهة الشبكة
os.networkInterfaces() يعرض معلومات تفصيلية عن جميع واجهات الشبكة، بما في ذلك عناوين IP وعناوين MAC ومجموعات العناوين.
▶ مثال: عرض واجهات الشبكة
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})`);
}
}
}
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] هو المسار إلى البرنامج النصي الذي يتم تنفيذه؛ أما العناصر التالية فهي معلمات سطر الأوامر التي تم تمريرها.
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' }"]
▶ مثال: تحليل معلمات سطر الأوامر
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);
node cli.js --env production --port 8080 --verbose
{ env: 'production', port: '8080', verbose: true }
(2) متغير البيئة process.env
process.env يحتوي على جميع أزواج المفاتيح والقيم الخاصة بمتغيرات البيئة، ويُعد الأساس الرئيسي الذي يعتمد عليه برنامج النص البرمجي الخاص بالنشر لتحديد بيئة التشغيل.
▶ مثال: قراءة متغيرات البيئة وتعيينها
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}`);
NODE_ENV: development
PATH: /usr/local/bin:/usr/bin:/bin
APP_MODE: production
(3) إنهاء العملية ودليل العمل
process.exit(code) إنهاء العملية (تشير القيمة 0 إلى النجاح؛ أما القيم غير الصفرية فتشير إلى الفشل)، process.cwd() العودة إلى دليل العمل الحالي.
▶ مثال: الخروج المشروط والتحقق من الدليل
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`);
Missing required environment variables: DATABASE_URL, APP_SECRET
(4) تدفقات قياسية: stdin / stdout / stderr
process.stdout وprocess.stderr هما تياران قابلان للكتابة، في حين أن process.stdin هو تيار قابل للقراءة يُستخدم للتفاعل مع جهاز الطرفي.
▶ مثال: استخدام المدخلات والمخرجات القياسية
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);
});
Please enter your name: Alice
Hello, Alice!
(5) process.nextTick()
process.nextTick() يضع دالة الاستدعاء في قائمة انتظار المهام الصغيرة، حيث يتم تنفيذها بعد اكتمال العملية الحالية ولكن قبل حدوث أي أحداث إدخال/إخراج. وغالبًا ما يُستخدم هذا لضمان سير العمليات غير المتزامنة بالترتيب المتوقع.
▶ مثال: ترتيب تنفيذ nextTick
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');
});
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
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'));
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:
NODE_ENV=production
DATABASE_URL=postgresql://db.example.com:5432/myapp
APP_SECRET=my-super-secret-key
APP_PORT=3000
قم بتحميل الكود:
require('dotenv').config();
console.log(`Environment: ${process.env.NODE_ENV}`);
console.log(`Database: ${process.env.DATABASE_URL}`);
console.log(`Port: ${process.env.APP_PORT}`);
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) قراءة متغيرات البيئة بأمان
▶ مثال: قراءة متغيرات البيئة مع التحقق من صحتها
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
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);
node syscheck.js --envKeys NODE_ENV,APP_PORT,DATABASE_URL
================================================
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)
================================================
❓ أسئلة شائعة
os.freemem()؟process.stdin بالاقتران مع مستمع الأحداث data، أو استخدام واجهة القراءة سطراً سطراً التي توفرها الوحدة النمطية readline؛ وتُعد readline أكثر ملاءمة لسيناريوهات الأسئلة والأجوبة التفاعلية.process.exit()؟process.exit() بإنهاء العملية على الفور، متخطيةً جميع عمليات الاستدعاء المعلقة وعمليات الإدخال/الإخراج ومنطق التنظيف، مما قد يؤدي إلى فقدان البيانات أو بقاء الموارد غير مُحررة. يجب أن تُعطى الأولوية للسماح لحلقة الأحداث بالانتهاء بشكل طبيعي.process.nextTick() وsetImmediate()؟nextTick في قائمة انتظار المهام الصغيرة؛ حيث يتم تنفيذها فور انتهاء العملية الحالية، ولها الأولوية على جميع عمليات الإدخال/الإخراج. أما setImmediate فهي موجودة في قائمة انتظار المهام الكبيرة وتُنفَّذ خلال مرحلة حلقة أحداث الإدخال/الإخراج؛ وتتمتع nextTick بأولوية أعلى.config({ path: 'custom/path' }). تأكد من إضافة .env إلى .gitignore لمنع الكشف عن المعلومات الحساسة.📖 ملخص
- توفر الوحدة النمطية
osمعلومات على مستوى النظام: وحدة المعالجة المركزية (CPU)، والذاكرة، والمنصة، وواجهات الشبكة، ومعلومات المستخدم، وغيرها. - تقوم الدالة
process.argvبتحليل معلمات سطر الأوامر؛ حيث يمثلargv[0]مسار Node، ويمثلargv[1]مسار البرنامج النصي process.envتدير متغيرات البيئة؛ بينما تقوم مكتبةdotenvبتحميل الإعدادات من ملفات.env- استخدم
process.exit()بحذر لتجنب تخطي منطق التنظيف. process.nextTick()هي مهمة صغيرة، ولها الأسبقية علىsetImmediateوPromise- استخدم os.EOL و os.sep و path.join للتعامل مع الاختلافات بين الأنظمة الأساسية المختلفة
📝 تمارين
- اكتب برنامجًا نصيًّا يعرض عدد نوى وحدة المعالجة المركزية (CPU)، وإجمالي الذاكرة (بالجيجابايت)، والذاكرة المتاحة (بالجيجابايت)، ونسبة استخدام الذاكرة في النظام الحالي.
- استخدم
process.argvلإنشاء آلة حاسبة بسيطة تعمل عبر سطر الأوامر وتدعم ثلاث عمليات حسابية:--addو--subو--mul. - إنشاء ملف .env لتخزين معلومات الاتصال بقاعدة البيانات، وتحميله باستخدام dotenv، وقراءته بأمان في البرنامج النصي (مع توفير قيم افتراضية)
- قم بتنفيذ دالة تتحقق مما إذا كانت المنصة الحالية هي Windows؛ وإذا كان الأمر كذلك، فاستخدم حرف فاصل الأسطر
\r\n؛ وإلا، فاستخدم\n. - اكتب برنامجًا نصيًّا لمراقبة استخدام الذاكرة وعرض رسالة تحذير على stderr عندما يتجاوز استخدام الذاكرة نسبة 90%.