Введение
Соединенные потоки ввода и вывода для компьютерных программ, стандартные дескрипторы I/O. В компьютерном программировании стандартные потоки — это предварительно подключенные каналы связи между компьютерной программой и её окружением при начале выполнения. Три соединения ввода/вывода (I/O) называются стандартным входом (stdin), стандартным выходом (stdout) и стандартным потоком ошибок (stderr). Изначально ввод/вывод осуществлялся через физически подключенную системную консоль (ввод с клавиатуры, вывод на монитор), но стандартные потоки абстрагируют этот процесс. Когда команда выполняется через интерактивную оболочку, потоки обычно подключены к текстовому терминалу, на котором запущена оболочка, но могут быть изменены с помощью перенаправления или конвейера. В более общем случае, дочерний процесс наследует стандартные потоки своего родительского процесса.
standard I/O file descriptors
In computer programming, standard streams are preconnected input and output communication channels between a computer program and its environment when it begins execution. The three input/output (I/O) connections are called standard input (stdin), standard output (stdout) and standard error (stderr). Originally I/O happened via a physically connected system console (input via keyboard, output via monitor), but standard streams abstract this. When a command is executed via an interactive shell, the streams are typically connected to the text terminal on which the shell is running, but can be changed with redirection or a pipeline. More generally, a child process inherits the standard streams of its parent process.
Применение
Пользователи обычно знают стандартные потоки как каналы ввода и вывода, обрабатывающие данные, поступающие от устройства ввода, или записывающие данные из приложения. Данные могут быть представлены текстом в любой кодировке или в виде двоичных данных. Когда программа запускается как демон, её стандартный поток ошибок перенаправляется в лог-файл, как правило, для анализа ошибок. Потоки могут использоваться для объединения приложений в цепочку, то есть выходной поток одной программы может быть перенаправлен на входной поток другого приложения. Во многих операционных системах это выражается перечислением имён приложений, разделённых символом вертикальной черты, который поэтому часто называют символом конвейера. Хорошо известный пример – использование программ постраничного вывода, таких как more, предоставляющих пользователю возможность управлять отображением выходного потока на экране.
Предыстория
В большинстве операционных систем, предшествовавших Unix, программы должны были явно подключаться к соответствующим входным и выходным устройствам. Специфические особенности ОС делали это утомительной задачей программирования. На многих системах требовалось получить контроль над настройками окружения, доступ к локальной таблице файлов, определить целевой набор данных и корректно обрабатывать аппаратное обеспечение в случае считывателя перфокарт, магнитной ленты, дисковода, линейного принтера, перфоратора или интерактивного терминала. Одним из нескольких революционных достижений Unix стало использование абстрактных устройств, устранивших необходимость для программы знать или учитывать тип устройств, с которыми она взаимодействует. Более ранние операционные системы навязывали программисту структуру записей и часто неортогональную семантику данных и управление устройствами. Unix избавил от этой сложности благодаря концепции потока данных – упорядоченной последовательности байтов данных, которую можно читать до конца файла. Программа также может записывать байты по мере необходимости, не требуя и не имея возможности легко указать их количество или группировку. Еще одним прорывом Unix стало автоматическое сопоставление ввода с терминальной клавиатурой, а вывода – с дисплеем терминала по умолчанию, то есть программа (и программист) не должны были предпринимать никаких действий для установления ввода и вывода для типичной программы ввода-вывода (если не выбиралась иная парадигма). В отличие от этого, предыдущие операционные системы обычно требовали некоторого – часто сложного – языка управления заданиями для установления соединений, либо эквивалентную нагрузку приходилось организовывать в самой программе. Поскольку Unix предоставлял стандартные потоки, среда выполнения Unix C была обязана поддерживать их. В результате большинство сред выполнения C (и языков, произошедших от C), независимо от операционной системы, предоставляют эквивалентную функциональность.
Стандартный вход (stdin)
Стандартный ввод — это поток, из которого программа считывает свои входные данные. Программа запрашивает передачу данных посредством операции чтения. Не все программы нуждаются в потоковом вводе. Например, программы `dir` и `ls` (которые отображают имена файлов, содержащихся в каталоге) могут принимать аргументы командной строки, но выполнять свои операции без каких-либо данных из потока ввода. Если не было произведено перенаправление, стандартный ввод наследуется от родительского процесса. В случае интерактивной оболочки он обычно связан с устройством ввода терминала (или псевдотерминала), который в конечном итоге подключен к клавиатуре пользователя. В системах POSIX файловый дескриптор стандартного ввода равен 0 (нулю); определение `STDIN_FILENO` приводится в POSIX `<unistd.h>`; соответствующая абстракция C предоставляется через глобальную переменную `FILE* stdin` из `<stdio.h>`. Аналогично, глобальная переменная `std::cin` типа `<iostream>` в C++ обеспечивает абстракцию посредством потоков C++. Схожие абстракции существуют в стандартных библиотеках ввода-вывода практически всех языков программирования.
Стандартный выход (stdout)
Стандартный вывод — это поток, в который программа выводит свои данные. Программа запрашивает передачу данных операцией записи. Не все программы генерируют вывод. Например, команда переименования файла (которая может называться mv, move или ren) не сообщает об успехе. Если вывод не перенаправлен, стандартный вывод наследуется от родительского процесса. В случае интерактивной оболочки это обычно текстовый терминал, из которого была запущена программа. Дескриптор файла для стандартного вывода — 1 (один); определение POSIX в <unistd.h> — STDOUT_FILENO; соответствующая переменная в C <stdio.h> — FILE* stdout; аналогично, в C++ <iostream> — std::cout.
1960: АЛГОЛ 60
ALGOL 60 подвергся критике за отсутствие стандартного доступа к файлам.
1970-е: C и Unix
В языке программирования C стандартные потоки ввода, вывода и ошибок связаны с существующими дескрипторами файлов Unix 0, 1 и 2 соответственно. В среде POSIX вместо "магических чисел" следует использовать определения STDIN_FILENO, STDOUT_FILENO или STDERR_FILENO из <unistd.h>. Также предоставляются файловые указатели stdin, stdout и stderr. Кен Томпсон (разработчик и реализатор оригинальной операционной системы Unix) изменил программу сортировки в Unix версии 5, чтобы она принимала " " в качестве обозначения стандартного ввода, что распространилось на другие утилиты и стало частью операционной системы в виде специального файла в версии 8. Диагностические сообщения выводились в стандартный поток вывода до версии 6, после чего Деннис М. Ричи ввёл понятие стандартного потока ошибок.
ГИИ
Графические пользовательские интерфейсы (GUI) не всегда используют стандартные потоки ввода-вывода; они используют их, когда GUI являются оболочками для базовых скриптов и/или консольных программ, например, GUI-управляющий пакетами Synaptic, который оборачивает команды apt в Debian и/или Ubuntu. GUI, созданные с помощью скриптовых инструментов, таких как Zenity и KDialog от проекта KDE, используют stdin, stdout и stderr и основаны на простых скриптах, а не на полноценном графическом интерфейсе, запрограммированном и скомпилированном на C/C++ с использованием Qt, GTK или других эквивалентных проприетарных фреймворков. Меню "Сервисы", реализованное в NeXTSTEP и Mac OS X, также аналогично стандартным потокам. В этих операционных системах графические приложения могут предоставлять функциональность через общесистемное меню, которое оперирует текущим выделением в графическом интерфейсе, независимо от того, в каком приложении оно находится. Некоторые GUI-программы, преимущественно на Unix, по-прежнему выводят отладочную информацию в стандартный поток ошибок. Другие (например, многие Unix-медиаплееры) могут читать файлы из стандартного ввода. Популярные программы для Windows, которые открывают отдельное консольное окно в дополнение к окнам GUI, – это эмуляторы pSX и DOSBox. GTK-сервер может использовать stdin в качестве интерфейса связи с интерпретируемой программой для реализации GUI. Парадигма Common Lisp Interface Manager "представляет" элементы GUI, отправленные в расширенный выходной поток.