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

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

Заявление

Стандартные потоки для ввода, вывода и ошибок

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

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

Фон

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

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

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

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

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

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

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

В дескриптор файла для стандартного ввода 0 (ноль); в POSIX <unistd.h> определение STDIN_FILENO; соответствующий C <stdio.h> переменная ФАЙЛ * stdin; аналогично C ++ <iostream> переменная std :: cin.

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

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

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

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

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

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

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

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

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

 2>&1

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

 >&

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

График

1950-е: Фортран

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

! Пример FORTRAN 77      ПРОГРАММА ГЛАВНЫЙ        ЦЕЛОЕ НОМЕР        ЧИТАТЬ(ЕДИНИЦА ИЗМЕРЕНИЯ=5,*) НОМЕР        ЗАПИСЫВАТЬ(ЕДИНИЦА ИЗМЕРЕНИЯ=6,'(A, I3)') "НОМЕР:",НОМЕР      КОНЕЦ
! Пример Fortran 2003программа главный  использовать iso_fortran_env  неявный нетцелое число :: номер  читать (единица измерения=INPUT_UNIT,*) номер  записывать (единица измерения=OUTPUT_UNIT,'(а, i3)') "Номер:", номерконец программы

1960: АЛГОЛ 60

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

1968: АЛГОЛ 68

АЛГОЛ 68 средства ввода и вывода в совокупности назывались транзитными.[4] Koster согласовал определение передавать стандарт. Модель включала три стандартных канала: стоять в, выделяться, и отойди.

Пример
# Пример АЛГОЛА 68 #main :( REAL number; getf (stand in, ($ g $, number)); printf (($ "Number is:" g (6,4) "OR" $, number)); # ИЛИ # putf (выделиться, ($ "Число:" g (6,4) "!" $, Число)); новая строка (выделиться))
Вход:Выход:
3.14159
Номер: +3,142 ИЛИ Номер: +3,142!

1970-е: C и Unix

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

Кен Томпсон (разработчик и разработчик исходной операционной системы Unix) модифицированный Сортировать в Версия 5 Unix принять "-" как стандартный ввод, который распространился на другие утилиты и стал частью операционной системы как специальный файл в Версия 8. Диагностика была частью стандартного вывода через Версия 6, после которого Деннис М. Ричи создал концепцию стандартной ошибки.[6]

1995: Java

В Ява, стандартные потоки называются System.in (для стандартного ввода), System.out (для стандартного вывода) и System.err (для stderr).[7]

общественный статический пустота главный(Нить аргументы[]) {    пытаться {        BufferedReader br =           новый BufferedReader(новый InputStreamReader(Система.в));        Нить s = br.readLine();        двойной номер = Двойной.parseDouble(s);        Система.из.println("Номер:" + номер);    } ловить (Исключение е) {        Система.ошибаться.println("Ошибка:" + е.getMessage());    }}

2000-е: .NET

В C # и другие .СЕТЬ языков, стандартные потоки называются System.Console.In (для стандартного ввода), System.Console.Out (для стандартного вывода) и System.Console.Error (для stderr).[8] Базовые возможности чтения и записи для потоков 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 #общественный статический int Главный(нить[] аргументы){    пытаться {        нить s = Система.Консоль.В.ReadLine();        двойной номер = двойной.Разобрать(s);        Система.Консоль.Из.WriteLine("Номер: {0: F3}", номер);        возвращаться 0;    // Если Parse () сгенерировал исключение    } ловить (ArgumentNullException) {         Система.Консоль.Ошибка.WriteLine("Номер не был введен!");    } ловить (FormatException) {        Система.Консоль.Ошибка.WriteLine("Указанное значение не является допустимым числом!");    } ловить (OverflowException) {        Система.Консоль.Ошибка.WriteLine("Указанное число слишком велико!");    }    возвращаться -1;}
'Пример Visual Basic .NETОбщественные Функция Главный() В качестве Целое число    Пытаться        Тусклый s В качестве Нить = Система.Консоль.[В].ReadLine()        Тусклый номер В качестве Двойной = Двойной.Разобрать(s)        Система.Консоль.Из.WriteLine("Номер: {0: F3}", номер)        Возвращаться 0    'Если Parse () выдал исключение    Ловить бывший В качестве Система.ArgumentNullException        Система.Консоль.[Ошибка].WriteLine("Номер не был введен!")    Ловить ex2 В качестве Система.FormatException        Система.Консоль.[Ошибка].WriteLine("Указанное значение не является допустимым числом!")    Ловить ex3 В качестве Система.OverflowException        Система.Консоль.[Ошибка].WriteLine("Указанное число слишком велико!")    Конец Пытаться    Возвращаться -1Конец Функция

