التدفقات القياسية
في برمجة الكمبيوتر ، تكون التدفقات القياسية قنوات اتصال إدخال وإخراج متصلة مسبقًا [1] بين برنامج الكمبيوتر وبيئته عندما يبدأ التنفيذ. تسمى اتصالات الإدخال/الإخراج الثلاثة الإدخال القياسي ( stdin ) والإخراج القياسي ( stdout ) والخطأ القياسي ( stderr ). في الأصل، حدث الإدخال/الإخراج عبر وحدة تحكم نظام متصلة فعليًا (الإدخال عبر لوحة المفاتيح والإخراج عبر الشاشة)، لكن التدفقات القياسية تلخص هذا. عندما يتم تنفيذ أمر عبر غلاف تفاعلي ، تكون التدفقات عادةً متصلة بمحطة النص التي يعمل عليها الغلاف، ولكن يمكن تغييرها بإعادة التوجيه أو خط أنابيب . بشكل عام، ترث العملية الفرعية التدفقات القياسية لعملية الأصل الخاصة بها .
طلب

يعرف المستخدمون عمومًا التدفقات القياسية كقنوات إدخال وإخراج تتعامل مع البيانات القادمة من جهاز إدخال، أو تكتب البيانات من التطبيق. قد تكون البيانات نصًا بأي ترميز، أو بيانات ثنائية . عندما يتم تشغيل برنامج كخادم ، يتم إعادة توجيه تدفق الخطأ القياسي الخاص به إلى ملف سجل، عادةً لأغراض تحليل الأخطاء.
يمكن استخدام التدفقات لتسلسل التطبيقات، مما يعني أنه يمكن إعادة توجيه تدفق الإخراج لبرنامج واحد ليكون تدفق الإدخال لتطبيق آخر. في العديد من أنظمة التشغيل، يتم التعبير عن ذلك من خلال سرد أسماء التطبيقات، مفصولة بحرف الشريط العمودي، ولهذا السبب غالبًا ما يُطلق عليه حرف خط الأنابيب . ومن الأمثلة المعروفة استخدام تطبيق الترقيم ، مثل more ، مما يوفر للمستخدم التحكم في عرض تدفق الإخراج على الشاشة.
خلفية
في أغلب أنظمة التشغيل التي سبقت يونكس ، كان لزامًا على البرامج أن تتصل صراحةً بأجهزة الإدخال والإخراج المناسبة. وكانت التعقيدات الخاصة بنظام التشغيل سببًا في جعل هذه المهمة البرمجية شاقة. ففي العديد من الأنظمة، كان من الضروري الحصول على التحكم في إعدادات البيئة، والوصول إلى جدول ملفات محلي، وتحديد مجموعة البيانات المقصودة، والتعامل مع الأجهزة بشكل صحيح في حالة قارئ البطاقات المثقبة ، أو محرك الشريط المغناطيسي ، أو محرك الأقراص ، أو الطابعة الخطية ، أو المثقبة بالبطاقات، أو المحطة الطرفية التفاعلية.
كان أحد التطورات العديدة الرائدة التي حققها يونكس هو الأجهزة المجردة ، والتي ألغت الحاجة إلى معرفة البرنامج أو الاهتمام بنوع الأجهزة التي كان يتواصل معها [ بحاجة لمصدر ] . فرضت أنظمة التشغيل القديمة على المبرمج بنية تسجيل ودلالات بيانات غير متعامدة في كثير من الأحيان والتحكم في الجهاز. أزال يونكس هذا التعقيد بمفهوم دفق البيانات: تسلسل منظم من بايتات البيانات التي يمكن قراءتها حتى نهاية الملف . قد يكتب البرنامج أيضًا بايتات حسب الرغبة ولا يحتاج إلى ذلك، ولا يمكنه بسهولة إعلان عددها أو تجميعها.
كان أحد الاختراقات التي حققتها يونكس هو ربط الإدخال والإخراج تلقائيًا بلوحة المفاتيح الطرفية وشاشة الطرفية، على التوالي، افتراضيًا [ بحاجة لمصدر ] - لم يفعل البرنامج (والمبرمج) أي شيء على الإطلاق لإنشاء الإدخال والإخراج لبرنامج إدخال-عملية-إخراج نموذجي (ما لم يختار نموذجًا مختلفًا). على النقيض من ذلك، كانت أنظمة التشغيل السابقة تتطلب عادةً بعض لغات التحكم في الوظائف - المعقدة غالبًا - لإنشاء الاتصالات، أو كان يجب أن يقوم البرنامج بتنسيق العبء المكافئ. [ بحاجة لمصدر ]
نظرًا لأن يونكس يوفر تدفقات قياسية، فقد كانت بيئة تشغيل يونكس سي ملزمة بدعمها أيضًا. ونتيجة لذلك، توفر معظم بيئات تشغيل سي (والبيئات التي تنحدر من سي )، بغض النظر عن نظام التشغيل، وظائف مكافئة.
المدخل القياسي (stdin)
الإدخال القياسي هو دفق يقرأ منه البرنامج بيانات الإدخال الخاصة به. يطلب البرنامج نقل البيانات باستخدام عملية القراءة . لا تتطلب جميع البرامج إدخال دفق. على سبيل المثال، قد تأخذ برامج dir و ls (التي تعرض أسماء الملفات الموجودة في دليل) وسيطات سطر الأوامر ، لكنها تؤدي عملياتها دون إدخال أي دفق بيانات.
ما لم تتم إعادة التوجيه ، يتم توريث الإدخال القياسي من العملية الأصلية. في حالة وجود غلاف تفاعلي، يرتبط هذا عادةً بجهاز الإدخال الخاص بالطرفية (أو الطرفية الزائفة ) والذي يرتبط في النهاية بلوحة مفاتيح المستخدم .
في أنظمة POSIX ، يكون موصوف الملف للإدخال القياسي هو 0 (صفر)؛ وتعريف POSIX <unistd.h> هو STDIN_FILENO؛ <stdio.h>ويتم توفير التجريد C المقابل عبر FILE* stdinالمتغير العالمي. وعلى نحو مماثل، يوفر المتغير العالمي C++ std::cinمن النوع <iostream>تجريدًا عبر تدفقات C++ . وتوجد تجريدات مماثلة في مكتبات الإدخال/الإخراج القياسية لكل لغة برمجة تقريبًا .
الإخراج القياسي (stdout)
الإخراج القياسي هو دفق يكتب فيه البرنامج بيانات الإخراج الخاصة به. يطلب البرنامج نقل البيانات مع عملية الكتابة . لا تقوم جميع البرامج بإنشاء إخراج. على سبيل المثال، أمر إعادة تسمية الملف (يُطلق عليه بشكل مختلف mv أو move أو ren ) صامت في حالة النجاح.
ما لم تتم إعادة التوجيه ، يتم توريث الإخراج القياسي من العملية الأصلية. في حالة وجود غلاف تفاعلي، يكون هذا عادةً هو المحطة النصية التي بدأت البرنامج.
الوصف الملفي للإخراج القياسي هو 1 (واحد)؛ تعريف POSIX <unistd.h> هو STDOUT_FILENO؛ المتغير C المقابل <stdio.h>هو FILE* stdout؛ وبالمثل، المتغير C++ <iostream>هو std::cout.
الخطأ المعياري (stderr)
الخطأ القياسي هو دفق إخراج آخر يستخدمه عادةً البرامج لإخراج رسائل الخطأ أو التشخيصات. وهو دفق مستقل عن الإخراج القياسي ويمكن إعادة توجيهه بشكل منفصل.
يحل هذا مشكلة شبه المسند ، مما يسمح بتمييز الناتج والأخطاء، وهو مشابه لدالة تعيد زوجًا من القيم - انظر مشكلة شبه المسند § إرجاع متعدد القيم . الوجهة المعتادة هي محطة النص التي بدأت البرنامج لتوفير أفضل فرصة للرؤية حتى إذا تم إعادة توجيه الناتج القياسي (لذا لا يمكن ملاحظته بسهولة). على سبيل المثال، يتم إعادة توجيه ناتج برنامج في خط أنابيب إلى إدخال البرنامج التالي أو ملف نصي، ولكن الأخطاء من كل برنامج لا تزال تذهب مباشرة إلى محطة النص حتى يتمكن المستخدم من مراجعتها في الوقت الفعلي. [2]
من المقبول والطبيعي توجيه الإخراج القياسي والخطأ القياسي إلى نفس الوجهة، مثل محطة النص. تظهر الرسائل بنفس الترتيب الذي يكتبها به البرنامج، ما لم يكن هناك تخزين مؤقت . على سبيل المثال، في المواقف الشائعة، لا يتم تخزين دفق الخطأ القياسي مؤقتًا ولكن يتم تخزين دفق الإخراج القياسي مؤقتًا؛ في هذه الحالة، قد يظهر النص المكتوب إلى الخطأ القياسي لاحقًا على المحطة في وقت سابق، إذا لم يكن مخزن دفق الإخراج القياسي ممتلئًا بعد.
يتم تعريف موصوف الملف للخطأ المعياري بواسطة POSIX على أنه 2 (اثنان)؛ يوفر ملف الرأس <unistd.h> الرمز STDERR_FILENO؛ [3] المتغير C المقابل <stdio.h>هو FILE* stderr. يوفر رأس C++ <iostream>القياسي متغيرين مرتبطين بهذا الدفق: std::cerrو std::clog، حيث يكون الأول غير مخزن مؤقتًا ويستخدم الأخير نفس آلية التخزين المؤقت مثل جميع دفقات C++ الأخرى.
تسمح قذائف نمط بورن بإعادة توجيه الخطأ القياسي إلى نفس الوجهة التي يتم توجيه الإخراج القياسي إليها باستخدام
2>&1
تسمح أصداف نمط csh بإعادة توجيه الخطأ القياسي إلى نفس الوجهة التي يتم توجيه الإخراج القياسي إليها باستخدام
>&
تمت إضافة الخطأ المعياري إلى يونكس في سبعينيات القرن العشرين بعد أن انتهت عدة عمليات طباعة ضوئية ضائعة برسائل خطأ تم كتابتها بدلاً من عرضها على محطة المستخدم. [4]
الخط الزمني
خمسينيات القرن العشرين: فورتران
يحتوي Fortran على ما يعادل موصوفات الملفات في Unix: وفقًا للاتفاقية، تستخدم العديد من تطبيقات Fortran أرقام الوحدات UNIT=5لـ stdin و UNIT=6stdout و UNIT=0stderr. في Fortran-2003، ISO_FORTRAN_ENVتم توحيد الوحدة النمطية الجوهرية لتشمل الثوابت المسماة INPUT_UNITو OUTPUT_UNITو ERROR_UNITلتحديد أرقام الوحدات بشكل قابل للنقل.
! FORTRAN 77 مثال
البرنامج الرئيسي عدد صحيح قراءة ( الوحدة = 5 ، * ) كتابة الرقم ( الوحدة = 6 ، '(A,I3)' ) ' الرقم هو: ' ، نهاية الرقم
! برنامج مثال Fortran 2003 الاستخدام الرئيسي
iso_fortran_env implicit none integer :: number read ( unit = INPUT_UNIT , * ) number write ( unit = OUTPUT_UNIT , '(a,i3)' ) 'Number is: ' , number end program
1960: ألجول 60
تم انتقاد ALGOL 60 لعدم وجود وصول قياسي للملفات. [ بحاجة لمصدر ]
1968: ألجول 68
تمت الإشارة إلى مرافق الإدخال والإخراج في ALGOL 68 بشكل جماعي باسم transput. [5] قام كوستر بتنسيق تعريف معيار transput . تضمن النموذج ثلاث قنوات قياسية: stand inو stand outو و stand back.
# مثال على ALGOL 68 #
رئيسي:(
رقم حقيقي؛
getf(الوقوف في، ($g$، رقم));
printf(($"الرقم هو: "g(6,4)"أو "$,number)); # أو #
putf(تبرز،($" الرقم هو: "g(6,4)"!"$,number));
سطر جديد (يبرز)
)
| |
| مدخل: | الإخراج: |
|---|---|
3.14159 |
الرقم هو: +3.142 أو الرقم هو: +3.142! |
سبعينيات القرن العشرين: لغة C وUnix
في لغة البرمجة C ، يتم ربط تدفقات الإدخال والإخراج والخطأ القياسية بموصفات الملفات الموجودة في يونكس 0 و1 و2 على التوالي. [6] في بيئة POSIX ، يجب استخدام تعريفات < unistd.h > STDIN_FILENO أو STDOUT_FILENO أو STDERR_FILENO بدلاً من الأرقام السحرية . يتم أيضًا توفير مؤشرات الملفات stdin و stdout و stderr .
قام كين تومسون (مصمم ومنفذ نظام التشغيل يونكس الأصلي) بتعديل الفرز في الإصدار 5 من يونكس لقبول "-" كمدخل قياسي، والذي انتشر إلى أدوات مساعدة أخرى وأصبح جزءًا من نظام التشغيل كملف خاص في الإصدار 8. كانت التشخيصات جزءًا من الإخراج القياسي حتى الإصدار 6 ، وبعد ذلك ابتكر دينيس إم ريتشي مفهوم الخطأ القياسي. [7]
1995: جافا
في Java ، تتم الإشارة إلى التدفقات القياسية بواسطة System.in(بالنسبة لـ stdin)، و System.out(بالنسبة لـ stdout)، و System.err(بالنسبة لـ stderr). [8]
public static void main ( String args [] ) { try { BufferedReader br = new BufferedReader ( new InputStreamReader ( System.in ) ) ; String s = br.readLine ( ) ; double number = Double.parseDouble ( s ) ; System.out.println ( " الرقم هو : " + number ) ; } catch ( استثناء e ) { System.err.println ( " خطأ : " + e.getMessage ( ) ) ; } }
2000: .NET
في لغة C# ولغات .NET الأخرى ، تتم الإشارة إلى التدفقات القياسية بواسطة System.Console.In(بالنسبة لـ stdin) و System.Console.Out(بالنسبة لـ stdout) و System.Console.Error(بالنسبة لـ stderr). [9] يمكن أيضًا الوصول إلى إمكانيات القراءة والكتابة الأساسية لتدفقات stdin وstdout مباشرةً من خلال الفئة System.Console(على سبيل المثال، System.Console.WriteLine()يمكن استخدامها بدلاً من System.Console.Out.WriteLine()).
System.Console.In، System.Console.Outو System.Console.Errorهي كائنات System.IO.TextReader(stdin) و System.IO.TextWriter(stdout, stderr)، والتي تسمح فقط بالوصول إلى التدفقات القياسية الأساسية على أساس نصي. يجب تنفيذ الوصول الثنائي الكامل إلى التدفقات القياسية من خلال System.IO.Streamالكائنات التي تم إرجاعها بواسطة System.Console.OpenStandardInput()، System.Console.OpenStandardOutput()و System.Console.OpenStandardError()على التوالي.
// مثال C#
public static int Main ( string [ ] args ) { try { string s = System.Console.In.ReadLine ( ) ; double number = double.Parse ( s ) ; System.Console.Out.WriteLine ( " Number is : { 0 : F3 } " , number ) ; return 0 ;
// إذا ألقى Parse ( ) استثناءً } catch ( ArgumentNullException ) { System.Console.Error.WriteLine ( " لم يتم إدخال أي رقم!" ) ; } catch ( FormatException ) { System.Console.Error.WriteLine ( " القيمة المحددة ليست رقمًا صالحًا! " ) ; } catch ( OverflowException ) { System.Console.Error.WriteLine ( " الرقم المحدد كبير جدًا ! " ) ; }
العودة - 1 ؛
'مثال على Visual Basic .NET
دالة عامة Main ( ) كعدد صحيح جرب Dim s كسلسلة = System.Console . [ In ] .ReadLine ( ) Dim number كـ Double = Double.Parse ( s ) System.Console.Out.WriteLine ( " Number is : { 0 : F3 } " , number ) إرجاع 0
'إذا ألقى Parse() استثناءً
Catch ex As System . ArgumentNullException System . Console . [ Error ] . WriteLine ( "لم يتم إدخال أي رقم!" ) Catch ex2 As System . FormatException System . Console . [ Error ] . WriteLine ( "القيمة المحددة ليست رقمًا صالحًا!" ) Catch ex3 As System . OverflowException System . Console . [ Error ] . WriteLine ( "الرقم المحدد كبير جدًا!" ) End Try
العودة - 1 نهاية الدالة
عند تطبيق System.Diagnostics.Process الفصل، يمكنك استخدام خصائص StandardInput المثيل و StandardOutputو StandardErrorلتلك الفصل للوصول إلى التدفقات القياسية للعملية.
2000 - : بايثون (2 أو 3)
يوضح المثال التالي، المكتوب بلغة Python ، كيفية إعادة توجيه الإدخال القياسي إلى الإخراج القياسي وإلى ملف نصي.
#!/usr/bin/env بايثون
استيراد النظام
# احفظ stdout الحالي حتى نتمكن من التراجع عن sys.stdout
# بعد أن نكمل إعادة التوجيه
ملف stdin_no = sys .stdin
stdout_fileno = sys .stdout
# إعادة توجيه sys.stdout إلى الملف
sys.stdout = open ( " myfile.txt" , "w " )
نقرة = 0
بالنسبة إلى inps في stdin_fileno :
ctrs = str ( ctr )
# الطباعة إلى stdout المعاد توجيهه ()
sys.stdout.write ( ctrs + " ) هذا هو المسار المعاد توجيهه ---> " + inps + " \ n " )
# الطباعة على معالج stdout المحفوظ فعليًا
stdout_fileno.write ( ctrs + ") هذا هو إلى --- > " + inps + " \n " ) الفعلي
كتر = كتر + 1
# اغلاق الملف
sys .stdout .close ( )
# استعادة sys.stdout إلى معالج الملف المحفوظ القديم لدينا
sys .stdout = stdout_fileno
واجهات المستخدم الرسومية
لا تستخدم واجهات المستخدم الرسومية (GUIs) دائمًا التدفقات القياسية؛ فهي تفعل ذلك عندما تكون واجهات المستخدم الرسومية عبارة عن غلافات للبرامج النصية الأساسية و/أو برامج وحدة التحكم، على سبيل المثال واجهة المستخدم الرسومية لمدير الحزم Synaptic ، والتي تغلف أوامر apt في Debian و/أو Ubuntu. تستخدم واجهات المستخدم الرسومية التي تم إنشاؤها باستخدام أدوات البرمجة النصية مثل Zenity وKDialog بواسطة مشروع KDE [10] stdin وstdout وstderr، وتستند إلى نصوص برمجية بسيطة بدلاً من واجهة مستخدم رسومية كاملة مبرمجة ومجمعة في C/C++ باستخدام Qt أو GTK أو إطار عمل آخر مكافئ للأدوات الذكية.
قائمة الخدمات ، كما تم تنفيذها في NeXTSTEP و Mac OS X ، تشبه أيضًا التدفقات القياسية. في أنظمة التشغيل هذه، يمكن للتطبيقات الرسومية توفير الوظائف من خلال قائمة على مستوى النظام تعمل على التحديد الحالي في واجهة المستخدم الرسومية، بغض النظر عن التطبيق.
لا تزال بعض برامج واجهة المستخدم الرسومية، وخاصة تلك الموجودة على يونكس، تكتب معلومات التصحيح إلى الخطأ القياسي. وقد تقرأ برامج أخرى (مثل العديد من مشغلات الوسائط في يونكس) الملفات من الإدخال القياسي. ومن بين برامج Windows الشائعة التي تفتح نافذة وحدة تحكم منفصلة بالإضافة إلى نوافذ واجهة المستخدم الرسومية الخاصة بها برامج المحاكاة pSX و DOSBox .
يمكن لخادم GTK استخدام stdin كواجهة اتصال مع برنامج مفسر لتحقيق واجهة مستخدم رسومية.
يقدم نموذج Common Lisp Interface Manager عناصر واجهة المستخدم الرسومية المرسلة إلى مجرى إخراج ممتد.
انظر أيضا
- إعادة التوجيه (الحوسبة)
- تيار (الحوسبة)
- الإدخال/الإخراج
- إدخال/إخراج ملف C
- SYSIN و SYSOUT
- التدفقات القياسية في نظام الملفات Files-11
مراجع
- ^ DM Ritchie، "نظام إدخال وإخراج التيار"، مجلة AT&T Bell Laboratories Technical Journal، 68(8)، أكتوبر 1984.
- ^ "ما هي stdin وstdout وstderr في Linux؟ | CodePre.com". 2 ديسمبر 2021. تم الاسترجاع في 8 أبريل 2022 .
- ^ "<unistd.h>". مواصفات قاعدة المجموعة المفتوحة، العدد 6—IEEE Std 1003.1، إصدار 2004. المجموعة المفتوحة. 2004.
- ^ جونسون، ستيف (2013-12-11). "[TUHS] Graphic Systems C/A/T phototypesetter" (قائمة بريدية). مؤرشف من الأصل في 2020-09-25 . تم الاسترجاع في 2020-11-07 .
- ^ “تقرير منقح عن اللغة الخوارزمية Algol 68”، تم تحريره بواسطة A. van Wijngaarden، BJ Mailloux، JEL Peck، CHA Koster، M. Sintzoff، CH Lindsey، LGLT Meertens and RG Fisker، القسم 10.3.
- ^ "Stdin(3): Standard I/O streams - Linux man page". die.net . مؤرشف من الأصل في 8 يونيو 2023.
- ^ McIlroy, MD (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (تقرير فني). CSTR. Bell Labs. 139. مؤرشف (PDF) من الأصل في 15 ديسمبر 2023.
- ^ "النظام (Java Platform SE 7)". مركز مساعدة Oracle . تم الاسترجاع في 20 يوليو 2012 .
- ^ ".NET Framework 4.7.1, mscorlib, console.cs". مصدر مرجعي - Microsoft . مؤرشف من الأصل في 10 ديسمبر 2017 . تم الاسترجاع في 2017-12-10 .
- ^ Kißling, Kristian (2009). "إضافة عناصر رسومية إلى البرامج النصية الخاصة بك باستخدام Zenity وKDialog". مجلة Linux . تم الاسترجاع في 11 أبريل 2021 .
مصادر
- "المجاري القياسية"، مكتبة GNU C
- دليل مرجعي لـ KRONOS 2.1 ، شركة Control Data Corporation، رقم القطعة 60407000، 1974
- إصدار NOS 1 من تطبيقات المبرمج الفوري ، شركة Control Data Corporation، رقم القطعة 60436000، 1978
- المستوى 68 مقدمة في البرمجة على MULTICS محفوظ في 2021-02-25 على موقع Wayback Machine ، شركة Honeywell Corporation، 1981
- تطور نظام التشغيل MVS، شركة IBM، 1981
- تعليق ليونز على الطبعة السادسة من يونكس ، جون ليونز، ISBN 1-57398-013-7 ، 1977
- فئة وحدة التحكم، مكتبة فئة .NET Framework، شركة Microsoft Corporation، 2008
روابط خارجية
- تعريف الإدخال القياسي - بواسطة مشروع معلومات Linux
- تعريف الإخراج القياسي - بواسطة مشروع معلومات Linux
- تعريف الخطأ المعياري - بواسطة مشروع معلومات لينكس
