Linux-এর প্রসেস: ps, top, htop, kill, সিগন্যাল ও nice
Linux-এ প্রসেস দেখা হয় ps aux (এক মুহূর্তের স্ন্যাপশট) এবং top ও htop (লোডসহ হালনাগাদ হওয়া তালিকা) দিয়ে। প্রসেস বন্ধ করা হয় kill PID দিয়ে, যা ডিফল্টে নম্র SIGTERM পাঠায়; kill -9 (SIGKILL) শুধু তখনই, যখন প্রসেস সাড়া দেয় না। অগ্রাধিকার ঠিক হয় চালুর সময় nice দিয়ে, আর চলমান প্রসেসের জন্য renice দিয়ে; মান -20 থেকে 19 পর্যন্ত।
Linux-এ চলমান প্রতিটি প্রোগ্রাম একটি প্রসেস — তার নিজস্ব PID নম্বর, মালিক, অবস্থা ও অগ্রাধিকার থাকে। প্রসেস দেখতে ps, top ও htop ব্যবহার হয়, বন্ধ করতে kill, আর অগ্রাধিকার বদলাতে nice ও renice। নিচে দেখানো হবে এই কমান্ডের আউটপুট কীভাবে পড়তে হয়, কোন সিগন্যাল কখন পাঠাতে হয়, এবং কেন kill -9 প্রথম প্রতিক্রিয়া হওয়া উচিত নয়।
প্রসেস ও PID কী
প্রসেস হলো চলমান অবস্থায় থাকা একটি প্রোগ্রাম: কোড, মেমরি, খোলা ফাইল এবং কিছু অ্যাট্রিবিউট। কার্নেল প্রতিটি প্রসেসকে একটি অনন্য শনাক্তকারী PID দেয়, এবং মনে রাখে PPID — যে প্যারেন্ট প্রসেস এটি চালু করেছে তার নম্বর। সিস্টেমের প্রথম প্রসেস, PID 1, সাধারণত systemd; এটিই বাকি সবার “পূর্বপুরুষ”।
নতুন প্রসেস দুই ধাপে তৈরি হয়। প্রথমে প্যারেন্ট fork() কল করে নিজের একটি কপি পায়, তারপর সেই কপি execve() কল করে নিজের কোড বদলে নতুন প্রোগ্রামের কোড নেয়। টার্মিনালে ls লিখলে bash ঠিক এটাই করে এবং সন্তানের শেষ হওয়ার জন্য wait()-এ অপেক্ষা করে।
$ echo $$ # বর্তমান শেলের PID
4182
$ ps -o pid,ppid,cmd -p $$
PID PPID CMD
4182 4170 -bash
ps দিয়ে প্রসেস দেখা
ps এক মুহূর্তের স্ন্যাপশট নেয়: চালু করার ঠিক সেই মুহূর্তের প্রসেসগুলো দেখিয়ে শেষ হয়। কোনো আর্গুমেন্ট ছাড়া এটি শুধু বর্তমান টার্মিনালের প্রসেস দেখায়, তাই বাস্তবে প্রায় সবসময় দুটির একটি রূপ ব্যবহার হয়।
$ ps aux | head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 168540 12780 ? Ss 09:12 0:03 /sbin/init
root 2 0.0 0.0 0 0 ? S 09:12 0:00 [kthreadd]
www-data 1532 1.2 2.1 412308 86420 ? S 09:15 1:47 php-fpm: pool www
postgres 1610 0.4 3.8 221004 154312 ? Ss 09:15 0:31 postgres: checkpointer
এখানে a — সব ব্যবহারকারীর প্রসেস, u — মালিকসহ বিস্তারিত ফরম্যাট, x — টার্মিনালবিহীন প্রসেসও (ডেমন)। System V শৈলীর বিকল্প সিনট্যাক্স ps -ef: এটি PPID দেখায়, যা জানতে সুবিধাজনক কে কাকে চালু করেছে।
| কলাম | অর্থ |
|---|---|
PID | প্রসেসের শনাক্তকারী |
%CPU, %MEM | প্রসেসরের ও ভৌত মেমরির অংশ |
VSZ | ভার্চুয়াল মেমরি KB-তে (RAM-এ না থাকা অংশসহ) |
RSS | আসলে দখল করা ভৌত মেমরি KB-তে |
STAT | প্রসেসের অবস্থা (R, S, D, Z, T) ও ফ্ল্যাগ |
TIME | মোট প্রসেসর সময়, চালু থাকার সময় নয় |
ps-এর কয়েকটি কার্যকর কৌশল
# মেমরিতে শীর্ষ 10
ps aux --sort=-%mem | head -11
# প্রসেসরে শীর্ষ 10
ps aux --sort=-%cpu | head -11
# নিজের পছন্দের কলাম
ps -eo pid,ppid,user,ni,stat,etime,cmd
# প্রসেসের গাছ
ps -ef --forest
pstree -p
# নাম দিয়ে PID খোঁজা
pgrep -a nginx
pidof nginx
একটি সাধারণ ভুল — ps aux | grep nginx দিয়ে প্রসেস খুঁজতে গিয়ে আউটপুটে নিজের grep-কেই পাওয়া। এর বদলে pgrep বা grep [n]ginx ব্যবহার করুন; শেষেরটি নিজের কমান্ড-লাইনের সঙ্গে মেলে না।
প্রসেসের অবস্থা: R, S, D, Z, T
STAT কলামের অক্ষরটি অর্থহীন নয়, এটি প্রসেসের প্রকৃত অবস্থা। এর ওপর নির্ভর করে লোড কীভাবে বুঝবেন এবং kill আদৌ কাজ করবে কি না।
| কোড | অবস্থা | বাস্তবে কী বোঝায় |
|---|---|---|
R | Running | চলছে বা CPU-এর জন্য সারিতে অপেক্ষা করছে |
S | Interruptible sleep | কোনো ঘটনার অপেক্ষায় (নেটওয়ার্ক, ইনপুট, টাইমার); বেশিরভাগ প্রসেসের স্বাভাবিক অবস্থা |
D | Uninterruptible sleep | কার্নেলের ভেতরে I/O-র অপেক্ষায়, সিগন্যাল পৌঁছায় না |
Z | Zombie | শেষ হয়ে গেছে, কিন্তু প্যারেন্ট এখনও exit কোড নেয়নি |
T | Stopped | SIGSTOP বা Ctrl+Z দিয়ে স্থগিত |
অক্ষরের পরে অতিরিক্ত চিহ্নও কাজের: s — সেশন লিডার, + — টার্মিনালের সামনের প্রসেস, < — বেশি অগ্রাধিকার, N — কম অগ্রাধিকার, l — মাল্টিথ্রেডেড।
D অবস্থার প্রসেস
D অবস্থার প্রসেস একটি সিস্টেম কলের ভেতরে থাকে এবং যেমন ডিস্ক বা আটকে যাওয়া NFS-এর উত্তরের অপেক্ষা করে। এতে কোনো সিগন্যাল পৌঁছায় না, এমনকি SIGKILL-ও না। তাই এখানে kill -9 অকেজো: অপেক্ষার কারণ খুঁজতে হবে — iostat, dmesg ও নেটওয়ার্ক স্টোরেজের অবস্থা দেখুন।
জম্বি প্রসেস
জম্বি আগেই মৃত: সে CPU বা মেমরি খরচ করে না, শুধু প্রসেস টেবিলে একটি সারি দখল করে। তাকে মারা যায় না, কারণ সে এমনিতেই শেষ হয়ে গেছে। সারি মুছে যায় যখন প্যারেন্ট wait() কল করে, অথবা প্যারেন্ট নিজেই শেষ হলে জম্বিকে PID 1 দত্তক নেয়।
# জম্বি ও তাদের প্যারেন্ট খোঁজা
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'
একটি-দুটি জম্বি ক্ষতিকর নয়। শত শত হলে এবং সংখ্যা বাড়লে প্যারেন্ট প্রোগ্রামে ভুল আছে — সেটি ঠিক করতে হবে বা পুনরায় চালু করতে হবে।
top: রিয়েল টাইমে প্রসেস ও লোড
top একই তালিকা দেখায়, কিন্তু প্রতি কয়েক সেকেন্ডে তা হালনাগাদ করে এবং সিস্টেমের সারসংক্ষেপ দেখায়। “সার্ভার ধীর হয়ে গেছে” — এমন সময়ে এটিই প্রথম চালানোর কমান্ড।
top - 14:21:07 up 12 days, 3:02, 2 users, load average: 1.84, 1.20, 0.95
Tasks: 213 total, 2 running, 211 sleeping, 0 stopped, 0 zombie
%Cpu(s): 23.1 us, 4.2 sy, 0.0 ni, 70.3 id, 1.9 wa, 0.0 hi, 0.5 si, 0.0 st
MiB Mem : 7821.4 total, 412.6 free, 3105.8 used, 4303.0 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 4398.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1532 www-data 20 0 412308 86420 14212 R 38.2 1.1 1:47.31 php-fpm
1610 postgres 20 0 221004 154312 148900 S 6.0 1.9 0:31.08 postgres
%Cpu(s) লাইনটি সবচেয়ে গুরুত্বপূর্ণ: us — ব্যবহারকারীর কোড, sy — কার্নেল, id — অলস, wa — ডিস্কের অপেক্ষা। প্রসেসর ফাঁকা থাকলে অথচ wa বেশি হলে বোঝা যায় বাধা I/O-তে।
top-এর শর্টকাট কী
| কী | কাজ |
|---|---|
P / M | CPU / মেমরি অনুসারে সাজানো |
1 | প্রতিটি কোর আলাদাভাবে দেখানো |
c | পূর্ণ কমান্ড-লাইন |
u | ব্যবহারকারী অনুযায়ী ছাঁকা |
k | প্রসেসে সিগন্যাল পাঠানো |
r | প্রসেসের nice বদলানো |
H | থ্রেড দেখানো |
q | বের হওয়া |
স্ক্রিপ্ট ও লগের জন্য ব্যাচ মোড কাজে লাগে: top -b -n 1 | head -20 ইন্টার্যাকশন ছাড়া একটি স্ন্যাপশট দেয়। নির্দিষ্ট একটি প্রসেস দেখতে — top -p 1532।
Load Average একটি সারি, শতাংশ নয়
load average-এর তিনটি সংখ্যা গত 1, 5 ও 15 মিনিটের গড় সারির দৈর্ঘ্য। Linux-এ এই সারিতে থাকে R ও D অবস্থার প্রসেস, সাধারণ ঘুমন্ত S প্রসেস নয়। LA-র সঙ্গে কোরের সংখ্যা (nproc) তুলনা করতে হয়: 4 কোরে মান 4 মানে পূর্ণ লোড, আর 12 মানে সারি ক্ষমতার তিনগুণ।
LA বেশি, অথচ প্রসেসর অলস — তাহলে D অবস্থার প্রসেস খুঁজুন: ps -eo stat,pid,cmd | grep '^D'। প্রায় সবসময় কারণ ধীর ডিস্ক বা নেটওয়ার্ক স্টোরেজ।
htop: top-এর সুবিধাজনক বিকল্প
htop একই তথ্য দেখায়, কিন্তু কোরের রঙিন নির্দেশক, স্ক্রল, মাউস সমর্থন ও প্রসেসের গাছসহ। সাধারণত আগে ইনস্টল করতে হয়: sudo apt install htop বা sudo dnf install htop।
F3বা/— নাম দিয়ে প্রসেস খোঁজা;F4— ফিল্টার, শুধু মিলে যাওয়া প্রসেস রেখে;F5বাt— “প্যারেন্ট — সন্তান” গাছ;F6— সাজানোর কলাম বেছে নেওয়া;F7/F8— nice কমানো বা বাড়ানো;F9— নির্বাচিত প্রসেসের সিগন্যাল মেনু;Space— একাধিক প্রসেস চিহ্নিত করে একসঙ্গে কাজ।
যেখানে কিছু ইনস্টল করা যায় না, সেখানে top-ই যথেষ্ট: এর সব মূল কাজই সেখানে আছে।
প্রসেস বন্ধ করা: kill ও সিগন্যাল
kill আসলে প্রসেস “মারে” না, প্রসেসের কাছে একটি সিগন্যাল পাঠায়। এরপর কী ঘটবে তা নির্ভর করে সিগন্যাল ও প্রোগ্রামটি কীভাবে তা হ্যান্ডেল করে।
| সিগন্যাল | নম্বর | উদ্দেশ্য |
|---|---|---|
SIGHUP | 1 | টার্মিনাল বিচ্ছিন্ন; অনেক ডেমন কনফিগ আবার পড়ে |
SIGINT | 2 | বাধা দেওয়া, Ctrl+C-এর সমান |
SIGKILL | 9 | কার্নেলের জোরপূর্বক বন্ধ, ধরা যায় না |
SIGTERM | 15 | ভদ্রভাবে বন্ধ হওয়ার অনুরোধ; kill-এর ডিফল্ট |
SIGSTOP | 19 | স্থগিত করা, ধরা যায় না |
SIGCONT | 18 | স্থগিত প্রসেস আবার চালু |
SIGTSTP | 20 | টার্মিনাল থেকে স্থগিত, Ctrl+Z |
নম্বরগুলো x86 ও ARM-এর জন্য; পুরো তালিকা দেখায় kill -l। নাম দিয়ে সিগন্যাল পাঠানো নম্বরের চেয়ে নির্ভরযোগ্য।
kill 1532 # SIGTERM
kill -TERM 1532 # একই, স্পষ্টভাবে
kill -HUP $(pidof nginx) # কনফিগারেশন আবার পড়ানো
kill -STOP 1532; kill -CONT 1532
kill -0 1532 && echo "প্রসেস বেঁচে আছে"
সিগন্যাল 0 কিছুই পাঠায় না, শুধু যাচাই করে প্রসেস আছে কি না এবং তাতে লেখার অধিকার আছে কি না — স্ক্রিপ্টে এটি কাজে লাগে।
কেন kill -9 দিয়ে শুরু করা উচিত নয়
SIGTERM প্রোগ্রামকে ফাইল বন্ধ করার, বাফার লেখার, lock-ফাইল মোছার এবং লেনদেন ঠিকভাবে শেষ করার সুযোগ দেয়। SIGKILL সবকিছু তৎক্ষণাৎ ছিঁড়ে দেয়: অসম্পূর্ণ লেখা হারায়, অস্থায়ী ফাইল থেকে যায়, আর ডেটাবেস পরের চালুতে পুনরুদ্ধার করতে পারে।
সঠিক ক্রম এই:
kill PID(SIGTERM) পাঠান।- 5–30 সেকেন্ড অপেক্ষা করুন,
kill -0 PIDদিয়ে দেখুন। - শুধু প্রসেস বেঁচে থাকলে এবং
Dঅবস্থায় না থাকলে —kill -9 PID।
systemd-র সার্ভিসের ক্ষেত্রে PID হাতে না ধরাই ভালো: systemctl stop নিজেই SIGTERM পাঠায়, সময়সীমা পর্যন্ত অপেক্ষা করে, তারপর SIGKILL দিয়ে শেষ করে।
pkill ও killall: নাম দিয়ে
pkill -f "python worker.py" # পুরো কমান্ড-লাইন দিয়ে
pkill -u alice # একজন ব্যবহারকারীর সব প্রসেস
killall -TERM node # node নামের সব প্রসেস
pgrep -l -f worker # আগে দেখুন কী কী ধরা পড়বে
বড় আকারে pkill চালানোর আগে একই প্যাটার্ন দিয়ে pgrep চালান: -f কমান্ড-লাইনের যেকোনো অংশের সঙ্গে মেলে, তাই সহজেই অপ্রয়োজনীয় কিছু ধরে ফেলতে পারে।
শুধু নিজের প্রসেসে সিগন্যাল পাঠানো যায়; অন্যদের প্রসেসে sudo লাগে। Operation not permitted ত্রুটির মানে এটিই।
অগ্রাধিকার: nice ও renice
nice মান শিডিউলারকে বলে দেয় কে প্রসেসর ছেড়ে দেবে। পরিসর — -20 (সবচেয়ে বেশি অগ্রাধিকার) থেকে 19 (সবাইকে ছেড়ে দেয়), ডিফল্ট 0। top-এ এটি NI কলামে দেখা যায়, আর PR হলো এর থেকে তৈরি অভ্যন্তরীণ অগ্রাধিকার।
# ভারী কাজ কম অগ্রাধিকারে চালানো
nice -n 10 tar czf backup.tar.gz /var/www
# চলমান প্রসেসের অগ্রাধিকার কমানো
renice -n 15 -p 1532
# বাড়ানো (শুধু root)
sudo renice -n -5 -p 1610
# একজন ব্যবহারকারীর সব প্রসেস
sudo renice -n 10 -u alice
সাধারণ ব্যবহারকারী নিজের প্রসেসের অগ্রাধিকার শুধু কমাতে পারে; ঋণাত্মক মান শুধু root-এর জন্য। মনে রাখুন nice শুধু CPU-র ওপর প্রভাব ফেলে। কোনো কাজ ডিস্ক দিয়ে সিস্টেমকে ধীর করলে ionice -c3 কমান্ড ব্যবহার করুন — এটি idle শ্রেণি, যা ডিস্ক তখনই পায় যখন অন্য কারও দরকার নেই।
পটভূমির প্রসেস ও শেলের কাজ
কমান্ডের শেষে & দিয়ে এটি পটভূমিতে চালানো যায়, অথবা Ctrl+Z দিয়ে স্থগিত করা যায়। শেল কাজের একটি তালিকা রাখে, যা নিয়ন্ত্রণ করে অন্তর্নির্মিত কমান্ড।
$ long_task &
[1] 5120
$ jobs
[1]+ Running long_task &
$ fg %1 # সামনের স্তরে ফিরিয়ে আনা
^Z # স্থগিত (SIGTSTP)
$ bg %1 # পটভূমিতে চালু রাখা
টার্মিনাল বন্ধ করলে শেল কাজগুলোকে SIGHUP পাঠায়, ফলে সেগুলো শেষ হয়ে যায়। টার্মিনাল বন্ধ হলেও প্রসেস টিকিয়ে রাখতে nohup কমান্ড & দিয়ে চালান, অথবা disown ব্যবহার করুন, কিংবা tmux। স্থায়ী কাজের জন্য সবচেয়ে ভালো হলো এটিকে systemd সার্ভিস হিসেবে সাজানো।
সাধারণ রোগনির্ণয়ের পরিস্থিতি
কে প্রসেসর খেয়ে ফেলছে
top -o %CPU # অথবা top-এর ভেতরে P
ps -eo pid,user,%cpu,etime,cmd --sort=-%cpu | head
কোনো প্রসেস অকারণে CPU খেলে আগে renice দিয়ে তার অগ্রাধিকার কমান — এটি নিরাপদ এবং বিষয়টি বুঝতে সময় দেয়।
কে পোর্ট দখল করেছে
sudo ss -ltnp | grep :8080
sudo lsof -i :8080
আউটপুটে PID থাকবে; তারপর /proc/PID/-এ গিয়ে চালু হওয়া ফাইল (exe), কাজের ডিরেক্টরি (cwd) ও আর্গুমেন্ট (cmdline) দেখা যায়।
প্রসেস হঠাৎ অদৃশ্য হয়ে গেছে
এর একটি সাধারণ কারণ OOM Killer, যা মেমরি ফুরিয়ে গেলে প্রসেস মেরে ফেলে। পরীক্ষা করুন: dmesg -T | grep -i oom বা journalctl -k | grep -i "killed process"।
সারসংক্ষেপ
Linux-এ প্রসেস নিয়ে কাজের জন্য ছোট একটি কমান্ডসেটই যথেষ্ট: স্ন্যাপশটের জন্য ps aux, পর্যবেক্ষণের জন্য top ও htop, সঠিক সিগন্যালসহ বন্ধ করার জন্য kill, এবং অগ্রাধিকারের জন্য nice/renice। কাজ করার আগে প্রসেসের অবস্থা পড়ুন: জম্বি ও D অবস্থার প্রসেস সিগন্যালে ভালো হয় না। আর SIGTERM দিয়ে শুরু করুন, kill -9 রাখুন শেষ উপায় হিসেবে। প্রসেস, মেমরি, Load Average ও সিস্টেম কল নিয়ে বিস্তারিত আলোচনা হয়েছে লিনাক্স কোর্সে, হাতে-কলমে।
সাধারণ প্রশ্ন
ps aux ও ps -ef-এর পার্থক্য কী?
এগুলো একই কমান্ডের দুটি সিনট্যাক্স: aux — BSD শৈলী, যেখানে %CPU, %MEM ও STAT কলাম থাকে; -ef — System V শৈলী, যেখানে PPID কলাম থাকে। দুই ক্ষেত্রেই প্রসেসের তালিকা একই — সিস্টেমের সব প্রসেস।
সিস্টেমে মোট কতটি প্রসেস চলছে তা কীভাবে জানবেন?
সবচেয়ে সহজ উপায় top-এর Tasks লাইনটি দেখা, অথবা ps -e --no-headers | wc -l চালানো। থ্রেডের সংখ্যা দেখাবে ps -eLf --no-headers | wc -l।
kill -9 দেওয়ার পরও প্রসেস কেন বন্ধ হয় না?
হয় সেটি D অবস্থায় আছে এবং কার্নেলে I/O-র অপেক্ষা করছে, অথবা এটি একটি জম্বি, যা আগেই শেষ হয়ে গেছে। প্রথম ক্ষেত্রে ডিস্ক বা নেটওয়ার্ক স্টোরেজের সমস্যা খুঁজুন, দ্বিতীয় ক্ষেত্রে প্যারেন্টকে ঠিক করুন বা পুনরায় চালু করুন।
PID 1-কে মারলে কী হবে?
কার্নেল init-কে রক্ষা করে: ব্যবহারকারীর সাধারণ সিগন্যাল, এমনকি SIGKILL-ও, init পৌঁছাতে পারে না যদি সে সেটি হ্যান্ডেল না করে। তবে init সত্যিই শেষ হয়ে গেলে সিস্টেম kernel panic-এ পড়বে।
কোনো প্রসেসের মেমরির ব্যবহার সীমিত করা যায় কীভাবে?
systemd সার্ভিসের জন্য unit-ফাইলে MemoryMax= লিখুন, আর এক বারের চালু করার জন্য systemd-run --scope -p MemoryMax=500M কমান্ড। এটি cgroups দিয়ে কাজ করে এবং পুরনো ulimit -v-এর চেয়ে নির্ভরযোগ্য।
“Linux: с нуля до уверенного администрирования” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।
কোর্সে যান