stringtranslate.com

Стандартные потоки

В программировании компьютеров стандартные потоки — это предварительно подключенные каналы ввода и вывода [1] между компьютерной программой и ее средой, когда она начинает выполняться. Три соединения ввода/вывода (I/O) называются стандартным вводом ( stdin ), стандартным выводом ( stdout ) и стандартной ошибкой ( stderr ). Первоначально ввод/вывод осуществлялся через физически подключенную системную консоль (ввод через клавиатуру, вывод через монитор), но стандартные потоки абстрагируют это. Когда команда выполняется через интерактивную оболочку , потоки обычно подключаются к текстовому терминалу, на котором запущена оболочка, но могут быть изменены с помощью перенаправления или конвейера . В более общем смысле, дочерний процесс наследует стандартные потоки своего родительского процесса .

Приложение

Стандартные потоки для ввода, вывода и ошибок в общей конфигурации по умолчанию

Пользователи обычно знают стандартные потоки как входные и выходные каналы, которые обрабатывают данные, поступающие с устройства ввода, или которые записывают данные из приложения. Данные могут быть текстом с любой кодировкой или двоичными данными . Когда программа запускается как демон , ее стандартный поток ошибок перенаправляется в файл журнала, как правило, для целей анализа ошибок.

Потоки могут использоваться для объединения приложений в цепочку, что означает, что выходной поток одной программы может быть перенаправлен в качестве входного потока для другого приложения. Во многих операционных системах это выражается перечислением имен приложений, разделенных символом вертикальной черты, по этой причине часто называемым символом конвейера . Хорошо известным примером является использование приложения для разбиения на страницы , такого как more , предоставляющего пользователю контроль над отображением выходного потока на дисплее.

Фон

В большинстве операционных систем, предшествовавших Unix , программы должны были явно подключаться к соответствующим устройствам ввода и вывода. Специфические для ОС тонкости делали это утомительной задачей программирования. Во многих системах было необходимо получить контроль над настройками среды, получить доступ к локальной таблице файлов, определить предполагаемый набор данных и правильно обращаться с оборудованием в случае считывателя перфокарт , накопителя на магнитной ленте , дисковода , линейного принтера , перфоратора или интерактивного терминала.

Одним из нескольких новаторских достижений Unix были абстрактные устройства , которые устранили необходимость для программы знать или заботиться о том, с какими устройствами она взаимодействует [ требуется ссылка ] . Старые операционные системы навязывали программисту структуру записи и часто неортогональную семантику данных и управление устройствами. Unix устранил эту сложность с помощью концепции потока данных: упорядоченной последовательности байтов данных, которые могут быть прочитаны до конца файла . Программа также может записывать байты по желанию и без необходимости и не может легко объявлять их количество или группировку.

Другим прорывом Unix было автоматическое связывание ввода и вывода с клавиатурой терминала и дисплеем терминала соответственно по умолчанию [ требуется цитата ] — программа (и программист) не делали абсолютно ничего, чтобы установить ввод и вывод для типичной программы ввода-обработки-вывода (если только она не выбирала другую парадигму). Напротив, предыдущие операционные системы обычно требовали некоторого — часто сложного — языка управления заданиями для установления соединений, или эквивалентная нагрузка должна была быть организована программой. [ требуется цитата ]

Поскольку Unix предоставлял стандартные потоки, среда выполнения Unix C также была обязана их поддерживать. В результате большинство сред выполнения C (и потомков C ), независимо от операционной системы, предоставляют эквивалентную функциональность.

Стандартный ввод (stdin)

Стандартный ввод — это поток, из которого программа считывает свои входные данные. Программа запрашивает передачу данных с помощью операции чтения . Не всем программам требуется потоковый ввод. Например, программы dir и ls (которые отображают имена файлов, содержащихся в каталоге) могут принимать аргументы командной строки , но выполнять свои операции без ввода потоковых данных.

Если не перенаправлено , стандартный ввод наследуется от родительского процесса. В случае интерактивной оболочки это обычно связано с устройством ввода терминала ( или псевдотерминала ), который в конечном итоге связан с клавиатурой пользователя .

В системах POSIX файловый дескриптор для стандартного ввода равен 0 (нулю); определение POSIX <unistd.h> равно STDIN_FILENO; соответствующая <stdio.h>абстракция C предоставляется через FILE* stdinглобальную переменную. Аналогично, глобальная std::cinпеременная C++ типа <iostream>предоставляет абстракцию через потоки C++ . Аналогичные абстракции существуют в стандартных библиотеках ввода-вывода практически каждого языка программирования .

Стандартный вывод (stdout)

