Linux میں watch کمانڈ درست طریقے سے کیسے استعمال کریں
watch ہر 2 سیکنڈ بعد کمانڈ چلاتا ہے۔ مناسب interval منتخب کریں، diff نمایاں کریں، تبدیلی پر بند ہوں، اور pipes کو quote کریں تاکہ کمانڈ درست چلے۔
What the watch command does
The watch command re-runs another command at a fixed interval and redraws its output in the same place on screen. The default interval is two seconds. Reach for it when you are waiting for a number to move: a disk filling up, a container settling down, a certificate renewal landing, or a queue draining.
watch comes from procps-ng and is already installed on a fresh Ubuntu or Debian VPS as part of the procps package. Check your version before you trust any flag below, because two of the useful options are recent.
watch --versionOn Ubuntu 24.04 that prints a line like watch from procps-ng 4.0.4. Now the simplest useful example.
watch df -h /The screen clears and shows a header line, a blank line, then the output of df -h /:
Every 2.0s: df -h / server1: Sun Aug 9 10:21:44 2026On the left is the interval and the exact command watch is running. On the right is the hostname and the current time. The clock is the useful half, because it proves the screen is still refreshing when the numbers below it are not moving. Press Ctrl+C to quit.
watch draws one frame that fits the terminal. Long lines wrap, -w truncates them instead, and anything past the bottom row is not drawn at all. There is no scrollback inside the frame, because every cycle overwrites the last one. That single fact decides most of what watch is good for.
watch کو کمانڈ کتنی بار دوبارہ چلانی چاہیے؟
دو سیکنڈ صرف ایک default ہے۔ interval کا انتخاب اس بنیاد پر کریں کہ value کتنی تیزی سے بدلتی ہے اور ہر run پر کتنا system load پڑتا ہے۔
-n 0.5ان counters کے لیے جو مسلسل بدلتے رہتے ہیں، جیسےss -sیا کسی interface کا byte count۔ watch کا کم ترین قابل قبول interval 0.1 seconds ہے۔-n 30یا-n 60disks اور certificates کے لیے۔ جو filesystem ایک دن میں بھرتا ہو، اسے ایک منٹ میں تیس frames کی ضرورت نہیں ہوتی۔
watch کمانڈ چلاتا ہے، اس کے مکمل ہونے کا انتظار کرتا ہے، اور پھر interval کے لیے sleep کرتا ہے۔ command کا runtime gap میں شامل ہو جاتا ہے۔ اس لیے -n 2 کے تحت آٹھ سیکنڈ لینے والی کمانڈ ہر دس سیکنڈ میں ایک frame دیتی ہے اور پوری مدت میں machine کو مصروف رکھتی ہے۔ -p (--precise) شامل کرنے پر watch اس کے بجائے ہر interval seconds بعد run شروع کرنے کی کوشش کرتا ہے۔ پیمائش ایک run کے آغاز سے اگلے run کے آغاز تک کی جاتی ہے۔
اگر آپ ہمیشہ مختلف default چاہتے ہیں تو اپنے shell profile میں WATCH_INTERVAL export کریں۔ واضح طور پر دیا گیا -n پھر بھی اس پر فوقیت رکھتا ہے۔ یہ تصدیق کرنے کے لیے watch --help چلائیں کہ آپ کی build اس variable کو پڑھتی ہے۔
-d سے تبدیل شدہ حصوں کو نمایاں کریں
ایک جیسے متن کی دیوار میں اس ایک فیلڈ کو تلاش کرنا جس کی قدر تبدیل ہوئی ہو، مشکل کام ہے۔ -d (--differences) یہ کام آپ کے لیے کرتا ہے۔
watch -n 30 -d 'df -h / /var'پچھلے فریم سے مختلف characters کو reverse video میں دکھایا جاتا ہے، اس لیے Use% cell کے حرکت کرتے ہی روشن ہو جاتا ہے اور باقی سب غیر نمایاں رہتا ہے۔ اگر /var الگ filesystem نہ ہو تو root filesystem دو بار درج ہوگا۔ اس سے یہ جاننے کا فوری طریقہ ملتا ہے کہ سسٹم کو کس طرح partition کیا گیا تھا۔
موازنہ positional ہوتا ہے، یعنی watch نئی frame کی ہر لائن کو پرانی frame کے مقابل character by character رکھتا ہے۔ ایسے output میں جس کے columns کی چوڑائی تبدیل ہوتی رہتی ہو، تقریباً پورا output نمایاں ہو جائے گا۔ اس لیے مستحکم layout والی commands کو ترجیح دیں۔ موجودہ procps-ng watch --differences=permanent بھی قبول کرتا ہے۔ اس سے صرف حالیہ تبدیلی کے بجائے ہر وہ position نمایاں رہتی ہے جو کبھی تبدیل ہوئی ہو۔ اس پر انحصار کرنے سے پہلے watch --help کے ذریعے اس کی تصدیق کریں۔
آؤٹ پٹ تبدیل ہونے پر watch سے کیسے خارج ہوں؟
-g (--chgexit) آؤٹ پٹ کے پچھلے run سے مختلف ہوتے ہی پہلی بار watch کو روک دیتا ہے۔ آپ کا prompt واپس آ جاتا ہے، اس لیے اسی لائن پر اس کے بعد کچھ لکھ سکتے ہیں۔
watch -n 10 -g 'systemctl is-active myapp' ; echo 'state changed'یہ flag watch کو "deploy مکمل ہونے کی اطلاع دینے والا" tool بنا دیتا ہے۔ اس میں ایک مسئلہ ہے جو ہر کسی کو پیش آتا ہے: comparison پورے آؤٹ پٹ پر ہوتا ہے، اس لیے آؤٹ پٹ میں موجود کوئی بھی clock یا PID (process identifier) پہلی refresh پر ہی بدل جاتا ہے اور watch فوراً خارج ہو جاتا ہے۔ systemctl status myapp گزرا ہوا وقت اور memory use دکھاتا ہے، اس لیے اس پر -g بے فائدہ ہے۔ command کو اس واحد مستحکم حقیقت تک محدود کریں جس کا آپ انتظار کر رہے ہیں؛ systemctl is-active یہی کرتا ہے۔
جدید procps-ng میں اس کے برعکس test، --equexit <cycles>، بھی موجود ہے۔ یہ اتنے cycles تک آؤٹ پٹ یکساں رہنے کے بعد خارج ہو جاتا ہے۔ یہ اس سوال کا جواب دیتا ہے: "معلوم کریں کہ یہ کب خاموش ہو گیا ہے۔" watch --help دیکھیں، کیونکہ پرانی builds میں یہ موجود نہیں ہوتا۔
watch میری pipe اور glob کو کیوں نظر انداز کرتا ہے؟
یہ وہ مسئلہ ہے جس کا سامنا ہر شخص کو کم از کم ایک بار ہوتا ہے، اور اس کی وجہ watch کے بجائے آپ کا shell ہوتا ہے۔
watch docker compose ps | grep webآپ کا interactive shell کوئی بھی command چلنے سے پہلے پوری لائن پڑھ لیتا ہے اور اسے pipe پر تقسیم کر دیتا ہے۔ یہ watch docker compose ps شروع کرتا ہے اور watch کی اپنی screen output کو grep سے جوڑ دیتا ہے۔ watch اب terminal پر نہیں لکھ رہا ہوتا، اس لیے display خراب یا خالی دکھائی دیتا ہے، اور grep container list کے بجائے redraw output کو filter کر رہا ہوتا ہے۔
پوری pipeline کو quote کریں تاکہ وہ ایک ہی argument کے طور پر پہنچے۔
watch 'docker compose ps | grep web'watch اس string کو sh -c کو دیتا ہے، اور وہ shell ہر cycle میں pipeline کو ایک بار چلاتا ہے۔ Globs بھی اسی اصول پر کام کرتے ہیں، لیکن ان کی علامت کم نمایاں ہوتی ہے۔
watch ls -l /var/log/*.log
watch 'ls -l /var/log/*.log'پہلی لائن glob کو ایک ہی بار، آپ کے shell میں، Enter دبانے کے وقت expand کرتی ہے۔ اس کے بعد watch filenames کی منجمد فہرست دوبارہ چلاتا رہتا ہے، اس لیے ایک منٹ بعد بننے والی log file کبھی ظاہر نہیں ہوتی۔ دوسری لائن glob کو watch کے حوالے کرتی ہے، جو اسے ہر cycle میں sh کے اندر expand کرتا ہے؛ اس لیے نئی files خود بخود ظاہر ہو جاتی ہیں۔
Quotes یہ بھی طے کرتے ہیں کہ variable یا command substitution کب evaluate ہو۔ watch "echo $(date)" آپ کے shell میں date کو ایک بار چلاتا ہے، پھر اسی fixed string کو ہمیشہ echo کرتا رہتا ہے۔ watch 'echo $(date)' ہر cycle میں date چلاتا ہے۔ Single quotes کا مطلب ہے بعد میں۔ Double quotes کا مطلب ہے ابھی۔
اس sh -c کے مزید دو نتائج ہیں:
- Aliases اور shell functions اس کے اندر موجود نہیں ہوتے۔
watch ll،sh: 1: ll: not foundکے ساتھ fail ہوتا ہے، کیونکہsh -cآپ کا.bashrcکبھی نہیں پڑھتا۔ اصل command واضح طور پر لکھیں، یا اس binary کا مکمل path دیں جو صرف آپ کے interactivePATHمیں موجود ہے۔ - Standard error کو capture کرنا مفید ہے۔ جب error text کو frame کے اندر ترتیب سے دکھانا ہو، تو quotes کے اندر
2>&1شامل کریں، تاکہ وہ frame کے باہر بکھرا ہوا نظر نہ آئے۔
جب quoting مشکل ہو جائے تو -x (--exec) command کو sh -c کے ذریعے چلانے کے بجائے براہ راست چلاتا ہے۔ Spaces والے arguments آسانی سے handle ہو جاتے ہیں، لیکن pipes اور globs مکمل طور پر کام کرنا بند کر دیتے ہیں، کیونکہ انہیں interpret کرنے کے لیے کوئی shell باقی نہیں رہتا۔
Privileges بھی اسی اصول کے مطابق کام کرتے ہیں، کیونکہ watch ایک عام process ہے۔ watch 'sudo ss -tulpn' ایسا password prompt دکھاتا ہے جسے آپ نہ دیکھ سکتے ہیں نہ اس میں input دے سکتے ہیں۔ اس کے بجائے sudo watch 'ss -tulpn' چلائیں، اور یاد رکھیں کہ پھر پوری loop اس وقت تک root کے طور پر چلتی رہے گی جب تک آپ Ctrl+C نہ دبائیں۔
VPS پر نظر رکھنے کے قابل چار چیزیں
بھرنے والی disk
watch -n 30 -d 'df -h / /var'df ان اعداد و شمار کے لیے kernel سے رجوع کرتا ہے جو kernel پہلے ہی محفوظ رکھتا ہے، اس لیے اسے مسلسل دہرانا کم خرچ ہے۔ du -sh /var/log ایسا نہیں کرتا، کیونکہ یہ ہر cycle میں tree کی ہر file کو پڑھتا ہے۔ watch کے تحت یہ disk کو مسلسل پڑھتا ہے اور اسی machine کو سست کر دیتا ہے جس کی تشخیص آپ کر رہے ہیں۔ du ایک بار چلائیں، یا ncdu استعمال کریں، پھر df کو watch کے تحت چلنے دیں تاکہ معلوم ہو کہ عدد اب بھی بڑھ رہا ہے یا نہیں۔
بار بار restart ہونے والا container
cd /srv/myapp
watch -n 5 -d 'docker compose ps'status column دکھاتا ہے کہ ہر container کتنے وقت سے چل رہا ہے۔ crash loop میں موجود container بار بار "Up 2 seconds" پر reset ہوتا رہتا ہے، اور -d اسے ایک نظر میں واضح کر دیتا ہے۔ پہلے directory تبدیل کریں، کیونکہ watch اسی shell کی working directory استعمال کرتا ہے جس نے اسے شروع کیا تھا، اور docker compose کو اپنے project directory کی ضرورت ہوتی ہے۔ watch بتاتا ہے کہ restart ہو رہا ہے۔ docker compose logs -f web بتاتا ہے کہ ایسا کیوں ہو رہا ہے۔ وجہ معلوم ہونے کے بعد جواب کو ایسے Compose healthcheck میں شامل کریں جو container کو خود restart کرے تاکہ کسی کو screen کے سامنے بیٹھ کر نگرانی نہ کرنی پڑے۔
certificate renewal کا مکمل ہونا
sudo -i
watch -n 60 -g 'openssl x509 -noout -enddate -in /etc/letsencrypt/live/example.com/fullchain.pem'یہ command ایک line، notAfter=Nov 7 09:14:22 2026 GMT، اور اس کے علاوہ کچھ نہیں دکھاتی، اس لیے -g عین اسی وقت چلتا ہے جب file نئی renewed file سے replace ہوتی ہے۔ /etc/letsencrypt/live کے تحت موجود files صرف root پڑھ سکتا ہے، اسی لیے یہ root shell میں چلتا ہے۔ یاد رکھیں کہ یہ disk پر موجود certificate کی نگرانی کرتا ہے۔ چلتا ہوا web server پرانا certificate memory میں رکھتا ہے جب تک اسے reload نہ کیا جائے، اس لیے echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate سے جانچیں کہ حقیقت میں کون سا certificate serve ہو رہا ہے، اور کسی public host کے خلاف اس command کو دو second کے interval پر نہ چلائیں۔ Renewal خود systemd service اور timer کے ذریعے ہوتی ہے، اور systemctl list-timers دکھاتا ہے کہ یہ اگلی بار کب چلے گا۔
queue کا ختم ہوتے جانا
watch -n 15 'postqueue -p | tail -n 1'یہ ایک summary line دکھاتا ہے، مثلاً -- 24 Kbytes in 6 Requests.، یا مکمل ہونے کے بعد Mail queue is empty۔ یہی طریقہ کسی بھی ایسی queue کے لیے کام کرتا ہے جس کی گنتی کی جا سکے: watch -n 5 'find /srv/queue/incoming -type f | wc -l'۔
یہاں watch کی حد سامنے آ جاتی ہے۔ یہ ایک frame کا پچھلے frame سے موازنہ کرتا ہے، اور کسی condition کو test نہیں کر سکتا، اس لیے یہ کبھی نہیں بتا سکتا کہ "count zero تک پہنچ گیا"۔ سادہ shell loop یہ کام کر سکتا ہے۔ ہر pass پر count محفوظ کرنے کے لیے command substitution استعمال کریں:
until [ "$(find /srv/queue/incoming -type f | wc -l)" -eq 0 ]; do sleep 5; done; echo 'queue drained'جب watch کمانڈ مناسب نہ ہو
watch آپ کی کمانڈ کو دوبارہ چلاتا ہے، لیکن اسے پچھلے run کی کوئی یاد نہیں ہوتی اور نہ ہی اسے معلوم ہوتا ہے کہ کمانڈ کیا کرتی ہے۔ df کے لیے یہ کافی ہے۔ تاہم، چار صورتوں میں یہ مناسب نہیں۔
- Logs۔
watchایک مقررہ frame دوبارہ بناتا ہے، اس لیے دو cycles کے درمیان ظاہر ہو کر scroll ہونے والی lines ضائع ہو جاتی ہیں۔journalctl -fu nginxیاtail -fاستعمال کریں۔ یہ نئی lines کو لکھے جانے کے ساتھ stream کرتے ہیں۔ - مہنگی کمانڈز۔
du -sh /یا مصروف database کے خلاف query کسی بھی interval پر مستقل background load بن جاتی ہے، کیونکہwatchاسے بار بار شروع کرتا رہتا ہے۔ - ہر وہ چیز جس کے side effects ہوں۔ جو کمانڈ write، post، restart یا install کرتی ہو، وہ ہر cycle میں دوبارہ یہی عمل کرے گی۔ کسی API کے خلاف ہر دو seconds بعد
curlچلانے سے روزانہ 43,200 requests بنتی ہیں۔ اسی طرح free API key suspend ہو سکتی ہے۔ - طویل عرصے تک چلنے والی checks۔
watchآپ کے terminal میں چلتا ہے اور session ختم ہونے کے ساتھ بند ہو جاتا ہے۔ یہ کسی کو alert نہیں کرتا اور laptop بند کرنے کے بعد کوئی history محفوظ نہیں رکھتا۔ اس مقصد کے لیے Uptime Kuma جیسا حقیقی status monitor استعمال کریں، یا ایسی scheduled check بنائیں جو server پر چلتی رہے۔
حقیقی حد وقت ہے۔ watch اس دس منٹ کے لیے ہے جس میں آپ کسی ایک مخصوص چیز کے ہونے کا انتظار کرتے ہیں۔ جو check کل بھی جاری رہنی چاہیے، اسے scheduled timer یا حقیقی monitor میں منتقل کریں۔
SSH پر ہوں تو tmux کے اندر watch چلائیں
SSH کے ذریعے watch اتنا ہی پائیدار ہوتا ہے جتنا SSH کنکشن۔ کنکشن منقطع ہونے پر آپ کے shell کو SIGHUP موصول ہوتا ہے، اور watch بھی اسی کے ساتھ بند ہو جاتا ہے۔ tmux اس مسئلے کو حل کرتا ہے۔ اسی کی وجہ سے remote server پر watch واقعی مفید بنتا ہے۔
tmux new -As ops
watch -n 30 -d 'df -h /'الگ ہونے کے لیے Ctrl+b دبائیں، پھر d دبائیں۔ یہ loop server پر چلتا رہے گا۔ بعد میں دوبارہ connect کرکے tmux attach -t ops چلائیں۔ frame اب بھی update ہو رہا ہوگا، اور header کی clock اس کی تصدیق کرے گی۔ window کو split کریں۔ ایک طرف watch اور دوسری طرف journalctl -f چلا سکتے ہیں۔ یہی tmux پر مبنی terminal workbench کا بنیادی مقصد ہے۔ جب ایک ہی سوال کا جواب بیک وقت کئی servers پر درکار ہو تو اس کے لیے watch panes کی دیوار کے بجائے متعدد Linux servers manage کرنے کے لیے بنایا گیا tool استعمال کریں۔
یہاں دیے گئے screens صرف مثال کے طور پر ہیں۔ مختلف distributions اور procps-ng releases میں column layout اور version strings مختلف ہو سکتی ہیں۔ اس لیے اپنے machine پر man watch پڑھیں تاکہ معلوم ہو سکے کہ آپ کی build میں واقعی کون سے flags موجود ہیں۔
FAQ
watch میں watch mycmd | grep foo کے بعد آنے والی pipe کو کیوں نظرانداز کرتا ہے؟
آپ کا shell، watch شروع ہونے سے پہلے ہی، pipe پر اس command line کو تقسیم کر دیتا ہے۔ اس طرح watch کی اپنی screen drawing grep کو بھیج دی جاتی ہے، جبکہ command کا output filter نہیں ہوتا۔ پوری pipeline کو quote کریں: watch 'mycmd | grep foo'۔ watch یہ واحد argument sh -c کو دیتا ہے، جو ہر cycle میں pipeline چلاتا ہے۔ یہی اصول globs اور command substitution پر بھی لاگو ہوتا ہے۔
watch کے ساتھ کون سا interval استعمال کرنا چاہیے؟
اسے value کی تبدیلی کی رفتار اور ایک run کی لاگت کے مطابق رکھیں۔ تیز counters کے لیے نصف سیکنڈ موزوں ہے، جبکہ 0.1 seconds وہ کم ترین interval ہے جسے watch قبول کرتا ہے۔ disks اور certificates کے لیے 30 سے 60 seconds موزوں ہیں۔ جب تک آپ -p نہ دیں، command کا runtime gap میں شامل ہو جاتا ہے۔ اس لیے -n 1 کے تحت سست command مسلسل ایک کے بعد ایک چلتی ہے اور کبھی وقفہ نہیں لیتی۔
کیا watch کسی log file کو follow کر سکتا ہے؟
نہیں۔ watch ایک frame دوبارہ بناتا ہے اور کوئی history محفوظ نہیں کرتا۔ اس لیے دو cycles کے درمیان ظاہر ہو کر scroll ہونے والی ہر line ہمیشہ کے لیے ختم ہو جاتی ہے۔ journalctl -fu <unit> اور tail -f نئی lines کو ظاہر ہوتے ہی stream کرتے ہیں، اور logs کے لیے یہی طریقہ درکار ہے۔ watch کو ان values کے لیے رکھیں جن کی current state ہو، مثلاً disk percentage یا queue length۔
جس واقعے کا انتظار ہے، اس کے بعد watch کو کیسے روکوں؟
-g (--chgexit) استعمال کریں اور ایسی command دیں جس کا output اس event تک یکساں رہے۔ clock یا PID پر مشتمل output پہلی refresh پر ہی بدل جاتا ہے اور فوراً exit ہو جاتا ہے، اس لیے systemctl is-active myapp وہاں کام کرتا ہے جہاں systemctl status myapp نہیں کرتا۔ کسی حقیقی condition، مثلاً count کے zero تک پہنچنے، کے لیے shell until loop استعمال کریں، کیونکہ watch صرف یہ معلوم کر سکتا ہے کہ output بدلا ہے۔
جو چیز میرے shell میں کام کرتی ہے، اس کے لیے watch command not found کیوں دکھاتا ہے؟
watch command کو sh -c کے حوالے کرتا ہے، اور وہ shell .bashrc نہیں پڑھتا۔ اس لیے آپ کے aliases اور shell functions وہاں موجود نہیں ہوتے۔ یہ message عموماً sh: 1: ll: not found ہوتا ہے۔ اصل command واضح طور پر لکھیں، یا اس binary کے لیے full path استعمال کریں جو صرف آپ کے interactive PATH پر موجود ہے۔