SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor

أمر watch في Linux: الفاصل، التغييرات والأنابيب

تعلّم استخدام watch في Linux: غيّر الفاصل الافتراضي البالغ ثانيتين، أبرز الفروق، اخرج عند التغيير، واقتبس الأنابيب كي ينفذها الأمر كما تريد.

ما الذي يفعله الأمر watch

يعيد الأمر watch تنفيذ أمر آخر على فاصل زمني ثابت، ويعيد رسم مخرجاته في الموضع نفسه على الشاشة. الفاصل الافتراضي هو ثانيتان. استخدمه عندما تنتظر تغيّر قيمة ما: امتلاء قرص، أو استقرار حاوية، أو إتمام تجديد شهادة، أو انخفاض عناصر قائمة انتظار.

يأتي watch من procps-ng، ويكون مثبتاً مسبقاً على Ubuntu أو Debian VPS جديد ضمن الحزمة procps. تحقّق من الإصدار قبل الاعتماد على أي خيار أدناه، لأن خيارين مفيدين منها أُضيفا حديثاً.

watch --version

في Ubuntu 24.04، يطبع ذلك سطراً مشابهاً لـ watch from procps-ng 4.0.4. والآن ننتقل إلى أبسط مثال مفيد.

watch df -h /

تمسح الشاشة وتعرض سطر ترويسة، ثم سطراً فارغاً، ثم مخرجات df -h /:

Every 2.0s: df -h /                          server1: Sun Aug  9 10:21:44 2026

يظهر على اليسار الفاصل الزمني والأمر الدقيق الذي يشغّله watch. ويظهر على اليمين اسم المضيف والوقت الحالي. الساعة هي الجزء المفيد، لأنها تثبت أن الشاشة ما زالت تُحدَّث عندما لا تتغير الأرقام أدناه. اضغط Ctrl+C للخروج.

يرسم watch إطاراً واحداً يلائم الطرفية. تلتف الأسطر الطويلة، بينما يقتطعها -w بدلاً من ذلك، ولا تُرسم أي محتويات تتجاوز الصف الأخير. لا يوجد سجل تمرير داخل الإطار، لأن كل دورة تستبدل الدورة السابقة. وهذه الحقيقة وحدها تحدد معظم الاستخدامات المناسبة لـ watch.

كم مرة ينبغي أن يعيد watch تشغيل الأمر؟

الثانيتان مجرد قيمة افتراضية. اختر الفاصل الزمني وفق سرعة تغيّر القيمة وتكلفة كل تشغيل.

  • -n 0.5 للعدادات التي تتغير باستمرار، مثل ss -s أو عدد وحدات البايت على واجهة الشبكة. أصغر فاصل زمني يقبله watch هو 0.1 ثانية.
  • -n 30 أو -n 60 للأقراص والشهادات. نظام ملفات يمتلئ خلال يوم لا يحتاج إلى ثلاثين لقطة في الدقيقة.

يشغّل watch الأمر، وينتظر اكتماله، ثم ينتظر الفاصل الزمني. يُضاف وقت التشغيل إلى الفاصل، لذلك فإن أمراً يستغرق ثماني ثوانٍ عند استخدام -n 2 يعطيك لقطة كل عشر ثوانٍ ويبقي الجهاز مشغولاً طوال الوقت. أضف -p (--precise)، وسيحاول watch بدء تشغيل جديد كل عدد محدد من الثواني، ويقيس ذلك من بداية تشغيل إلى بداية التشغيل التالي.

إذا أردت دائماً استخدام قيمة افتراضية مختلفة، فصدّر WATCH_INTERVAL في ملف تعريف الصدفة. تظل قيمة -n الصريحة هي المعتمدة بدلاً منها. شغّل watch --help للتأكد من أن إصدارك يقرأ هذا المتغير.

إبراز التغييرات باستخدام -d

يصعب قراءة كتلة طويلة من النص المتطابق للعثور على الحقل الوحيد الذي تغيّر موضعه. يتولى -d (--differences) ذلك نيابةً عنك.