Стандартный вывод — это поток, в который программа записывает свои выходные данные. Программа запрашивает передачу данных с помощью операции записи . Не все программы генерируют вывод. Например, команда переименования файла (называемая по-разному mv , move или ren ) не выдает никаких сообщений об успешном завершении.

Если не перенаправлено , стандартный вывод наследуется от родительского процесса. В случае интерактивной оболочки это обычно текстовый терминал , который инициировал программу.

Дескриптор файла для стандартного вывода — 1 (один); определение POSIX <unistd.h>STDOUT_FILENO; соответствующая <stdio.h>переменная C — FILE* stdout; аналогично, переменная C++ <iostream>std::cout.

Стандартная ошибка (stderr)

Стандартная ошибка — это другой выходной поток, который обычно используется программами для вывода сообщений об ошибках или диагностики. Это поток, независимый от стандартного вывода, и его можно перенаправить отдельно.

Это решает проблему полупредиката , позволяя различать вывод и ошибки, и аналогично функции, возвращающей пару значений – см. Проблема полупредиката: Многозначный возврат . Обычным местом назначения является текстовый терминал , который запустил программу, чтобы обеспечить наилучшие шансы быть увиденным, даже если стандартный вывод перенаправлен (поэтому нелегко наблюдать). Например, вывод программы в конвейере перенаправляется на ввод следующей программы или текстового файла, но ошибки из каждой программы по-прежнему поступают непосредственно в текстовый терминал, чтобы пользователь мог просматривать их в режиме реального времени. [2]

Допустимо и нормально направлять стандартный вывод и стандартную ошибку в одно и то же место назначения, например, на текстовый терминал. Сообщения появляются в том же порядке, в котором их записывает программа, если только не задействована буферизация . Например, в обычных ситуациях стандартный поток ошибок не буферизуется, но стандартный поток вывода буферизуется построчно; в этом случае текст, записанный в стандартную ошибку позже, может появиться на терминале раньше, если буфер стандартного потока вывода еще не заполнен.

Дескриптор файла для стандартной ошибки определен POSIX как 2 (два); заголовочный файл <unistd.h> предоставляет символ STDERR_FILENO; [3] соответствующая <stdio.h>переменная C — FILE* stderr. Стандартный заголовок C++ <iostream>предоставляет две переменные, связанные с этим потоком: std::cerrи std::clog, причем первая небуферизована, а вторая использует тот же механизм буферизации, что и все другие потоки C++.

Оболочки в стиле Bourne позволяют перенаправлять стандартную ошибку в то же место назначения, куда направляется стандартный вывод, используя

2>&1

Оболочки в стиле csh позволяют перенаправлять стандартные ошибки в то же место назначения, куда направляется стандартный вывод, используя

>&

Стандартная ошибка была добавлена ​​в Unix в 1970-х годах после того, как несколько бесполезных запусков фотонабора закончились тем, что сообщения об ошибках были набраны, а не отображены на терминале пользователя. [4]

Хронология

1950-е: Фортран

Fortran имеет эквивалент файловых дескрипторов Unix: По соглашению, многие реализации Fortran используют номера единиц UNIT=5для stdin, UNIT=6stdout и UNIT=0stderr. В Fortran-2003 встроенный ISO_FORTRAN_ENVмодуль был стандартизирован для включения именованных констант INPUT_UNIT, OUTPUT_UNIT, и ERROR_UNITдля переносимого указания номеров единиц.

! Пример FORTRAN 77 ПРОГРАММА MAIN INTEGER NUMBER READ ( UNIT = 5 , * ) NUMBER WRITE ( UNIT = 6 , '(A,I3)' ) ' NUMBER IS: ' , NUMBER END       
! Fortran 2003 пример программы main use iso_fortran_env неявный none целое :: число чтение ( единица = INPUT_UNIT , * ) число запись ( единица = OUTPUT_UNIT , '(a,i3)' ) 'Число равно: ' , число конец программы            

1960: АЛГОЛ 60

ALGOL 60 критиковали за отсутствие стандартного доступа к файлам. [ необходима цитата ]

1968: АЛГОЛ 68

Входные и выходные средства ALGOL 68 совместно назывались transput. [5] Костер координировал определение стандарта transput . Модель включала три стандартных канала: stand in, stand out, и stand back.

1970-е: C и Unix

В языке программирования C стандартные потоки ввода, вывода и ошибок присоединены к существующим файловым дескрипторам Unix 0, 1 и 2 соответственно. [6] В среде POSIX вместо магических чисел следует использовать определения < unistd.h > STDIN_FILENO , STDOUT_FILENO или STDERR_FILENO . Также предусмотрены указатели файлов stdin , stdout и stderr .

