ما المقصود بـ stdin و stdout و stderr على Linux؟
stdin
، stdout
و ، stderr
وهي ثلاثة تدفقات بيانات تم إنشاؤها عند تشغيل أمر Linux. يمكنك استخدامها لمعرفة ما إذا كان يتم توجيه البرامج النصية الخاصة بك أو إعادة توجيهها. نوضح لك كيف.
تيارات الانضمام إلى نقطتين
بمجرد البدء في تعلم عن لينكس ويونكس مثل أنظمة التشغيل، فسوف تأتي عبر شروط stdin
، stdout
و stederr
. هذه هي ثلاثة تدفقات قياسية يتم إنشاؤها عند تنفيذ أمر Linux. في الحوسبة ، الدفق هو شيء يمكنه نقل البيانات. في حالة هذه التدفقات ، تكون هذه البيانات نصية.
تيارات البيانات ، مثل تيارات المياه ، لها طرفان. لديهم مصدر وتدفق خارجي. أيًا كان أمر Linux الذي تستخدمه يوفر نهاية واحدة لكل دفق. يتم تحديد الطرف الآخر بواسطة القذيفة التي أطلقت الأمر. سيتم توصيل هذه النهاية بالنافذة الطرفية ، أو توصيلها بأنبوب ، أو إعادة توجيهها إلى ملف أو أمر آخر ، وفقًا لسطر الأوامر الذي أطلق الأمر.
تدفقات Linux القياسية
في Linux ، stdin
هو تدفق الإدخال القياسي. هذا يقبل النص كمدخلاته. يتم تسليم إخراج النص من الأمر إلى الغلاف عبر stdout
الدفق (خرج قياسي). يتم إرسال رسائل الخطأ من الأمر عبر stderr
التدفق (خطأ قياسي).
لذلك يمكنك أن ترى أن هناك تيارين الإخراج، stdout
و stderr
، وتيار مدخل واحد، stdin
. نظرًا لأن كل من رسائل الخطأ والمخرجات العادية لها قناة خاصة بها لنقلها إلى النافذة الطرفية ، فيمكن التعامل معها بشكل مستقل عن بعضها البعض.
يتم التعامل مع التدفقات مثل الملفات
يتم التعامل مع التدفقات في Linux - مثل أي شيء آخر تقريبًا - كما لو كانت ملفات. يمكنك قراءة نص من ملف ، ويمكنك كتابة نص في ملف. يتضمن كلا الإجراءين دفقًا من البيانات. لذا فإن مفهوم التعامل مع تدفق البيانات كملف ليس بهذا القدر من الامتداد.
يتم تخصيص رقم فريد لكل ملف مرتبط بعملية ما لتحديده. يُعرف هذا باسم واصف الملف. عندما يتطلب الأمر تنفيذ إجراء على ملف ، يتم استخدام واصف الملف لتعريف الملف.
وتستخدم هذه القيم دائما stdin
، stdout,
و stderr
:
- 0 : ستدين
- 1 : stdout
- 2 : ستدير
الرد على الأنابيب وعمليات إعادة التوجيه
لتسهيل تقديم شخص ما لموضوع ما ، فإن الأسلوب الشائع هو تعليم نسخة مبسطة من الموضوع. على سبيل المثال ، في القواعد النحوية ، يُقال لنا أن القاعدة هي "I قبل E ، إلا بعد C." لكن في الواقع ، هناك استثناءات لهذه القاعدة أكثر من الحالات التي تخضع لها.
وفي سياق مماثل، عندما نتحدث عن stdin
، stdout
و stderr
أنها مريحة لقدم إقتراحا البديهية المقبولة أن عملية لا يعرف ولا يكترث حيث يتم إنهاء ثلاثة تيارات القياسية. هل يجب أن تهتم العملية بما إذا كان إخراجها سينتقل إلى الجهاز أو يتم إعادة توجيهه إلى ملف؟ هل يمكنه حتى معرفة ما إذا كان الإدخال يأتي من لوحة المفاتيح أم أنه يتم إدخاله من عملية أخرى؟
في الواقع ، تعرف العملية - أو على الأقل يمكنها اكتشاف ذلك ، إذا اختارت التحقق - ويمكنها تغيير سلوكها وفقًا لذلك إذا قرر مؤلف البرنامج إضافة هذه الوظيفة.
يمكننا أن نرى هذا التغيير في السلوك بسهولة بالغة. جرب هذين الأمرين:
ls
ls | قط
و ls
سلوك القيادة بشكل مختلف إذا انتاجها ( stdout
) ويتم ضخها إلى أمر آخر. إنه ls
ينتقل إلى إخراج عمود واحد ، ولا يتم إجراء تحويل بواسطة cat
. و ls
يفعل الشيء نفسه إذا كان يتم إعادة توجيه انتاجها:
ls> capture.txt
cat capture.txt
إعادة توجيه stdout و stderr
هناك ميزة لوجود رسائل خطأ يتم تسليمها بواسطة دفق مخصص. هذا يعني أنه يمكننا إعادة توجيه إخراج الأمر ( stdout
) إلى ملف وما زلنا نرى أي رسائل خطأ ( stderr
) في نافذة المحطة الطرفية. يمكنك الرد على الأخطاء إذا احتجت إلى ذلك ، عند حدوثها. كما أنه يمنع رسائل الخطأ من تلويث الملف الذي stdout
تمت إعادة التوجيه إليه.
اكتب النص التالي في محرر واحفظه في ملف يسمى error.sh.
#! / bin / bash echo "على وشك محاولة الوصول إلى ملف غير موجود" cat bad-filename.txt
اجعل البرنامج النصي قابلاً للتنفيذ باستخدام هذا الأمر:
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
يتم إعادة توجيه رسالة الخطأ stdout
echo
ويتم إرسال الرسالة إلى نافذة المحطة الطرفية:
دعونا نرى ما هو موجود في ملف 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
إلى نفس الوجهة التيstdout
تتم إعادة توجيه الدفق 1 إليها"
لا يوجد مخرج مرئي. هذا مشجع.
دعنا نتحقق من ملف capture.txt ونرى ما بداخله.
cat capture.txt
تم إعادة توجيه كل من التدفقات stdout
و stderr
إلى ملف وجهة واحد.
لإعادة توجيه إخراج الدفق وإلقائه بصمت ، قم بتوجيه الإخراج إلى /dev/null
.
الكشف عن إعادة التوجيه داخل البرنامج النصي
ناقشنا كيف يمكن للأمر اكتشاف ما إذا كان قد تم إعادة توجيه أي من التدفقات ، ويمكنه اختيار تغيير سلوكه وفقًا لذلك. هل يمكننا تحقيق ذلك في نصوصنا الخاصة؟ نعم نستطيع. وهي تقنية سهلة الفهم والتوظيف.
اكتب النص التالي في محرر واحفظه كمدخل.
#! / bin / bash if [-t 0] ؛ ثم صدى stdin القادمة من لوحة المفاتيح آخر صدى stdin قادمة من أنبوب أو ملف fi
استخدم الأمر التالي لجعله قابلاً للتنفيذ:
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.
#! / bin / bash if [-t 1] ؛ ثم echo stdout يذهب إلى النافذة الطرفية وإلا يتم إعادة توجيه echo stdout أو توجيهه عبر الأنابيب
استخدم الأمر التالي لجعله قابلاً للتنفيذ:
chmod + x input.sh
التغيير الوحيد المهم لهذا النص هو في الاختبار بين القوسين المعقوفين. نستخدم الرقم 1 لتمثيل واصف الملف لـ stdout
.
دعونا نجربها. سنقوم بتوجيه الإخراج cat
.
./output | قط
يتعرف البرنامج النصي على أن مخرجاته لن تذهب مباشرة إلى نافذة طرفية.
يمكننا أيضًا اختبار البرنامج النصي عن طريق إعادة توجيه الإخراج إلى ملف.
./output.sh> capture.txt
لا يوجد إخراج للنافذة الطرفية ، يتم إرجاعنا بصمت إلى موجه الأوامر. كما كنا نتوقع.
يمكننا النظر داخل ملف Capture.txt لمعرفة ما تم التقاطه. استخدم الأمر التالي للقيام بذلك.
التقاط القط
مرة أخرى ، يكتشف الاختبار البسيط في البرنامج النصي أن stdout
الدفق لا يتم إرساله مباشرة إلى نافذة طرفية.
إذا قمنا بتشغيل البرنامج النصي بدون أي أنابيب أو إعادة توجيه ، فيجب أن يكتشف أنه stdout
يتم تسليمه مباشرة إلى نافذة المحطة الطرفية.
./output.sh
وهذا بالضبط ما نراه.
تيارات الوعي
تتيح لك معرفة كيفية معرفة ما إذا كانت البرامج النصية الخاصة بك متصلة بالنافذة الطرفية ، أو الأنبوب ، أو يتم إعادة توجيهها ، ضبط سلوكها وفقًا لذلك.
يمكن أن تكون مخرجات التسجيل والتشخيص أكثر أو أقل تفصيلاً ، اعتمادًا على ما إذا كان سينتقل إلى الشاشة أو إلى ملف. يمكن تسجيل رسائل الخطأ في ملف مختلف عن إخراج البرنامج العادي.
كما هو الحال عادة ، تجلب المعرفة المزيد من الخيارات.