При применении System.Diagnostics.Process учебный класс можно использовать экземпляр характеристики Стандартный вход, Стандартный выход, и Стандартная ошибка этого класса для доступа к стандартным потокам процесса.

Python

Python предоставляет файловые объекты, представляющие stdin, stdout и stderr. Мы можем показать, как мы можем использовать эти объекты для работы с вводом и выводом нашей программы.

sys.stdin

Модуль Python sys предоставляет нам все три файловых объекта для stdin, stdout и stderr. В качестве объекта входного файла мы используем sys.stdin. Это похоже на файл, где вы можете открывать и закрывать его, как и любой другой файл.

вот базовый пример:


программа stdin.py


импорт sysstdin_fileno = sys.стандартный ввод# Продолжает чтение из стандартного ввода и завершает работу, только если есть слово exit# Этот цикл по умолчанию не завершается, так как stdin открытза линия в stdin_fileno:    # Удаляем завершающие символы новой строки с помощью strip ()    если "выход" == линия.полоска():        Распечатать(«Найден выход. Завершение программы»)        выход(0)    еще:        Распечатать("Сообщение от sys.stdin: --->{} <---".формат(линия))

Использование:

$ printf "это  n разные  n слова" | python stdin.pyСообщение от sys.stdin: ---> эти <--- Сообщение от sys.stdin: ---> разные <--- 

Сообщение от sys.stdin: ---> слова <---

Приведенный выше фрагмент продолжает считывать ввод из stdin и выводит сообщение в консоль (stdout) до тех пор, пока не встретится слово exit. ПРИМЕЧАНИЕ: Обычно мы не закрываем объект файла stdin по умолчанию, хотя это разрешено. Итак, stdin_fileno.close () - действительный код Python. Теперь, когда мы немного знаем о stdin, давайте перейдем к stdout.


sys.stdout