watch -n 30 -d 'df -h / /var'

تظهر الأحرف التي تختلف عن الإطار السابق بطريقة العرض المعكوسة، لذلك تضيء خلية Use% فور تحركها، بينما يبقى كل شيء آخر دون تغيير. إذا لم يكن /var نظام ملفات مستقلاً، فسترى نظام الملفات الجذري مدرجاً مرتين، وهذه طريقة سريعة لمعرفة كيفية تقسيم الخادم.

تجري المقارنة حسب الموضع، أي إن الأداة تقارن أسطر الإطار الجديد بالإطار القديم حرفاً بحرف. ستضيء مخرجات يتغير عرض أعمدتها بالكامل تقريباً، لذلك يُفضّل استخدام أوامر ذات تنسيق ثابت. يقبل procps-ng الحالي أيضاً watch --differences=permanent، الذي يُبقي كل موضع سبق أن تغيّر مميزاً بدلاً من تمييز التغيير الأحدث فقط. تحقّق من ذلك باستخدام watch --help قبل الاعتماد عليه.

كيف أجعل watch ينتهي عند تغيّر المخرجات؟

يتوقف -g (--chgexit) عن العمل في أول مرة تختلف فيها المخرجات عن التشغيل السابق. يعود موجّه الأوامر، لذا يمكنك وضع شيء بعده في السطر نفسه.

watch -n 10 -g 'systemctl is-active myapp' ; echo 'state changed'

هذا الخيار يحوّل watch إلى أداة «أبلغني عند اكتمال النشر». لكنه يتضمن فخاً واحداً ويقع فيه الجميع: تشمل المقارنة المخرجات كاملة، لذلك يتغير أي وقت أو PID (معرّف العملية) فيها عند أول تحديث، وينتهي watch فوراً. يعرض systemctl status myapp الوقت المنقضي واستخدام الذاكرة، لذا يكون استخدام -g معه غير مفيد. اختصر الأمر إلى الحقيقة الثابتة الوحيدة التي تنتظرها، وهذا ما يوفّره systemctl is-active.

تضيف الإصدارات الأحدث من procps-ng الاختبار العكسي، --equexit <cycles>، الذي ينتهي بعد بقاء المخرجات متطابقة طوال ذلك العدد من الدورات. وهو يجيب عن سؤال «أبلغني عندما يتوقف هذا عن التغيّر». تحقّق من watch --help، لأن الإصدارات الأقدم لا تتضمنه.

لماذا يتجاهل watch الأنبوب وglob؟

يواجه الجميع هذا الخطأ مرة واحدة، والسبب في الصدفة shell وليس في watch.

watch docker compose ps | grep web

تقرأ الصدفة التفاعلية السطر بأكمله قبل تشغيل أي شيء، ثم تقسّمه عند الأنبوب. فتشغّل watch docker compose ps وتوصل مخرجات شاشة watch نفسها بـ grep. لم يعد watch يكتب إلى طرفية، لذلك تصبح الشاشة معطّلة أو فارغة، ويعمل grep على تصفية مخرجات إعادة الرسم بدلاً من قائمة الحاويات.

ضع علامتي اقتباس حول خط الأنابيب بأكمله لكي يصل كوسيط واحد.

watch 'docker compose ps | grep web'

يمرّر watch هذه السلسلة إلى sh -c، ثم تشغّل تلك الصدفة خط الأنابيب مرة واحدة في كل دورة. تنطبق القاعدة نفسها على glob، لكن بأعراض أقل وضوحاً.

