ما المقصود بـ stdin و stdout و stderr على Linux؟

نشرت: 2022-01-29
نافذة المحطة الطرفية على كمبيوتر Linux
فاطماواتي أحمد زينوري / Shutterstock.com

stdin و stdout و stderr هي ثلاثة تدفقات بيانات تم إنشاؤها عند تشغيل أمر Linux. يمكنك استخدامها لمعرفة ما إذا كان يتم توجيه البرامج النصية الخاصة بك أو إعادة توجيهها. نوضح لك كيف.

تيارات الانضمام إلى نقطتين

بمجرد أن تبدأ في التعرف على أنظمة التشغيل التي تشبه Linux و Unix ، ستصادف المصطلحات stdin و stdout و stederr . هذه هي ثلاثة تدفقات قياسية يتم إنشاؤها عند تنفيذ أمر Linux. في الحوسبة ، الدفق هو شيء يمكنه نقل البيانات. في حالة هذه التدفقات ، تكون هذه البيانات نصية.

تيارات البيانات ، مثل تيارات المياه ، لها طرفان. لديهم مصدر وتدفق خارجي. أيًا كان أمر Linux الذي تستخدمه يوفر طرفًا واحدًا لكل دفق. يتم تحديد الطرف الآخر بواسطة القشرة التي أطلقت الأمر. سيتم توصيل هذه النهاية بالنافذة الطرفية ، أو توصيلها بأنبوب ، أو إعادة توجيهها إلى ملف أو أمر آخر ، وفقًا لسطر الأوامر الذي أطلق الأمر.

تدفقات لينكس القياسية

في Linux ، يعد stdin هو تدفق الإدخال القياسي. هذا يقبل النص كمدخلاته. يتم تسليم إخراج النص من الأمر إلى الغلاف عبر تيار stdout (خرج قياسي). يتم إرسال رسائل الخطأ من الأمر من خلال تيار stderr (خطأ قياسي).

لذلك يمكنك أن ترى أن هناك نوعان من تدفقات الإخراج ، stdout و stderr ، ودفق إدخال واحد ، stdin . نظرًا لأن كل من رسائل الخطأ والمخرجات العادية لها قناة خاصة بها لنقلها إلى النافذة الطرفية ، فيمكن التعامل معها بشكل مستقل عن بعضها البعض.

يتم التعامل مع التدفقات مثل الملفات

يتم التعامل مع التدفقات في Linux - مثل أي شيء آخر تقريبًا - كما لو كانت ملفات. يمكنك قراءة نص من ملف ، ويمكنك كتابة نص في ملف. يتضمن كلا الإجراءين دفقًا من البيانات. لذا فإن مفهوم معالجة تدفق البيانات كملف ليس بهذا القدر من الامتداد.

الإعلانات

يتم تخصيص رقم فريد لكل ملف مرتبط بعملية ما للتعرف عليه. يُعرف هذا باسم واصف الملف. عندما يتطلب الأمر تنفيذ إجراء على ملف ، يتم استخدام واصف الملف لتعريف الملف.

يتم استخدام هذه القيم دائمًا لـ stdin و stdout, و stderr :

  • 0 : ستدين
  • 1 : stdout
  • 2 : ستدير

الرد على الأنابيب وعمليات إعادة التوجيه

لتسهيل تقديم شخص ما لموضوع ما ، فإن الأسلوب الشائع هو تعليم نسخة مبسطة من الموضوع. على سبيل المثال ، في القواعد ، يُقال لنا أن القاعدة هي "أنا قبل هـ ، إلا بعد ج". لكن في الواقع ، هناك استثناءات لهذه القاعدة أكثر من الحالات التي تخضع لها.

