تتم مقاطعات البرامج على أنظمة Linux و Unix عبر الإشارات. هناك العديد من إشارات Linux المختلفة ، ولكن القليل منها بارز ومهم لفهمه ومعرفته: SIGINT و SIGTERM و SIGKILL. وإليك طريقة عملها.
ما هي إشارة Linux؟
نتفهم جميعًا أن الضوء الأحمر يعني أنه يتعين علينا التوقف عن المشي أو القيادة. وبالمثل ، في أنظمة Linux و Unix ، يمكن للمرء تمرير إشارة إلى برنامج أو خدمة قيد التشغيل للتفاعل معها. على سبيل المثال ، يمكن للمرء إرسال إشارة ضوئية حمراء إلى برنامج ببساطة عن طريق إصدار إشارة
SIGTERM.
تمامًا كما هو الحال مع إشارة المرور الحمراء ، قد يختار الأشخاص الاستمرار في المشي أو القيادة عندما يكون الضوء أحمر. في حين أن هذه قد لا تكون فكرة آمنة لجميع المعنيين ، فإن إرسال إشارة
SIGTERMإلى عملية ما سيفعل ذلك بالضبط ؛ قد تختار العملية / البرنامج تجاهل مثل هذه الإشارة.
تحتوي جميع إشارات Linux الأساسية على رقم (1-30 +). بعد فترة قصيرة ، سيعرف مستخدم Linux الماهر بشكل عام واحدًا أو أكثر من هؤلاء. على سبيل المثال ، إشارة
SIGTERM
تتطابق مع الرقم 15 ، والإشارة 9 (
SIGKILL
) هي على الأرجح الأكثر شهرة لأنها تتيح للمرء إنهاء العملية بقوة ، على عكس مثال الضوء الأحمر
SIGTERM.

هنا نرى الشاشة الرئيسية
htop
(يمكنك تثبيت هذه الأداة المفيدة بكتابة
sudo apt install htop
على Ubuntu / Mint ، أو
sudo yum install htopعلى RedHat / Centos / Fedora) مع عدد من إشارات الإنهاء والإشارات الأخرى (أقل في القائمة ؛ هناك 37 في المجموع) والتي يمكن إرسالها إلى عملية تم تحديده مسبقًا على اليمين.يمكن للمرء تحديد عملية بالضغط على المؤشر لأعلى / لأسفل ثم إرسال إشارة باستخدام F9.
SIGKILL & SIGTERM
في حين أن الاسم قد يبدو مشؤومًا بعض الشيء ، فإن لغة Linux الشائعة لإنهاء العملية هي أن الشخص "يقتل" العملية. بشكل عام ، سنرغب فقط في إنهاء العملية بإشارة
-9
(
SIGKILL) إذا كانت هذه العملية / البرنامج معلقة. لاحظ أنه كلما تحدثنا عن عملية أو برنامج ، يمكن تبادل الكلمات حسب الرغبة. في الأساس ، العملية هي أي برنامج (أو خدمة) قيد التشغيل تم إعطاؤها PID (معرف عملية).
دعونا نلقي نظرة على مثال لإنهاء عملية في الخلفية قيد التشغيل باستخدام إشارة
SIGKILL
لعملية التشغيل. لاحظ أنه كما هو موضح
SIGKILLمدمر إلى حد ما وسوف ينهي العملية بغض النظر عن ما تود العملية القيام به بالإشارة. يمكن التقاط عدد من الإشارات وإعادة توجيهها من خلال العملية ، بينما لا يمكن للآخرين ذلك.

هنا بدأنا
sleep 1800
في الخلفية (باستخدام
&
في نهاية الأمر) ، والتي بدأت باسم أولاً (
[1]
) عملية الخلفية باستخدام
PID 574660
لقد قتلنا لاحقًا عملية الخلفية هذه باستخدام
kill -9 574660، حيث يرمز
-9
إلى
SIGKILL
أثناء إنهاء العملية على الفور ، لا نرى رسالة الإنهاء (عملية الخلفية
1
مقتول ، أي
[1] + Killed) حيث يعود موجه الأوامر قبل عرض الرسالة ، أي أن إرجاع سطر الأوامر كان عملية أسرع ثم إنهاء العملية أو ما شابه.
نتحقق من قائمة العمليات عن طريق الاستيلاء على PID
ps -ef | grep 574660
. في حين أن هناك بعض المخرجات ، فإن الإخراج الموضح هو فقط لتشغيل الأمر
grep
؛ تم بالفعل إنهاء عملية
sleep.
دعونا نقيم الشيء نفسه مع
SIGTERM
، أي
kill -15 $ {PID}
حيث
$ {PID}هي العملية التي نريد إنهاؤها.

كان علينا الضغط على إدخال لتشغيل / إظهار رسالة الإنهاء (كما هو موضح أعلاه). يمكننا أن نرى أن البرنامج انتهى بشكل صحيح مرة أخرى. ومع ذلك ، هذه المرة ، بينما غير مرئي لهذا المثال بالذات (اقرأ!) ، داخليًا داخل رمز البرنامج
sleep، سارت الأمور بشكل مختلف قليلاً.
في هذه الحالة (باستخدام
-15
ie
SIGTERM
لإنهاء العملية) ،
sleep تم إخطار العملية وأتيحت لها الفرصة للتعامل مع الإشارة داخليًا. يمكن أن يستجيب لاحقًا عن طريق الإنهاء الذاتي ، أو بتجاهل الإشارة ، أو بأي إجراء آخر تم تطويره في الكود. يمكننا أيضًا إثبات صحة ذلك عن طريق التحقق من إشارة الخروج و / أو الإخراج:

هنا بدأنا العملية
sleep 2000
مرتين ، ثم استخدمنا جلسة shell / terminal أخرى لإنهاء البرنامج. في المرة الأولى ، استخدمنا
kill -9
وفي المرة الثانية استخدمنا
kill -15
لإيقاف
sleep عملية
نلاحظ على الفور كيف أن الناتج يُرجع
Killed
في المثيل الأول (
kill -9
action). بالنسبة للمحاولة الثانية (باستخدام
kill -15
) ، نرى الإخراج
تم إنهاؤهبدلاً من ذلك ؛ البرنامج منتهي ذاتيًا. بعد الإنهاءات ذات الصلة ، قمنا أيضًا بفحص إشارات الخروج ، ووجدنا أن رموز الخروج كانت مختلفة.
لماذا هذا مهم؟ النظر في برامج أكبر ؛ في هذه الحالة ، كنا ننهي أمرًا بسيطًا
sleep
. لم يتم التعامل مع أي بيانات ، ولم يتم إرسال أي حركة مرور للخلف / للخلف ، وما إلى ذلك.ولكن ماذا سيحدث إذا أرسلنا الأمر
kill -9إلى خادم قاعدة البيانات الخاص بنا (سيتطلب هذا بشكل عام امتيازات sudo / على مستوى الجذر)؟
سيؤدي ذلك إلى تشغيل قاعدة البيانات للانتقال إلى وضع استرداد الأعطال في المرة التالية التي تبدأ فيها لأنه ، على حد علم برنامج قاعدة البيانات ، كل ما حدث كان "كان هناك" متبوعًا بـ "لا شيء". بعبارة أخرى ، تحطمت. إذا كنا قد أصدرنا بدلاً من ذلك الأمر
kill -15، فربما يكون برنامج قاعدة البيانات قد قام بإيقاف تشغيل متحكم فيه ، على سبيل المثال ، أولاً عن طريق منع المستخدمين الجدد من الاتصال ، ثم فصل / إنهاء المستخدمين الحاليين ، ثم الانتهاء من كتابة البيانات ، وما إلى ذلك قبل الإنهاء الذاتي في النهاية.
إرسال إشارات Linux مع تسلسل لوحة المفاتيح
هل تعلم أنه كلما أرسلت تسلسل مفاتيح
CTRL + c
إلى برنامج قيد التشغيل ، على سبيل المثال في محطة طرفية ، فهذا بدلاً من ذلك
SIGINTيتم إرسالها؟ دعنا نعود إلى الأمر الموثوق به
sleep
ونختبر هذا:

هنا بدأنا
sleep
مرة أخرى ، ثم ضغطنا على تركيبة لوحة المفاتيح
CTRL + c
تم إنهاء البرنامج ، أو الأفضل تمت مقاطعته بواسطة
SIGINTإشارة تم إرسالها. نطلب كود الخروج ونؤكد مرة أخرى أن كود الخروج مختلف عن الإشارات السابقة.
لاحظ أن رمز الخروج هذا ، للنوم ، سيكون دائمًا متطابقًا مع الإشارة المرسلة ، على الرغم من أنه من المحتمل ألا تتم تغطية جميع الإشارات. بمعنى آخر ، عند استخدام
CTRL + c
في سطر الأوامر ، سيكون رمز الخروج دائمًا
130
،
137
عند القتل بـ
kill -9
، و
143
عندما تم استخدام
kill -15.
يمكنك اختبار أكواد الخروج للأوامر من خلال الاستعلام عن المتغير
$؟، الذي يحمل رمز الخروج للأمر السابق (طالما أنك لم تبدأ أمرًا جديدًا).إن معرفة كود الخروج لأمر معين في موقف معين ، و / أو كنتيجة لإشارة معينة مرسلة إلى هذا الأمر ، تساعد عند برمجة الحلول التي تتعامل مع العمليات الأخرى ، وما إلى ذلك (وهذا هو الحال بالنسبة للعديد من البرامج النصية للقذيفة ، خاصةً عند إدارة الخوادم أو البيئات الآلية).
تسلسل لوحة مفاتيح آخر يستخدم كثيرًا هو
CTRL + z
هذا سيرسل إشارة
SIGTSTP
،
تعليق
إشارة تضع العملية فورًا في حالة تعليق حتى (على سبيل المثال) يتم إصدار أمر
'fg'لنفس العملية والذي سيعيدها إلى المقدمة.
لمعرفة المزيد حول إدارة العمليات ، راجع Bash Process Termination Hacks
التفاف
في هذه المقالة ، نظرنا إلى أهم إشارات Linux وكيف يمكننا استخدامها عمليًا في بيئة Linux أو Unix. تساعد معرفة إشارات Linux الأساسية الشخص مع استخدام Linux اليومي وإدارته ، على سبيل المثال ، عندما تكون العملية معلقة وتحتاج إلى إنهاء باستخدام
kill -9
في مقال مستقبلي ، قد ننظر في التقاط إشارة باستخدام الأمر
trapمن داخل برنامج Bash النصي ، مما يسمح للشخص بتحديد إجراء مخصص ليتم تنفيذه عند إصدار مثل هذه الإشارة.
إذا كنت قد استمتعت بقراءة هذا المقال ، فقم بإلقاء نظرة على سلسلة أتمتة Bash بدءًا من Bash Automation & Scripting Basics. في المقالة الثالثة من هذه السلسلة ، نناقش أيضًا إدارة العمليات في الخلفية ، والتي تم التطرق إليها سابقًا في هذه المقالة.