Skip to content

stdin, stdout, stderr, pipe

Файловый дескриптор (file descriptor) - это целое число, которое операционная система присваивает файлу при его открытии. Файловые дескрипторы используются для обращения к файлам и другим объектам ввода-вывода операционной системы.

Стандартные файловые дескрипторы

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

  • 0 - стандартный ввод (stdin).
  • 1 - стандартный вывод (stdout).
  • 2 - стандартный поток ошибок (stderr).

Эти дескрипторы представляют собой абстракцию для файловых объектов, которые могут быть использованы вводом или выводом операций.

stdin и stdout - это стандартные потоки ввода и вывода в Unix-подобных операционных системах (включая Linux). Они представляют собой каналы для передачи данных между программами и системой. Процессы считывают данные из потоков ввода и записывают данные в потоки вывода.

  1. stdin (стандартный поток ввода): Это поток, через который данные поступают в программу. Обычно stdin связан с клавиатурой или другими устройствами ввода, и программа читает данные из этого потока.

  2. stdout (стандартный поток вывода): Это поток, через который программа выводит данные. Обычно stdout связан с терминалом или другими устройствами вывода, и программа отправляет результаты своей работы в этот поток. Стандартный вывод прост. Ядро предоставляет каждому процессу стандартный поток вывода, в который можно записывать выходные данные.

  3. stderr (стандартный поток ошибок): Существует также и третий стандартный поток ввода/вывода, который назы­вается стандартной ошибкой. Он предназначен для вывода сообщений об ошибках и другой отладочной информации от программ. В отличие от stdout, который используется для обычного вывода данных, stderr предназначен специально для вывода сообщений об ошибках и предупреждений. stderr обычно связан с тем же устройством вывода, что и stdout, что означает, что сообщения об ошибках обычно будут появляться на том же экране или в том же файле, что и обычный вывод данных. Однако вы можете использовать оператор перенаправления 2> для перенаправления stderr в отдельный файл.

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

Одним из самых важных свойств стандартных потоков является легкость ма­нипулирования ими с целью записи и чтения, причем не только в терминале. Операторы перенаправления > и < могут использоваться для управления потоками stdin и stdout. Например:

  • command < input.txt - перенаправляет содержимое файла input.txt в stdin программы command.
  • command > output.txt - перенаправляет stdout программы command в файл output.txt.
  • command >> output.txt - добавляет stdout программы command к концу файла output.txt.
  • command 2> error.log - перенаправляет сообщения об ошибках, выводимые программой command, в файл error.log.
  • command > output.txt 2>&1 - перенаправляет как stdout, так и stderr программы command в файл output.txt.

Конвеер pipe |

Символ |, который называется "вертикальной чертой" или "пайпом" (pipe), используется в Linux для передачи данных между программами через стандартные потоки ввода и вывода. Это позволяет создавать цепочки команд, где вывод одной команды становится вводом для другой команды.

Примеры использования pipe |:

Пайпинг вывода:
command1 | command2  # В этом случае, вывод command1 становится вводом для command2. Это позволяет цепочке команд обрабатывать данные последовательно. 
ls -l | grep ".txt" # Здесь команда ls -l выводит список файлов и передает его ввод в команду grep, которая ищет строки, содержащие ".txt".
Анализ логов:
cat logfile.txt | grep "error" | more  
# Эта команда читает содержимое файла лога logfile.txt, передает его на ввод команде grep для поиска строк с "error", 
# и затем выводит результат постранично через more.
Фильтрация данных:
ps aux | sort -nrk 3 | head -n 5 
# Эта цепочка команд выводит список всех процессов (ps aux), сортирует их по использованию CPU (sort -nrk 3)
# и выводит первые 5 строк (head -n 5).
Подсчет количества строк в файле:
cat file.txt | wc -l 
# Здесь команда cat читает содержимое файла file.txt и передает его ввод в команду wc -l, которая подсчитывает количество строк.
Поиск наиболее используемых команд в истории терминала:
history | awk '{print $2}' | sort | uniq -c | sort -nr | head -n 10
# Эта цепочка команд анализирует историю команд в терминале. Она использует awk для извлечения второго столбца (команд), 
# затем сортирует, подсчитывает уникальные команды, снова сортирует по количеству использований и выводит 10 наиболее часто используемых команд.
Архивирование и сжатие:
tar czvf archive.tar.gz folder/ | ssh user@remotehost "cat > /path/to/remote/archive.tar.gz"
# Здесь tar создает архив папки folder/, сжимает его с помощью gzip, а затем передает его по SSH на удаленный хост с использованием команды ssh.
Анализ использования дискового пространства:
df -h | grep "/dev/sda" | sort -k 5 -h 
# Команда df -h выводит информацию о дисковом пространстве,
# grep фильтрует строки, связанные с /dev/sda, и sort сортирует их по использованию дискового пространства.

Нотация >&

Нотация >& используется для перенаправления потоков вывода (stdout и stderr) одной команды на ввод другой команды или в файл. Это позволяет управлять как обычным выводом, так и сообщениями об ошибках.

Примеры использования нотации >&:

Перенаправление stdout и stderr в файл:
command > output.txt 2>&1 
# В этом примере stdout команды command будет перенаправлен в файл output.txt, 
# а stderr будет также перенаправлен в тот же файл (2>&1).
Перенаправление stderr в stdout:
command 2>&1 
# Эта команда перенаправляет stderr в тот же поток, что и stdout, что означает, что оба потока будут выводиться вместе.
Перенаправление stdout и stderr в пустоту:
command1 &> /dev/null
# Нотация 2>&1 может быть сокращена нотацией &>
Перенаправление в пайп:
command1 2>&1 | command2 
# В этом случае, stdout и stderr команды command1 будут объединены и переданы как ввод для command2.
Перенаправление stdout в один файл, stderr - в другой:
command > output.txt 2>&1 | tee error.txt 
# Эта команда перенаправляет stdout в файл output.txt и объединяет stderr с stdout, 
# который затем выводится в консоль и записывается в файл error.txt с помощью утилиты tee.
Перенаправление только stderr в пайп:
command 2>&1 | grep "error"  
# Здесь stderr команды command перенаправляется в тот же поток, что и stdout,
# и затем передается через пайп команде grep для поиска строк с "error".
Перенаправление stdout и stderr в пайп и файл:
command > output.txt 2>&1 | tee error.txt
# В этом примере stdout будет перенаправлен в файл output.txt, а stderr будет объединен с stdout,
# затем через tee будет выведен на экран и записан в файл error.txt.

Полезная статья про перенаправление открытых дескрипторов.