على نفس المنوال ، عند الحديث عن stdin ، و stdout ، و stderr ، فمن الملائم أن نخبأ البديهية المقبولة بأن العملية لا تعرف ولا تهتم بمكان إنهاء تياراتها القياسية الثلاثة. هل يجب أن تهتم العملية بما إذا كان إخراجها سينتقل إلى الجهاز أو يتم إعادة توجيهه إلى ملف؟ هل يمكنه حتى معرفة ما إذا كان الإدخال يأتي من لوحة المفاتيح أم أنه يتم إدخاله عبر الأنابيب من عملية أخرى؟

في الواقع ، تعرف العملية - أو على الأقل يمكنها اكتشاف ذلك ، إذا اختارت التحقق - ويمكنها تغيير سلوكها وفقًا لذلك إذا قرر مؤلف البرنامج إضافة هذه الوظيفة.

الإعلانات

يمكننا أن نرى هذا التغيير في السلوك بسهولة بالغة. جرب هذين الأمرين:

 ls 

 ls | قط 

يتصرف الأمر ls بشكل مختلف إذا كان يتم توجيه مخرجاته ( stdout ) إلى أمر آخر. إنه ls الذي يتحول إلى إخراج عمود واحد ، وليس تحويلاً يتم إجراؤه بواسطة cat . ويفعل ls نفس الشيء إذا تمت إعادة توجيه مخرجاته:

 ls> capture.txt 

 cat capture.txt 

إعادة توجيه stdout و stderr

هناك ميزة لوجود رسائل خطأ يتم تسليمها بواسطة دفق مخصص. هذا يعني أنه يمكننا إعادة توجيه إخراج الأمر ( stdout ) إلى ملف وما زلنا نرى أي رسائل خطأ ( stderr ) في نافذة المحطة الطرفية. يمكنك الرد على الأخطاء إذا احتجت إلى ذلك ، عند حدوثها. كما أنه يمنع رسائل الخطأ من تلويث الملف الذي تمت إعادة توجيه stdout إليه.

اكتب النص التالي في محرر واحفظه في ملف يسمى error.sh.

 #! / بن / باش

صدى "على وشك محاولة الوصول إلى ملف غير موجود"
اسم ملف غير صالح للقطط. xt

اجعل البرنامج النصي قابلاً للتنفيذ باستخدام هذا الأمر:

 chmod + x error.sh

السطر الأول من البرنامج النصي يردد النص إلى النافذة الطرفية ، عبر تيار stdout . يحاول السطر الثاني الوصول إلى ملف غير موجود. سيؤدي هذا إلى إنشاء رسالة خطأ يتم تسليمها عبر stderr .

قم بتشغيل البرنامج النصي باستخدام هذا الأمر:

 ./error.sh 

يمكننا أن نرى أن كلا من تدفقات الإخراج ، stdout و stderr ، قد تم عرضها في النوافذ الطرفية.

دعنا نحاول إعادة توجيه الإخراج إلى ملف:

 ./error.sh> capture.txt 

الإعلانات

لا يزال يتم إرسال رسالة الخطأ التي يتم تسليمها عبر stderr إلى نافذة المحطة الطرفية. يمكننا التحقق من محتويات الملف لمعرفة ما إذا كان إخراج stdout قد انتقل إلى الملف.

 cat capture.txt 

تم إعادة توجيه الإخراج من stdin إلى الملف كما هو متوقع.

يعمل رمز إعادة التوجيه > مع stdout افتراضيًا. يمكنك استخدام أحد واصفات الملفات الرقمية للإشارة إلى تدفق الإخراج القياسي الذي ترغب في إعادة توجيهه.

لإعادة توجيه stdout بشكل صريح ، استخدم تعليمات إعادة التوجيه هذه:

 1>

لإعادة توجيه stderr بشكل صريح ، استخدم تعليمات إعادة التوجيه هذه:

 2>

دعنا نحاول اختبارنا مرة أخرى ، وهذه المرة سنستخدم 2> :

 ./error.sh 2> capture.txt 

تتم إعادة توجيه رسالة الخطأ ويتم إرسال رسالة echo stdout إلى نافذة المحطة الطرفية:

