Linux: إدارة العمليات — ps / top / kill ومراقبة النظام
في لينكس، يُسمّى البرنامج قيد التشغيل عملية (process). إدارة العمليات — معرفة ما يعمل، وكم يستهلك من موارد، وكيفية إيقافه بأمان — هي مهارة أساسية في إدارة الخوادم.
📋 المتطلبات المسبقة: يجب أن تعرف بالفعل
- الدرس 3: أساسيات الطرفية
1. ما ستتعلمه
- ps: عرض قائمة العمليات
- top/htop: المراقبة في الوقت الفعلي
- kill مقابل kill -9
- التنفيذ في الخلفية (& / nohup / disown)
- أولوية العمليات بnice
2. قصة خدمة لا تبدأ
(1) نقطة الألم: المنفذ مستخدم بالفعل
واجه شياو مينغ هذه المشكلة عند تشغيل خدمة Node.js:
node server.js
# Error: listen EADDRINUSE: address already in use :::3000
المنفذ مشغول. لم يعرف أي عملية تستخدم المنفذ 3000 ولا كيفية إيقافها.
(2) تحديد المنفذ وتحريره
# ابحث عن العملية التي تستخدم المنفذ 3000
ss -tlnp | grep 3000
# LISTEN 0 128 *:3000 *:* users:(("node",pid=1234,fd=20))
# أنهِ العملية
kill 1234
# أعِد تشغيل الخدمة
node server.js
(3) الفائدة: تعارضات المنافذ محسومة
تعلّم شياو مينغ استخدام ss أو lsof لإيجاد العمليات التي تشغل المنافذ، وkill لإرسال إشارات لإنهائها. الآن يحل تعارضات المنافذ خلال 30 ثانية.
3. نقاط المعرفة
(1) ps — لقطة العمليات
# الاستخدام الأساسي
ps aux # معلومات تفصيلية عن كل العمليات
ps aux | grep nginx # تصفية عمليات محددة
ps -ef # صيغة قياسية
# معاني الحقول الشائعة
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# alice 1234 0.3 1.2 123456 54321 ? Ssl 10:23 0:01 node server.js
# مخرجات مخصصة
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head -10
| الحقل | المعنى |
|---|---|
| PID | معرّف العملية |
| PPID | معرّف العملية الأصل |
| %CPU | نسبة استخدام المعالج |
| %MEM | نسبة استخدام الذاكرة |
| VSZ | حجم الذاكرة الافتراضية (كيلوبايت) |
| RSS | حجم الذاكرة الفعلية (كيلوبايت) |
| STAT | حالة العملية (R=قيد التشغيل، S=نائمة، D=غير قابلة للمقاطعة، Z=زومبي، T=متوقفة) |
| START | وقت البدء |
| TIME | وقت المعالج التراكمي |
| COMMAND | اسم الأمر / سطر الأوامر |
(2) top/htop — المراقبة في الوقت الفعلي
top # تشغيل top
top -o %MEM # ترتيب حسب الذاكرة
top -u alice # عرض عمليات مستخدم محدد فقط
top -bn1 | head -20 # لقطة واحدة
# مفاتيح التشغيل أثناء عمل top
# P ترتيب حسب المعالج
# M ترتيب حسب الذاكرة
# k إنهاء عملية (يطلب PID)
# u تصفية حسب المستخدم
# q خروج من top
# htop نسخة محسّنة من top (واجهة أفضل، دعم الفأرة)
htop
(3) kill — إرسال الإشارات
kill PID # إرسال SIGTERM (15)، طلب إنهاء
kill -2 PID # إرسال SIGINT (2)، مكافئ لـCtrl+C
kill -9 PID # إرسال SIGKILL (9)، إنهاء إجباري
kill -1 PID # إرسال SIGHUP (1)، إعادة تحميل الإعدادات
kill -19 PID # إرسال SIGSTOP (19)، إيقاف مؤقت للعملية
kill -18 PID # إرسال SIGCONT (18)، استئناف العملية
# إنهاء بالاسم
pkill -f "node server.js" # مطابقة سطر الأوامر
killall nginx # إنهاء كل العمليات التي تحمل نفس الاسم
| الإشارة | الرقم | المعنى |
|---|---|---|
| SIGHUP | 1 | قطع الاتصال (إعادة تحميل الإعدادات) |
| SIGINT | 2 | مقاطعة (Ctrl+C) |
| SIGQUIT | 3 | خروج (مع تفريغ الذاكرة) |
| SIGKILL | 9 | إنهاء إجباري (لا يمكن التقاطه/تجاهله) |
| SIGTERM | 15 | طلب إنهاء (الافتراضي) |
| SIGSTOP | 19 | إيقاف (لا يمكن التقاطه/تجاهله) |
| SIGCONT | 18 | استئناف التنفيذ |
المبدأ الأساسي: جرّب
kill PID(SIGTERM) أولًا. استخدمkill -9 PID(SIGKILL) فقط إذا لم ينفع ذلك. SIGKILL لا يعطي العملية فرصة للتنظيف، مما قد يسبب فقدان البيانات.
kill -9 (SIGKILL) ينهي العملية إجباريًا دون فرصة للتنظيف — الملفات المفتوحة قد تتلف، ومعاملات قاعدة البيانات قد تنقطع، والملفات المؤقتة تبقى عالقة. استخدم -9 فقط عندما لا يستجيب kill PID (SIGTERM). لا تستخدمه كاختصار.
(4) التنفيذ في الخلفية
# & — ضع في الخلفية
node server.js & # يعيد الطرفية فور البدء
> 💡 نصيحة: إلحاق `&` بأمر يشغّله في الخلفية، مما يحرر الطرفية فورًا. لكن `&` وحده يعني أن العملية ستُنهى عند إغلاق جلسة الطرفية. لإبقاء العملية تعمل بعد إغلاق الطرفية، ادمجه مع `nohup`: `nohup command &`.
sleep 30 & # تشغيل sleep في الخلفية
# jobs/fg/bg — إدارة العمليات الخلفية
jobs # عرض العمليات الخلفية
# [1]+ Running node server.js &
# [2]- Running sleep 30 &
fg %1 # إحضار العملية 1 إلى المقدمة
bg %2 # استئناف العملية 2 المتوقفة في الخلفية
# Ctrl+Z — تعليق العملية الحالية في المقدمة ونقلها للخلفية
# Ctrl+C — إنهاء العملية في المقدمة
# nohup — استمرار التشغيل بعد إغلاق الطرفية
nohup node server.js &
nohup python app.py > app.log 2>&1 &
> ℹ️ ملاحظة: `nohup` + `&` هو المزيج القياسي للأوامر الخلفية المستمرة — `nohup` يتجاهل إشارة SIGHUP (التي تُرسل عند إغلاق الطرفية)، و`&` يضع الأمر في الخلفية. المخرجات تُكتب افتراضيًا إلى `nohup.out`؛ يُنصح بتحديد ملف سجل يدويًا: `nohup command > app.log 2>&1 &`.
(5) ▶ مثال: عرض العمليات
# عرض كل العمليات
ps aux | head -10
# عرض عمليات مستخدم محدد
ps -u alice -o pid,%cpu,%mem,comm
# أعلى 10 عمليات حسب استخدام المعالج
ps aux --sort=-%cpu | head -11
# عرض شجرة العمليات
ps auxf | head -20
الإخراج:
TEXTUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 169344 13224 ? Ss 10:00 0:02 /sbin/init root 2 0.0 0.0 0 0 ? S 10:00 0:00 [kthreadd] alice 1234 0.3 1.2 123456 54321 ? Ssl 10:23 0:01 node server.js alice 2345 0.0 0.0 2345 567 pts/0 S+ 10:30 0:00 ps aux PID USER %CPU %MEM COMMAND 1234 alice 0.3 1.2 node 5678 bob 0.1 0.5 python3 USER PID %CPU %MEM COMMAND root 1 0.0 0.1 /sbin/init root 456 0.5 2.1 /usr/bin/containerd alice 1234 8.2 3.4 node server.js bob 2345 5.1 4.2 python train.py
(6) ▶ مثال: المراقبة في الوقت الفعلي
# تشغيل top
top
# العمليات داخل top
# P → ترتيب حسب المعالج
# M → ترتيب حسب الذاكرة
# k → أدخل PID، اضغط Enter، أدخل رقم الإشارة (15 أو 9)، اضغط Enter
# q → خروج
# الوضع غير التفاعلي
top -bn1 | head -15
الإخراج:
TEXTtop - 10:30:01 up 5:23, 2 users, load average: 0.15, 0.10, 0.05 Tasks: 120 total, 1 running, 119 sleeping, 0 stopped, 0 zombie %Cpu(s): 2.3 us, 0.8 sy, 0.0 ni, 96.5 id, 0.2 wa, 0.0 hi, 0.2 si MiB Mem : 3936.0 total, 512.0 free, 2048.0 used, 1376.0 buff/cache
(7) ▶ مثال: إنهاء عملية
# بدء عملية خلفية
sleep 1000 &
# ابحث عنها
ps aux | grep "sleep 1000"
# alice 5678 0.0 0.0 1234 567 pts/0 S 10:23 0:00 sleep 1000
# إنهاء سليم
kill 5678
# إذا لم ينفع ذلك
kill -9 5678
الإخراج:
TEXT[1]+ Terminated sleep 1000 alice 5678 0.0 0.0 1234 567 pts/0 S 10:23 0:00 sleep 1000 [1]+ Killed sleep 1000
(8) ▶ مثال: التنفيذ في الخلفية عمليًا
# بدء مهمة طويلة
nohup python train_model.py > train.log 2>&1 &
# عرض السجل
tail -f train.log
# حتى بعد إغلاق الطرفية، train_model.py يستمر في العمل
# بعد إعادة تسجيل الدخول، ps aux سيُظهر أنه لا يزال يعمل
الإخراج:
TEXT[1] 5678 [2026-07-07 10:23:01] Training epoch 1/100... [2026-07-07 10:23:15] Loss: 0.5234 [2026-07-07 10:23:30] Training epoch 2/100...
(9) ▶ مثال: تعديل الأولوية بnice/renice
# نطاق nice: -20 (أعلى أولوية) إلى 19 (أدنى أولوية)
# البدء بأولوية أقل
nice -n 10 ./heavy-task
# تعديل أولوية عملية قائمة
renice -n 5 -p 1234
# عرض قيم nice للعمليات
ps -eo pid,nice,comm | head -10
(10) ▶ مثال شامل: إدارة الخدمات
#!/bin/bash
# manage-server.sh - إدارة تطبيق Node.js
APP_NAME="server.js"
APP_DIR="/home/alice/app"
PID_FILE="/tmp/app.pid"
start() {
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
echo "App is already running (PID: $(cat $PID_FILE))"
exit 1
fi
cd "$APP_DIR"
nohup node "$APP_NAME" > app.log 2>&1 &
echo $! > "$PID_FILE"
echo "App started (PID: $!)"
}
stop() {
if [ ! -f "$PID_FILE" ]; then
echo "App is not running"
exit 1
fi
PID=$(cat "$PID_FILE")
echo "Stopping app (PID: $PID)..."
kill "$PID" 2>/dev/null
sleep 2
if kill -0 "$PID" 2>/dev/null; then
echo "Force killing..."
kill -9 "$PID" 2>/dev/null
fi
rm -f "$PID_FILE"
echo "Stopped"
}
status() {
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
echo "Running (PID: $(cat $PID_FILE))"
ps -p $(cat "$PID_FILE") -o pid,%cpu,%mem,etime,comm
else
echo "Not running"
fi
}
case "${1:-status}" in
start) start ;;
stop) stop ;;
restart) stop; start ;;
*) status ;;
esac
❓ أسئلة شائعة
س: لماذا
kill -9غير آمن؟ ج:kill -9(SIGKILL) يُجبر العملية على الإنهاء فورًا دون أي تنظيف — الملفات المفتوحة قد تتلف، ومعاملات قاعدة البيانات قد تنقطع، والملفات المؤقتة تُترك عالقة. استخدمه فقط عندما لا يستجيبkill PID(SIGTERM).
س: ما هي العملية الزومبي؟ ج: عملية انتهت لكن عمليةًها الأصل لم تقرأ حالة خروجها. تُترك مدخلة "زومبي" في جدول العمليات (STAT=Z). الزومبي نفسه لا يستهلك موارد، لكن الكثير منها قد يستنزف جدول العمليات. عادةً تحتاج لإنهاء أو إعادة تشغيل العملية الأصل لتنظيفها.
س: ما الفرق بين nohup وdisown؟ ج:
nohupيضبط العملية لتتجاهل SIGHUP عند البدء (تُرسل عند إغلاق الطرفية).disownهو أمر bash مدمج يزيل مهمة بدأت فعلًا من جدول مهام الصدفة.nohup command &هو الأسلوب الأكثر شيوعًا.
س: كيف أقيّد استخدام المعالج لعملية ما؟ ج: استخدم
cpulimit:cpulimit -l 50 -p PIDيقيّدها بـ50% من المعالج. أو استخدمniceلخفض الأولوية. في حاويات Docker، استخدم--cpusللتحديد.
س: كيف أجد أي عملية تستخدم منفذًا محددًا؟ ج: استخدم
ss -tlnp | grep :PORT(موصى به) أوlsof -i :PORT(يتطلب lsof) أوfuser PORT/tcp.
📖 ملخص
ps auxللقطة العمليات،top/htopللمراقبة في الوقت الفعلي- أولوية الإشارات: SIGTERM (15) إنهاء سليم → SIGKILL (9) إنهاء إجباري
&للخلفية،jobs/fg/bgلإدارة المهامnohup command &يستمر بالعمل بعد إغلاق الطرفيةnice -n 10 commandيعدّل الأولوية
📝 تمارين
- أساسي (⭐): استخدم
ps aux --sort=-%cpuلإيجاد أعلى 3 عمليات حسب استخدام المعالج، ثم شغّلsleep 300 &، واطلع عليه بـjobs، وأنهِه بـkill - متوسط (⭐⭐): استخدم
nohupلبدء أمر طويل، أغلق الطرفية، أعِد فتحها، وتأكد أنه لا يزال يعمل. ثم استخدمss -tlnpلعرض كل المنافذ المستمع إليها وعملياتها المرتبطة - متقدم (⭐⭐⭐): اكتب سكريبت إدارة عمليات يدعم أوامر start/stop/status/restart، ويستخدم ملف PID لتتبع العملية، ويُنفّذ إنهاءً سليمًا (SIGTERM أولًا، انتظر 3 ثوانٍ، ثم SIGKILL)