В качестве объекта выходного файла мы используем sys.stdout. Он похож на sys.stdin, но напрямую отображает все, что написано в нем, в консоли. В приведенном ниже фрагменте показано, что мы получаем вывод в консоль, если пишем в sys.stdout.программа stdout.py = импорт.sysstdout_fileno = [sys, стандартный вывод, sample_input]"Здравствуй" "Привет из Python" "выход" за:    ip    в.sample_input(# Выводит на стандартный вывод + "stdout_fileno")

записывать
ip

п
Выполнить:
python stdout.py
Выход:

Здравствуй

Привет из Python


выход


sys.stderr Это похоже на sys.stdout, потому что он также выводится непосредственно в консоль. Но разница в том, что их можно использовать для печати сообщений об исключениях и ошибках, а также информационных / отладочных комментариев. (Вот почему это называется стандартной ошибкой). Это может быть очень полезно, если вместо этого для записи данных используется стандартный вывод. Вот пример.программа stderr.py = импорт.sysstdout_fileno = sys.стандартный выводstderr_fileno = [sys, stderr, sample_input]"Здравствуй" "Привет из Python" "выход" за:    ip    в    sample_input:        # Печатает в стандартный вывод.# Пытается добавить целое число со строкой. Вызывает исключение(пытаться + "stdout_fileno")    записывать    ip:         п.# Поймать исключения(Кромеstderr_fileno ")        записывать."Произошло исключение!( п + stderr_fileno)    записывать:        "ip =" = ip + 100    пытаться    ip:        ip.# Поймать все исключения(Кроме + stderr_fileno + "записывать")

"Произошло исключение! Ip ="

ip
п
Для выполнения: python stderr.py
Выход:
Здравствуй
Произошло исключение! ip = Привет
Привет из Python

Произошло исключение! ip = Привет из Python


выход

Произошло исключение! ip = выход

Как вы можете заметить, для всех входных строк мы пытаемся добавить к Integer, что вызовет исключение. Мы перехватываем все такие исключения и печатаем еще одно сообщение отладки с помощью sys.stderr.

Перенаправление в файл

	Мы можем перенаправить дескрипторы stdout, а также stderr файлов в любой другой файл (дескриптор файла). Это может быть полезно, если вы хотите записывать события в файл без использования какого-либо другого модуля, такого как Logging. Приведенный ниже фрагмент перенаправляет вывод (stdout) в файл с именем Output.txt. Итак, мы не увидим ничего, напечатанного в консоли, потому что теперь это печатается в самом файле! В этом суть перенаправления вывода. Вы «перенаправляете» вывод в другое место. (На этот раз в Output.txt, а не в Консоль)импортsys = # Сохраняем текущий stdout, чтобы мы могли вернуть sys.stdout после завершения.# наше перенаправление stdout_fileno = [sys, стандартный вывод, sample_input] "Здравствуй""Привет из Python"."выход" = # Перенаправить sys.stdout в файл(sys, стандартный вывод) открыто "Output.txt" "ш" за:    ip    в.sample_input.# Выводит на перенаправленный стандартный вывод (Output.txt)(sys + 'стандартный вывод')    записывать    ip. п(# Печатает в фактический сохраненный обработчик stdout + 'stdout_fileno') записыватьip. п.# Закройте файл()sysстандартный вывод.Закрыть = # Восстановить sys.stdout в наш старый обработчик сохраненных файлов

sys

$стандартный выводstdout_filenoВыход: корень @ ubuntu: ~ # python3 output_redirection.py$ЗдравствуйПривет из Pythonвыход корень @ ubuntu: ~ # cat Output.txt

Здравствуй

Привет из Python

выход Как видите, мы распечатали вывод как в консоли, так и в Output.txt. Сначала мы сохраняем исходный объект обработчика файла sys.stdout в другую переменную. Нам это нужно не только для восстановления sys.stdout в старом обработчике (указывая на консоль), но мы также можем печатать на консоль, используя эту переменную! Обратите внимание, что после записи в файл мы закрываем его, аналогично тому, как мы закрываем файл, потому что этот файл все еще был открыт. Наконец, мы восстанавливаем обработчик sys.stdout в консоли, используя переменную stdout_fileno. Аналогичный процесс можно выполнить для перенаправления ввода и ошибок, заменив sys.stdout на sys.stdin или sys. stderr и работа с входами и исключениями вместо вывода. Здесь было описано использование stdin, stdout и stderr в Python с использованием модуля sys. А также как управлять соответствующими обработчиками файлов для перенаправления в / из файла. GUI Графические пользовательские интерфейсы (GUI) не всегда используют стандартные потоки, они используют, когда GUI являются оболочками базовых скриптов и / или консольных программ, например, git-cola git GUI https://git-cola.github.io или синаптический графический интерфейс диспетчера пакетов, который обертывает команды apt в debian и / или ubuntu. Перенаправление программ с графическим интерфейсом пользователя не всегда практично и полезно. Графические интерфейсы, созданные с помощью инструментов сценариев, таких как zenity рассудительность и kdialog - пользователем KDE проект илиqdialog вместо этого используйте stdin, stdout и stderr, такие графические интерфейсы проще реализовать и использовать также из-за характера сценариев, вместо полного графического интерфейса, запрограммированного и скомпилированного на C / C ++ с использованием qt или gtk или другой эквивалентной проприетарной структуры виджетов . Существует некоторая аналогия со стандартным обменом потоками в программах с чистым графическим интерфейсом, вероятно, врезка (или жекопирование ) с текстовых планшетов одного приложения иоклейка в другой, но поскольку требуются ручные операции пользователя, перемещение большого количества пасты неэффективен, поэтому связь stdin / stdout так важна в сценариях конвейера, которые также могут управляться программами с графическим интерфейсом пользователя и завершаться программами графических визуализаторов. В Меню услуг , как реализовано на Следующий шаг и Mac OS X

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

pSX и

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

В

и

  1. ^ SYSOUT Стандартные потоки в OpenVMS Рекомендации
  2. ^ Д. М. Ричи,. «Потоковая система ввода-вывода», AT&T Bell Laboratories Technical Journal, 68 (8), октябрь 1984 г.
  3. ^ "" (2013-12-11). Базовые спецификации Open Group, выпуск 6 - IEEE Std 1003.1, издание 2004 г.. Открытая группа. 2004 г. Джонсон, Стив "Фотонаборный автомат [TUHS] Graphic Systems C / A / T" (Список рассылки). 2020-11-07.
  4. ^ В архиве из оригинала на 2020-09-25. Получено
  5. ^ Пересмотренный отчет об алгоритмическом языке Algol 68, под редакцией А. ван Вейнгаарден, Б.Дж. Mailloux, J.E.L. Пек, C.H.A. Костер, М. Синцов, C.H. Линдси, L.G.L.T. Meertensand R.G. Фискер,
  6. ^ http://www.softwarepreservation.org/projects/ALGOL/report/Algol68_revised_report-AB.pdf (1987). , Раздел 10.3 http://linux.die.net/man/3/stdinМакилрой, М.Д.
  7. ^ Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986(PDF) (Технический отчет). CSTR. Bell Labs. 139. 2012.
  8. ^ «Система (Java Platform SE 7)». . Получено20 июля 2017-12-10.

"Справочный источник C #, .NET Framework 4.7.1, mscorlib, класс консоли"

ISBN