دعونا نرى ما هو موجود في ملف Capture.txt.

 cat capture.txt 

الرسالة stderr في capture.txt كما هو متوقع.

إعادة توجيه كل من stdout و stderr

بالتأكيد ، إذا تمكنا من إعادة توجيه إما stdout أو stderr إلى ملف بشكل مستقل عن الآخر ، فهل يجب أن نكون قادرين على إعادة توجيههما معًا في نفس الوقت ، إلى ملفين مختلفين؟

الإعلانات

نعم نستطيع. سيوجه هذا الأمر stdout إلى ملف يسمى capture.txt و stderr إلى ملف يسمى error.txt.

 ./error.sh 1> capture.txt 2> error.txt 

نظرًا لإعادة توجيه كل من تدفقات الإخراج - الإخراج القياسي والخطأ القياسي - إلى الملفات ، فلا يوجد إخراج مرئي في النافذة الطرفية. يتم إرجاعنا إلى موجه سطر الأوامر كما لو لم يحدث شيء.

دعنا نتحقق من محتويات كل ملف:

 cat capture.txt
 cat error.txt 

إعادة توجيه stdout و stderr إلى نفس الملف

هذا رائع ، لدينا كل تدفقات الإخراج القياسية تذهب إلى ملفها المخصص. التركيبة الأخرى الوحيدة التي يمكننا القيام بها هي إرسال كل من stdout و stderr إلى نفس الملف.

يمكننا تحقيق ذلك بالأمر التالي:

 ./error.sh> capture.txt 2> & 1

دعونا نكسر ذلك.

  • ./error.sh : يقوم بتشغيل ملف البرنامج النصي error.sh.
  • > capture.txt : يعيد توجيه تيار stdout إلى ملف capture.txt. > هو اختصار لـ 1> .
  • 2> & 1 : يستخدم هذا الأمر &> تعليمات إعادة التوجيه. تسمح لك هذه التعليمات بإخبار الغلاف بأن يجعل أحد الدفقين قد وصل إلى نفس الوجهة مثل دفق آخر. في هذه الحالة ، نقول "إعادة توجيه الدفق 2 ، stderr ، إلى نفس الوجهة التي تتم إعادة توجيه الدفق 1 ، stdout ، إليها."

لا يوجد إخراج مرئي. هذا مشجع.

دعنا نتحقق من ملف capture.txt ونرى ما بداخله.

 cat capture.txt 

تم إعادة توجيه كل من تدفقات stdout و stderr إلى ملف وجهة واحد.

لإعادة توجيه إخراج الدفق وإلقائه بصمت بعيدًا ، قم بتوجيه الإخراج إلى /dev/null .

الكشف عن إعادة التوجيه داخل البرنامج النصي

ناقشنا كيف يمكن للأمر اكتشاف ما إذا كان قد تمت إعادة توجيه أي من التدفقات ، ويمكنه اختيار تغيير سلوكه وفقًا لذلك. هل يمكننا تحقيق ذلك في نصوصنا الخاصة؟ نعم نستطيع. وهي تقنية سهلة الفهم والتوظيف.

الإعلانات

اكتب النص التالي في محرر واحفظه كمدخل.

 #! / بن / باش

إذا [-t 0] ؛ ومن بعد

  صدى stdin القادمة من لوحة المفاتيح
 
آخر

  صدى ستدين قادم من أنبوب أو ملف
 
فاي

استخدم الأمر التالي لجعله قابلاً للتنفيذ:

 chmod + x input.sh

الجزء الذكي هو الاختبار داخل الأقواس المربعة. يعيد الخيار -t (طرفي) صحيحًا (0) إذا انتهى الملف المرتبط بواصف الملف في نافذة المحطة الطرفية. لقد استخدمنا واصف الملف 0 كوسيطة للاختبار ، والذي يمثل stdin .

إذا كان stdin متصلاً بنافذة طرفية ، فسيكون الاختبار صحيحًا. إذا كان stdin متصلاً بملف أو أنبوب ، فسيفشل الاختبار.

