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-е: Фортран

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

! ПРИМЕР FORTRAN 77 ПРОГРАММА ОСНОВНОЙ ЦЕЛЫЙ НОМЕР ЧТЕНИЕ ( UNIT = 5 , * ) НОМЕР ЗАПИСЬ ( UNIT = 6 , '(A,I3)' ) ' NUMBER IS: ' , NUMBER END       
! Пример программы на Фортране 2003 , основное использование iso_fortran_env неявное none целое :: чтение числа ( unit = INPUT_UNIT , * ) запись числа ( unit = OUTPUT_UNIT , '(a,i3)' ) 'Number is: ' , число конца программы            

1960: АЛГОЛ 60

АЛГОЛ 60 критиковали за отсутствие стандартного доступа к файлам. [ нужна цитата ]

1968: АЛГОЛ 68

Средства ввода и вывода Алгола 68 вместе назывались транспутом. [5] Костер координировал определение стандарта передачи данных . Модель включала три стандартных канала: 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) изменил сортировку в Unix версии 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 ( новый InputStreamReader ( System . in )); Строка s = бр . читатьстроку (); двойное число = двойное . parseDouble ( s ); Система . вне . println ( "Число:" + число ); } catch ( Исключение е ) { System . ошибаюсь . 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 . Консоль . В . ЧитатьЛинию (); двойное число = двойное . Разобрать ( ы ); Система . Консоль . Вне . WriteLine ( "Номер: {0:F3}" , номер ); вернуть 0 ;                   // Если Parse() выдал исключение } catch ( ArgumentNullException ) { System . Консоль . Ошибка . WriteLine ( "Номер не введен!" ); } catch ( FormatException ) { System . Консоль . Ошибка . WriteLine ( "Указанное значение не является допустимым числом!" ); } catch ( OverflowException ) { System . Консоль . Ошибка . WriteLine ( "Указанное число слишком велико!" ); }                  возврат 1 ; } 
'Пример Visual Basic .NETОткрытая функция Main () Как целое число Попробуйте Dim s As String = System . Консоль . [ В ] . ReadLine () Тусклое число As Double = Double . Разбор ( ы ) системы . Консоль . Вне . WriteLine ( "Число: {0:F3}" , число ) Возвращает 0                      ' Если Parse() выдал исключение Catch ex As System . Система исключений ArgumentNullException . Консоль . [ Ошибка ] . WriteLine ( "Ни один номер не был введен!" ) Catch ex2 As System . Система исключений формата . Консоль . [ Ошибка ] . WriteLine ( "Указанное значение не является допустимым числом!" ) Catch ex3 As System . Система исключений переполнения . Консоль . [ Ошибка ] . WriteLine ( "Указанное число слишком велико!" ) End Try                  Возврат 1 Конечная функция  

При применении System.Diagnostics.Process класса можно использовать свойства StandardInput экземпляра , StandardOutputи StandardErrorэтого класса для доступа к стандартным потокам процесса.

2000 -: Питон (2 или 3)

В следующем примере, написанном на Python , показано, как перенаправить стандартный ввод как на стандартный вывод, так и в текстовый файл.

#!/usr/bin/env питонимпортировать  систему# Сохраняем текущий стандартный вывод, чтобы можно было вернуть sys.stdout# после того, как мы завершим наше перенаправлениеstdin_fileno  =  sys . стандартный вводstdout_fileno  =  sys . стандартный вывод# Перенаправляем sys.stdout в файлсис . stdout  =  открыть ( 'myfile.txt' ,  'w' )Ctrl  =  0для  ввода  в  stdin_fileno : ctrs  =  ул ( ctr ) # Печатает на перенаправленный стандартный вывод () сис . стандартный вывод . напишите ( ctrs  +  ") это для перенаправления --->"  +  inps  +  ' \n ' ) # Печатает фактически сохраненный обработчик стандартного вывода stdout_fileno . напишите ( ctrs  +  ") это актуальное --->"  +  inps  +  ' \n ' ) Ctrl  =  Ctrl  +  1# Закрываем файлсис . стандартный вывод . закрывать ()# Восстанавливаем sys.stdout в наш старый сохраненный обработчик файловсис . стандартный вывод  =  stdout_fileno

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

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

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

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

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

Парадигма 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>". Базовые спецификации открытой группы, выпуск 6 — стандарт IEEE 1003.1, издание 2004 г. Открытая группа. 2004.
  4. ^ Джонсон, Стив (11 декабря 2013 г.). «[TUHS] Фотонаборная машина Graphic Systems C/A/T» (список рассылки). Архивировано из оригинала 25 сентября 2020 г. Проверено 07.11.2020 .
  5. ^ «Пересмотренный отчет об алгоритмическом языке Algol 68», под редакцией А. ван Вейнгаардена, Б. Дж. Майу, Дж. Э. Пека, ЧА Костера, М. Синцова, К. Х. Линдси, LGLT Меертенса и Р. Г. Фискера, Раздел 10.3.
  6. ^ «Stdin(3): Стандартные потоки ввода-вывода — справочная страница Linux» . сайт die.net . Архивировано из оригинала 8 июня 2023 г.
  7. ^ Макилрой, доктор медицины (1987). Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (Технический отчет). CSTR. Лаборатории Белла. 139. Архивировано (PDF) из оригинала 15 декабря 2023 г.
  8. ^ «Система (платформа Java SE 7)» . Справочный центр Oracle . Проверено 20 июля 2012 г.
  9. ^ «.NET Framework 4.7.1, mscorlib, console.cs». Справочный источник — Microsoft . Архивировано из оригинала 10 декабря 2017 года . Проверено 10 декабря 2017 г.
  10. ^ Кисслинг, Кристиан (2009). «Добавление графических элементов в ваши скрипты с помощью Zenity и KDialog». Журнал Линукс . Проверено 11 апреля 2021 г.

Источники

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