watch ls -l /var/log/*.log
watch 'ls -l /var/log/*.log'

يوسّع السطر الأول glob مرة واحدة في صدفتك، عند لحظة الضغط على Enter. ثم يعيد watch تشغيل قائمة ثابتة من أسماء الملفات، لذلك لا يظهر ملف سجل أُنشئ بعد دقيقة. أما السطر الثاني فيمرّر glob إلى watch، الذي يوسّعه داخل sh في كل دورة، فتظهر الملفات الجديدة تلقائياً.

تحدد علامات الاقتباس أيضاً وقت تقييم المتغير أو استبدال الأوامر. يشغّل watch "echo $(date)" الأمر date مرة واحدة في صدفتك، ثم يطبع تلك السلسلة الثابتة إلى الأبد. أما watch 'echo $(date)' فيشغّل date في كل دورة. تعني علامات الاقتباس المفردة: لاحقاً. وتعني علامات الاقتباس المزدوجة: الآن.

ينتج عن sh -c هذا أثران إضافيان:

  • لا تكون الأسماء المستعارة ودوال الصدفة متاحة داخله. يفشل watch ll مع sh: 1: ll: not found، لأن sh -c لا يقرأ .bashrc الخاص بك. اكتب الأمر الفعلي، أو استخدم المسار الكامل لملف ثنائي موجود فقط في PATH التفاعلي.
  • من المفيد التقاط مخرجات الخطأ القياسية. ضع 2>&1 داخل علامات الاقتباس عندما تريد عرض نص الخطأ داخل الإطار بدلاً من توزيعه فوقه.

عندما تصبح علامات الاقتباس معقدة، يشغّل -x (--exec) الأمر مباشرة بدلاً من تشغيله عبر sh -c. تصبح الوسائط التي تحتوي على مسافات أسهل، لكن الأنابيب وglob يتوقفان تماماً عن العمل، لأنه لم تعد هناك صدفة لتفسيرهما.

تتبع الصلاحيات المنطق نفسه، لأن watch عملية عادية. يصل watch 'sudo ss -tulpn' إلى مطالبة كلمة مرور لا يمكنك رؤيتها أو الكتابة فيها. شغّل sudo watch 'ss -tulpn' بدلاً منه، وتذكّر أن الحلقة بأكملها ستعمل عندئذٍ بصلاحيات root إلى أن تضغط Ctrl+C.

أربعة أمور تستحق المراقبة على VPS

قرص تمتلئ مساحته

watch -n 30 -d 'df -h / /var'

يطلب df من kernel قيماً يحتفظ بها مسبقاً، لذلك لا يكلّف تكراره شيئاً تقريباً. أما du -sh /var/log فليس كذلك، لأنه يمر على كل ملف في الشجرة في كل دورة. عند استخدامه مع watch، يقرأ القرص باستمرار ويبطئ الجهاز الذي تحاول تشخيصه. شغّل du مرة واحدة، أو استخدم ncdu، ثم اترك df قيد المراقبة لمعرفة ما إذا كان الرقم لا يزال يرتفع.

حاوية تستمر في إعادة التشغيل

cd /srv/myapp
watch -n 5 -d 'docker compose ps'

يعرض عمود الحالة مدة تشغيل كل حاوية. تبقى الحاوية التي تدخل في حلقة انهيار تعيد ضبط حالتها إلى "Up 2 seconds"، ويجعل -d ذلك واضحاً فوراً. غيّر الدليل أولاً، لأن watch يرث دليل العمل من shell الذي شغّله، ويحتاج docker compose إلى دليل المشروع الخاص به. يخبرك watch بحدوث إعادة تشغيل. أما docker compose logs -f web فيخبرك بالسبب. بعد معرفة السبب، حوّل الإجابة إلى فحص سلامة في Compose يعيد تشغيل الحاوية نيابةً عنك حتى لا يضطر أحد إلى الجلوس والتحديق في الشاشة.

تثبيت تجديد شهادة

sudo -i
watch -n 60 -g 'openssl x509 -noout -enddate -in /etc/letsencrypt/live/example.com/fullchain.pem'

يطبع الأمر سطراً واحداً، notAfter=Nov 7 09:14:22 2026 GMT، ولا يطبع شيئاً آخر، لذلك يعمل -g بالضبط عندما يُستبدل الملف بملف مجدَّد. لا يمكن قراءة الملفات تحت /etc/letsencrypt/live إلا بواسطة root، ولذلك يُشغَّل هذا الأمر في root shell. انتبه إلى أنه يراقب الشهادة الموجودة على القرص. يحتفظ خادم الويب قيد التشغيل بالشهادة القديمة في الذاكرة إلى أن يعيد تحميلها، لذلك تحقّق مما يُقدَّم فعلياً باستخدام echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate، ولا تشغّل ذلك الأمر كل ثانيتين مقابل مضيف عام. تتم إدارة التجديد نفسه عبر خدمة systemd ومؤقت، ويعرض systemctl list-timers موعد التشغيل التالي.

تناقص عناصر قائمة انتظار

watch -n 15 'postqueue -p | tail -n 1'

يطبع ذلك سطر ملخص مثل -- 24 Kbytes in 6 Requests.، أو Mail queue is empty بعد الانتهاء. ويصلح النمط نفسه لأي قائمة انتظار يمكنك عدّ عناصرها: watch -n 5 'find /srv/queue/incoming -type f | wc -l'.

هنا يصل watch إلى حدوده. فهو يقارن إطاراً بالإطار السابق له، ولا يستطيع اختبار شرط، لذلك لا يمكنه إخبارك بأن "العدد وصل إلى الصفر". يمكن لحلقة shell عادية إجراء ذلك، باستخدام استبدال الأوامر لالتقاط العدد في كل دورة:

until [ "$(find /srv/queue/incoming -type f | wc -l)" -eq 0 ]; do sleep 5; done; echo 'queue drained'

عندما يكون الأمر watch أداة غير مناسبة

يعيد watch تشغيل الأمر من دون حفظ أي معلومات عن التشغيل السابق، ومن دون معرفة ما يفعله ذلك الأمر. هذا مناسب لـ df. لكنه غير مناسب في أربع حالات.

  • السجلات. يعيد watch رسم إطار ثابت، لذلك تضيع الأسطر التي تظهر وتختفي أثناء التمرير بين دورتين. استخدم journalctl -fu nginx أو tail -f، فهما يعرضان الأسطر الجديدة فور كتابتها.
  • الأوامر المكلفة. يصبح du -sh / أو الاستعلام الموجّه إلى قاعدة بيانات مشغولة حملاً دائماً في الخلفية مهما كان الفاصل الزمني، لأن watch يواصل تشغيله من جديد.
  • أي شيء له آثار جانبية. سيعيد الأمر الذي يكتب أو يرسل أو يعيد التشغيل أو يثبّت تنفيذ العملية في كل دورة. إنّ تنفيذ curl ضد واجهة API كل ثانيتين يعني 43,200 طلب في اليوم، وهذا قد يؤدي إلى تعليق مفتاح API المجاني.
  • عمليات التحقق طويلة الأمد. يعمل watch في الطرفية ويفشل عند انتهاء جلستك. لا يرسل تنبيهات إلى أي جهة، ولا يحتفظ بسجل بعد إغلاق الحاسوب المحمول. لذلك تحتاج إلى مراقب حالة فعلي مثل Uptime Kuma، أو إلى عملية تحقق مجدولة تعمل على الخادم.

الحد الفاصل الفعلي هو الزمن. استخدم watch خلال الدقائق العشر التي تنتظر فيها حدوث أمر محدد. أما أي شيء ينبغي أن يستمر في التحقق غداً، فينتمي إلى مؤقت مجدول أو إلى أداة مراقبة فعلية.

شغّل watch داخل tmux عند استخدام SSH

عبر SSH، يعتمد استمرار watch على استمرار الاتصال. عند انقطاع الاتصال، تتلقى الصدفة SIGHUP، فتتوقف watch معها. يحل tmux هذه المشكلة، ولذلك تصبح watch مفيدة فعلاً على خادم بعيد.

tmux new -As ops
watch -n 30 -d 'df -h /'

اضغط Ctrl+b ثم d لفصل الجلسة. تستمر الحلقة في العمل على الخادم. أعد الاتصال لاحقاً باستخدام tmux attach -t ops، وستظل الشاشة تتحدث، وتثبت ساعة الترويسة ذلك. قسّم النافذة، ويمكنك إبقاء watch في جانب وjournalctl -f في الجانب الآخر. هذه هي الفكرة الأساسية وراء بيئة عمل طرفية تعتمد على tmux. عندما ينطبق السؤال نفسه على عدة خوادم في الوقت نفسه، فاستخدم أداة مخصصة لإدارة خوادم Linux متعددة بدلاً من ملء الشاشة بنوافذ watch.

الشاشات المعروضة هنا توضيحية. يختلف تخطيط الأعمدة ونص الإصدار بين التوزيعات وإصدارات procps-ng، لذلك اقرأ man watch على جهازك لمعرفة الخيارات التي يدعمها الإصدار المثبّت لديك فعلياً.

FAQ

لماذا يتجاهل watch الأنبوب في watch mycmd | grep foo؟

تقسّم الصدفة السطر عند الأنبوب قبل أن يبدأ watch، لذلك توجّه ناتج رسم watch نفسه إلى grep، ولا تُرشَّح مخرجات الأمر. ضع خط الأنابيب بالكامل بين علامتي اقتباس بدلاً من ذلك: watch 'mycmd | grep foo'. يمرّر watch هذه الوسيطة المفردة إلى sh -c، الذي يشغّل خط الأنابيب مرة واحدة في كل دورة. وتنطبق القاعدة نفسها على الأنماط العامة واستبدال الأوامر.

ما الفاصل الزمني الذي ينبغي استخدامه مع watch؟

اضبطه وفق سرعة تغيّر القيمة وكلفة تشغيل الأمر مرة واحدة. يناسب نصف ثانية العدادات السريعة، ويمثل 0.1 ثانية أصغر فاصل يقبله watch. يناسب الفاصل من Thirty إلى sixty ثانية الأقراص والشهادات. يُضاف وقت تشغيل الأمر إلى الفاصل ما لم تمرّر -p، لذلك فإن الأمر البطيء مع -n 1 يُشغَّل مباشرة مرة بعد أخرى ولا يتوقف مؤقتاً.

هل يستطيع watch متابعة ملف سجل؟

لا. يعيد watch رسم إطار واحد ولا يحتفظ بالسجل، لذلك يختفي نهائياً أي سطر يظهر ثم يمر خارج الشاشة بين دورتين. يبث journalctl -fu <unit> وtail -f الأسطر الجديدة عند وصولها، وهذا ما تحتاج إليه السجلات. استخدم watch للقيم التي تمثل حالة حالية، مثل نسبة استخدام القرص أو طول قائمة الانتظار.

كيف أجعل watch يتوقف عند حدوث الشيء الذي أنتظره؟

استخدم -g (--chgexit)، ومرّر إليه أمراً تبقى مخرجاته متطابقة حتى وقوع الحدث. تتغير المخرجات التي تحتوي على ساعة أو PID عند أول تحديث، فينتهي التنفيذ فوراً، لذلك يعمل systemctl is-active myapp في الحالات التي لا يعمل فيها systemctl status myapp. بالنسبة إلى شرط فعلي، مثل وصول العدد إلى الصفر، استخدم حلقة صدفة until، لأن watch لا يستطيع إلا اكتشاف تغيّر المخرجات.

لماذا يقول watch إن الأمر غير موجود مع أن الأمر يعمل في صدفةي؟

يمرّر watch الأمر إلى sh -c، وهذه الصدفة لا تقرأ .bashrc، لذلك لا تتوفر فيها الأسماء المستعارة ودوال الصدفة لديك. تكون الرسالة عادةً sh: 1: ll: not found. اكتب الأمر الفعلي صراحةً، أو استخدم المسار الكامل لملف ثنائي لا يوجد إلا في PATH التفاعلية لديك.