Кен Томпсон (разработчик и разработчик оригинальной операционной системы Unix) модифицировал sort в версии 5 Unix , чтобы принять "-" как представление стандартного ввода, что распространилось на другие утилиты и стало частью операционной системы как специальный файл в версии 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 ( Exception 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 ( " Число равно : { 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 .NETPublic Function Main ( ) As Integer Try Dim s As String = System.Console . [ In ] .ReadLine ( ) Dim number As Double = Double.Parse ( s ) System.Console.Out.WriteLine ( " Число равно : { 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_fileno  =  sys . stdinstdout_fileno  =  sys . stdout# Перенаправить sys.stdout в файлsys.stdout = открыть ( "  myfile.txt" ,  "w " ) ctr  =  0для  inps  в  stdin_fileno : ctrs  =  str ( ctr ) # Выводит на перенаправленный stdout () sys . stdout . write ( ctrs  +  ") это перенаправлено --->"  +  inps  +  " \n " ) # Выводит на экран фактически сохраненный обработчик stdout stdout_fileno . write ( ctrs  +  ") это в фактическое --->"  +  inps  +  " \n " ) ctr  =  ctr  +  1# Закрыть файлsys.stdout.close ( )# Восстановить sys.stdout в наш старый сохраненный обработчик файловsys . stdout  =  stdout_fileno

Графические интерфейсы

Графические пользовательские интерфейсы (GUI) не всегда используют стандартные потоки; они это делают, когда GUI являются оболочками базовых скриптов и/или консольных программ, например, графический интерфейс менеджера пакетов Synaptic , который оборачивает команды apt в Debian и/или Ubuntu. GUI, созданные с помощью инструментов скриптования, таких как Zenity и KDialog проекта KDE [10], используют stdin, stdout и stderr и основаны на простых скриптах, а не на полном GUI, запрограммированном и скомпилированном на C/C++ с использованием Qt , GTK или другой эквивалентной фирменной структуры виджетов.

Меню Services , реализованное в NeXTSTEP и Mac OS X , также аналогично стандартным потокам. В этих операционных системах графические приложения могут предоставлять функциональность через общесистемное меню, которое работает с текущим выбором в GUI, независимо от того, в каком приложении.

Некоторые программы GUI, в основном на Unix, по-прежнему записывают отладочную информацию в стандартный поток ошибок. Другие (например, многие медиаплееры Unix) могут читать файлы из стандартного потока ввода. Популярные программы Windows, которые открывают отдельное консольное окно в дополнение к своим окнам GUI, — это эмуляторы pSX и DOSBox .

GTK-сервер может использовать stdin в качестве интерфейса связи с интерпретируемой программой для реализации графического интерфейса пользователя.

Парадигма Common Lisp Interface Manager «представляет» элементы графического интерфейса, отправленные в расширенный выходной поток.

Смотрите также

Ссылки

  1. ^ Д. М. Ритчи, «Система потокового ввода-вывода», Технический журнал AT&T Bell Laboratories, 68(8), октябрь 1984 г.
  2. ^ "Что такое stdin, stdout и stderr в Linux? | CodePre.com". 2 декабря 2021 г. Получено 8 апреля 2022 г.
  3. ^ "<unistd.h>". Базовые спецификации Open Group, выпуск 6 — IEEE Std 1003.1, издание 2004 г. The Open Group. 2004.
  4. ^ Джонсон, Стив (2013-12-11). "[TUHS] Graphic Systems C/A/T phototypesetter" (список рассылки). Архивировано из оригинала 2020-09-25 . Получено 2020-11-07 .
  5. ^ «Пересмотренный отчет об алгоритмическом языке Algol 68», под редакцией А. ван Вейнгаардена, Б. Дж. Майу, Дж. Э. Пека, Ч. А. Костера, М. Синцова, К. Х. Линдси, LGLT Меертенса и Р. Г. Фискера, Раздел 10.3.
  6. ^ "Stdin(3): Стандартные потоки ввода-вывода - страница руководства Linux". die.net . Архивировано из оригинала 8 июня 2023 г.
  7. ^ Макилрой, MD (1987). Исследовательский ридер Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (Технический отчет). CSTR. Bell Labs. 139. Архивировано (PDF) из оригинала 15 декабря 2023 г.
  8. ^ "Система (Java Platform SE 7)". Oracle Help Center . Получено 20 июля 2012 г.
  9. ^ ".NET Framework 4.7.1, mscorlib, console.cs". Источник ссылки - Microsoft . Архивировано из оригинала 10 декабря 2017 г. Получено 10 декабря 2017 г.
  10. ^ Кислинг, Кристиан (2009). «Добавление графических элементов в ваши скрипты с помощью Zenity и KDialog». Linux Magazine . Получено 11 апреля 2021 г.

Источники

Внешние ссылки