الإشارات في Bash

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

صفحة man للإشارات

يحتوي نظامك على صفحة man بها كل الإشارات المتاحة، لكن قد يُفتح بطريقة مختلفة اعتمادًا على نظام تشغيلك، والطريقة التي ستجدها في أغلب أنظمة لينكس هي man 7 signal، لكن إن كنت في ريب من الأمر فحدد صفحة man والقسم الذي تريده بالضبط باستخدام أوامر مثل:

man -k signal | grep list

أو

apropos signal | grep list

ستجد أسماء الإشارات باستخدام kill -l.

الإشارات إلى صدفة Bash الخاصة بك

تتجاهل صدفة bash التفاعلية إشارتي SIGTERM و SIGQUIT في غياب الأفخاخ (Traps)، وتُلتقط SIGINT ويُتعامل معها، ويتم تجاهل كل من SIGTTIN و SIGTTOU و SIGTSTP إن كان التحكم في الوظائف (job control) نشطًا. وكذلك فإن الأوامر التي تُشغَّل كنتيجة لاستبدال الأوامر (command substitution) تتجاهل أيضًا تلك الإشارات حين تولَّد عن طريق لوحة المفاتيح.

افتراضيًا، تُغلِق إشارةُ SIGHUP الصدفة، وسوف ترسل الصدفة التفاعلية إشارة SIGHUP إلى كل الوظائف (jobs) سواء العاملة منها أو المتوقفة، انظر توثيق أمر disown إن كنت تريد إيقاف هذا السلوك الافتراضي لعملية معينة.

استخدم خيار huponexit لقتل كل الوظائف عند استقبال إشارة SIGHUP باستخدام أمر shopt.

إرسال الإشارات باستخدام الصدفة

يمكن إرسال الإشارات التالية باستخدام صدفة bash:

جدول 12-1. إشارات التحكم في Bash

المجموعة الافتراضية للمفاتيح الوظيفة
ctrl+c إشارة الاعتراض، ترسل SIGINT إلى الوظيفة التي تعمل في الواجهة.
ctrl+y إشارة الإيقاف المؤجل، تُوقِف العملية الحالية حين تحاول قراءة مدخلات من الطرفية ويعود التحكم إلى الصدفة، ويستطيع المستخدم قتل العملية أو جعلها تعمل في الواجهة أو الخلفية. لا تتاح إشارة الإيقاف المؤجل إلا على أنظمة التشغيل التي تدعم هذه الخاصية.
ctrl+z إشارة الإيقاف، ترسل SIGTSTP إلى برنامج ما لإيقافه ومن ثَم إعادة التحكم إلى الصدفة.

إعدادات الطرفية

تفقَّد إعدادات stty لديك إذ أن إيقاف وإعادة التشغيل لخرج ما تكون عادة معطلة إن كنت تستخدم محاكيات طرفية حديثة، أما xterm فتدعم ctrl+s و ctrl+q افتراضيًا

استخدام الإشارات مع kill

تحتوي أغلب الصدفات الحديثة -بما فيها bash- على أمر kill مضمَّن، وتقبل bash الأسماء والأرقام كخيارات، وكذلك مسموح أن تكون الوسائط معرفات للوظائف أو العمليات. ويمكن إرسال تقرير بحالة خروج باستخدام الخيار l- بحيث يعطي صفرًا في حالة نجاح إرسال إشارة واحدة على الأقل، وقيمة غير صفرية في حالة الأخطاء.

قد يفعِّل النظام خيارات إضافية عند استخدام أمر kill من usr/bin/، مثل إمكانية قتل العمليات من معرّف مستخدم (user ID) غير المعرّف الخاص بك، وتحديد العمليات بأسمائها، مثل pgrep و pkill. يرسل كلا أمريْ kill إشارة TERM إن لم يُعط لها شيء.

هذه قائمة بالإشارات المشهورة:

جدول 12-2. إشارات القتل المشهورة في Bash

اسم الإشارة قيمة الإشارة التأثير
SIGHUP 1 إغلاق (hangup)
SIGINT 2 اعتراض من لوحة المفاتيح
SIGKILL 9 إشارة قتل
SIGTERM 15 إشارة إنهاء (termination)
SIGSTOP 17، 19، 23 إيقاف العملية (stop)

SIGKILL و SIGSTOP

لا يمكن التقاط أو حجب أو تجاهل SIGKILL أو SIGSTOP.

حين تريد قتل عملية أو سلسلة عمليات فمن المنطقي أن تبدأ بإشارة SIGTERM لأنها الإشارة الأقل خطورة وأثرًا، فبتلك الطريقة تحظى البرامج التي صُممت لتتبع إجراءات مرتبة للإغلاق بفرصة لاتباع تلك الإجراءات التي صُمِّمَت لتنفذها حين تستلم إشارة SIGTERM، مثل عمليات التنظيف والمسح (cleaning up) وإغلاق الملفات المفتوحة. أما إن أرسلت إشارة SIGKILL إلى عملية فإنك تلغي أي فرصة لها في تنفيذ تنظيف وإغلاق منظم مما قد يُحدث عواقب مؤسفة. لكن لو لم تنجح عملية الإنهاء النظيف فقد لا يكون أمامك سوى إشارتي INT أو KILL، فمثلًا إن لم تتوقف عملية باستخدام ctrl+c فمن الأفضل استخدام kill -9 على معرِّف تلك العملية:

hsoub: ~> ps -ef | grep stuck_process
hsoub    5607   2214  0 20:05 pts/5    00:00:02 stuck_process

hsoub: ~> kill -9 5607

hsoub: ~> ps -ef | grep stuck_process
hsoub    5614    2214 0 20:15 pts/5    00:00:00 grep stuck_process
[1]+ Killed		stuck_process

وفي حالة فتح العملية لأكثر من نسخة فإن استخدام killall يكون أسهل حينها، وهذا الأمر يأخذ نفس خيارات الأمر kill العادي، لكنه يطبقها على كل نسخ العملية التي يستهدفها. لكن يجب أن تختبر هذا الأمر قبل استخدامه في بيئة إنتاج إذ أنه قد لا يعمل كما يجب في بعض أنظمة يونكس التجارية.

انظر أيضًا

مصادر