يمكننا استخدام أي ملف نصي مناسب لإنشاء مدخلات إلى البرنامج النصي. نحن هنا نستخدم ملفًا يسمى dummy.txt.

 ./input.sh <dummy.txt 

يوضح الإخراج أن البرنامج النصي يتعرف على أن الإدخال لا يأتي من لوحة المفاتيح ، بل يأتي من ملف. إذا اخترت ذلك ، فيمكنك تغيير سلوك النص وفقًا لذلك.

الإعلانات

كان ذلك مع إعادة توجيه الملف ، فلنجربه باستخدام أنبوب.

 القط dummy.txt | ./input.sh 

يتعرف البرنامج النصي على أن مدخلاته يتم ضخها فيه. أو بتعبير أدق ، يتعرف مرة أخرى على أن تيار stdin غير متصل بنافذة طرفية.

لنقم بتشغيل البرنامج النصي بدون أنابيب أو عمليات إعادة توجيه.

 ./input.sh 

يتم توصيل دفق stdin بالنافذة الطرفية ، ويبلغ البرنامج النصي عن ذلك وفقًا لذلك.

للتحقق من نفس الشيء مع تدفق الإخراج ، نحتاج إلى نص برمجي جديد. اكتب ما يلي في محرر واحفظه باسم output.sh.

 #! / بن / باش

إذا [-t 1] ؛ ومن بعد

صدى stdout يذهب إلى النافذة الطرفية
 
آخر

إعادة توجيه stdout أو إعادة توجيه الأنابيب
 
فاي

استخدم الأمر التالي لجعله قابلاً للتنفيذ:

 chmod + x input.sh

التغيير الوحيد المهم في هذا النص هو في الاختبار بين قوسين معقوفين. نستخدم الرقم 1 لتمثيل واصف ملف stdout .

لنجربها. سنقوم بتوجيه الإخراج من خلال cat .

 ./output | قط 

الإعلانات

يتعرف البرنامج النصي على أن مخرجاته لن تذهب مباشرة إلى نافذة طرفية.

يمكننا أيضًا اختبار البرنامج النصي عن طريق إعادة توجيه الإخراج إلى ملف.

 ./output.sh> capture.txt 

لا يوجد إخراج للنافذة الطرفية ، يتم إرجاعنا بصمت إلى موجه الأوامر. كما كنا نتوقع.

يمكننا النظر داخل ملف capture.txt لمعرفة ما تم التقاطه. استخدم الأمر التالي للقيام بذلك.

 التقاط القط 

مرة أخرى ، يكتشف الاختبار البسيط في البرنامج النصي الخاص بنا أن تيار stdout لا يتم إرساله مباشرة إلى نافذة طرفية.

الإعلانات

إذا قمنا بتشغيل البرنامج النصي بدون أي أنابيب أو عمليات إعادة توجيه ، فيجب أن يكتشف أن stdout يتم تسليمه مباشرة إلى نافذة المحطة الطرفية.

 ./output.sh 

وهذا بالضبط ما نراه.

تيارات الوعي

تتيح لك معرفة كيفية معرفة ما إذا كانت البرامج النصية الخاصة بك متصلة بالنافذة الطرفية ، أو الأنبوب ، أو يتم إعادة توجيهها ، ضبط سلوكها وفقًا لذلك.

يمكن أن تكون مخرجات التسجيل والتشخيص أكثر أو أقل تفصيلاً ، اعتمادًا على ما إذا كان سيتم الانتقال إلى الشاشة أو إلى ملف. يمكن تسجيل رسائل الخطأ في ملف مختلف عن إخراج البرنامج العادي.

كما هو الحال عادة ، فإن المزيد من المعرفة يجلب المزيد من الخيارات.

ذات صلة: أفضل أجهزة كمبيوتر Linux المحمولة للمطورين والمتحمسين