متوفر أيضًا بلغات أخرى: English · Español · Português · Français
شرح رموز الخروج
ابحث عن رمز خروج في يونكس، وانظر كل القراءات التي يحتملها، وأي وثيقة تسند كلًّا منها.
ما رمز الخروج؟
حين ينتهي برنامج يسلّم النظام رقمًا واحدًا بين 0 و255. فالصفر يعني أنه نجح، وما سواه يعني أنه لم ينجح، وهذا كل المضمون تقريبًا. ويحفظ الصدف هذا الرقم في المتغير الذي يُكتب بعلامة استفهام، وتطبعه أنظمة التكامل المستمر حين تخفق خطوة، وتبلّغ عنه مشغّلات الحاويات حين يتوقف شيء.
وأكثر جداول رموز الخروج على الشبكة تعرض قائمة واحدة مسطّحة — 0 نجاح، و1 خطأ عام، و2 سوء استعمال الأوامر المدمجة، ومن 64 إلى 78 من sysexits، و126، و127، و128 زائد رقم الإشارة — كأن معيارًا واحدًا قال ذلك كله. وبقراءة الوثائق نفسها تجد هذه الصفوف آتية من أربعة مواضع مختلفة، وأشهرها ليس آتيًا من موضع أصلًا. وهذه الصفحة تفك الرمز وتخبرك، عند كل قراءة، أي وثيقة وراءها.
وليس هذا التمييز تنطعًا، بل هو الفرق بين قاعدة تنتظر من برنامج آخر أن يلتزمها، وعادةٍ شاعت في الزاوية التي تعلمت فيها.
كيفية الاستخدام
- اكتب الرقم. أيًّا كان ما أظهره سجل التكامل المستمر أو مشغّل الحاويات أو الصدف. والأزرار تغطي أكثر ما يأتي به الناس.
- اقرأ القراءات كلها لا الأولى وحدها. فالرقم الواحد قد يكون أشياء عدة معًا: 64 رمزٌ من sysexits وهو في الوقت نفسه رقم عادي اختاره برنامج لأسبابه، وعرض أحدهما دون الآخر ادعاء لا تسنده المصادر.
- انظر من يعرّفه. كل قراءة موسومة بـ POSIX أو دليل Bash أو sysexits.h أو لا معيار. وهذا الوسم هو ما يستحق أن يُحفظ.
أي الأرقام محدَّد فعلًا
يثبّت معيار POSIX، في باب لغة الصدف، القليل جدًا: الصفر للنجاح، و127 حين لا يُعثر على الأمر، و126 حين يوجد ولا يمكن تشغيله. وهذه الثلاثة يُعوَّل عليها في كل مكان. أما البرنامج الذي تقتله إشارة فيقول عنه فقط إن الرمز سيكون أكبر من 128 وإنه سيحدد الإشارة بطريقة تعرّفها كل تنفيذة بنفسها، ولا يقول 128 زائد رقم الإشارة.
وهذا الجزء الأخير يفاجئ، لأن 128 زائد رقم الإشارة هو ما يحدث بالضبط. لكنه في دليل Bash لا في POSIX: يذكر bash أن الأمر إذا انتهى بإشارة قاتلة رقمها N استعمل 128+N. وبالقياس هنا على bash وdash وصدف النظام اتفقت الثلاثة: عملية قتلها SIGTERM أعادت 143، وSIGKILL أعادت 137، وSIGINT أعادت 130، وSIGHUP أعادت 129. وهو موثوق عمليًا، وهو وعد صدفٍ لا وعد معيار.
ويعرّف bash كذلك الرقم 2، لكن أضيق كثيرًا مما توحي به الجداول: فكل أوامره المدمجة تعيد 2 للدلالة على استعمال خاطئ، كخيار غير صالح أو مُعامل ناقص. وهذه حقيقة عن أوامر bash المدمجة، لا نصيحةٌ في ما ينبغي أن يعيده سكربتك، ولا شيء يلزم أي برنامج آخر باتباعها.
ثم يأتي الرقم 1، أكثر رموز الخروج ورودًا في جداول الإنترنت، وموسومًا في كل مكان بأنه خطأ عام. ولا وثيقة تعرّفه: يقول POSIX ودليل Bash فقط إن ما خالف الصفر يدل على إخفاق. وبعدّ القيم الـ256 الممكنة تجد وثيقةً ما تقول شيئًا عن خمسين منها، وتبقى الـ206 الأخرى متروكة للبرنامج وحده.
أمران تخطئ فيهما الجداول
أولهما sysexits. فالرموز من 64 إلى 78 تُعرض في كل مكان بوصفها رموز الخروج المعيارية، ولم تكن قط من POSIX. مصدرها ملف ترويسي بلغة سي كُتب لأجل sendmail، والملف صريح مع نفسه صراحةً لافتة: يقول إن القيم لا توجد إلا لتوافق الواجهات وإنها متروكة في برمجيات FreeBSD الأساسية، وإنها كُتبت لأجل sendmail خصوصًا، ثم — قبل سردها مباشرةً — إن معنى الرموز على وجه التقريب كما يلي. ومجموعة ثوابت يصف واضعها معانيها بأنها تقريبية عُرفٌ معقول داخل مشروع يستعمله أصلًا، ورهانٌ رديء إن انتظرت من برنامج شخص لا تعرفه أن يحترمه.
وثانيهما أن 128 زائد رقم إشارة لا يحدد الإشارة دائمًا. فالرجوع من الرمز إلى الإشارة يقتضي معرفة أي إشارة تحمل ذلك الرقم، وأرقام الإشارات ليست واحدة في كل مكان. ففي لينكس على x86 الإشارة 10 هي SIGUSR1، وعلى Alpha وSPARC وmacOS هي SIGBUS. فالرمز 138 يعني إشارة مستخدم على جهاز وخطأ ناقل على آخر، ولا جدول يطبع اسمًا واحدًا يصحّ في الحالتين. اكتب 138 في الأعلى فترى الأداة تعرض الانقسام بدل أن تختار عنك.
وثمة فخ أصغر في الاتجاه المقابل. فالرمز ثمانية بتات، وإعادة ما هو أكبر تلتفّ في صمت: فالأمر exit 256 يصل 0، فينقلب الإخفاق نجاحًا. وبالقياس هنا عاد exit 300 بالقيمة 44، وexit 257 بالقيمة 1. والسالب أسوأ من مجرد الالتفاف: حوّل bash القيمة -1 إلى 255، بينما رفضها dash برسالة رقم غير مشروع وأعاد 2، فالسكربت نفسه يبلّغ عن إخفاقين مختلفين بحسب الصدف الذي شغّله.
لماذا لا يعني خلافُ الصفر أن شيئًا انكسر
العُرف الذي يحمله الجميع أن الصفر على ما يرام وأن ما سواه مشكلة. والأداتان الأكثر ظهورًا في أنبوب أوامر تناقضانه: يعيد grep الرقم 1 حين لا يجد تطابقًا لا غير، ويحجز 2 للخطأ الحقيقي. ويعيد diff الرقم 1 حين يختلف الملفان، وهو الجواب الطبيعي للسؤال الذي طُرح عليه، ويحجز 2 كذلك. ويفعل cmp مثلهما.
وهذا هو السبب العملي في أهمية التنبيه الذي يظهر أسفل كل نتيجة في هذه الصفحة. فالسكربت العامل تحت set -e سيتوقف عند grep لم يجد شيئًا، لأن الصدف لا يفرّق بين جواب بالنفي وبين إخفاق: كلاهما 1. ومعرفة أي أدواتك تستعمل 1 جوابًا لا خطأً أنفع من أي جدول رموز معيارية، لأنها الحالة التي تعضّ فعلًا.
وإن كنت تختار رموزًا لبرنامجك أنت: فالصفر للنجاح، وما خالفه للإخفاق، ووثّق ما يعنيه كل رقم. هذا كل العقد القابل للنقل. وإن أردت بنيةً أكثر فاختر نظامًا واكتبه، لأن قارئ رمز خروجك لا سبيل له إلى معرفته.
لماذا هي مجانية؟
هذه جدول بحث وشيء من الحساب، تعمل داخل متصفحك. فلا شيء يُشغَّل على خادم، فلا شيء يُتقاضى ولا حساب يُنشأ.
ولا يُرفع شيء مما تكتبه ولا يُخزَّن ولا يُسجَّل، وما كان ليكون في التسجيل كبير فائدة: فالمُدخَل رقم بين 0 و255.