pipe linux что это

Что такое каналы (pipe) в Linux? Как работает перенаправление каналов?

Главное меню » Linux » Что такое каналы (pipe) в Linux? Как работает перенаправление каналов?

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

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

Но знаете ли вы, что под ним? Как на самом деле работает перенаправление каналов?

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

Примечание. Мы использовали термин Unix в некоторых местах, потому что концепция каналов (как и многие другие вещи в Linux) происходит от Unix.

Каналы в Linux: общая идея

Вот что вы повсюду увидите относительно «что такое каналы в Unix?»:

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

Намного лучше. Удаление абстракции сделало его намного чище и точнее. Вы можете посмотреть на следующую схему, чтобы понять, как работает pipe.

Один из простейших примеров команды pipe – передать некоторый вывод команды команде grep для поиска определенной строки.

Имейте в виду: Pipe перенаправляет стандартный вывод на стандартный ввод, но не как аргумент команды

Очень важно понять, что конвейер передает команду stdout другой команде stdin, но не как аргумент команды. Мы объясним это на примере.

Если вы используете команду cat без аргументов, по умолчанию будет выполняться чтение из stdin. Вот пример:

Здесь мы использовали cat без передачи файлов, поэтому по умолчанию stdin. Затем мы написали строку, а затем использовал Ctrl + d, чтобы сообщить, что закончили писать (Ctrl + d подразумевает EOF или конец файла). Как только мы закончили писать, cat прочитал stdin и написал эту строку в stdout.

Теперь рассмотрим следующую команду:

Вторая команда НЕ эквивалентна cat hey. Здесь stdout”hey” переносится в буфер и передает stdin в cat. Поскольку аргументов командной строки не было, cat по умолчанию выбрал stdin для чтения, а что-то уже было в stdin, поэтому команда cat приняла это и напечатала stdout.

Фактически, мы создали файл с именем hey и поместили в него некоторый контент.

Типы каналов в Linux

В Linux есть два типа каналов:

Каналы без названия

Без названия каналы, как следует из названия, не имеют имени. Они создаются на лету вашей оболочкой Unix всякий раз, когда вы используете символ |.

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

Именованные каналы

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

Это создаст файл с именем «pipe». Выполните следующую команду:

Обратите внимание на «p» в начале, это означает, что файл является каналом. Теперь воспользуемся этим каналом.

Как мы говорили ранее, конвейер пересылает вывод одной команды на вход другой. Это как курьерская служба, вы даете посылку доставить с одного адреса, а они доставляют по другому. Итак, первый шаг – предоставить пакет, то есть предоставить каналу что-то.

Вы заметите, что echo еще не вернули нам терминал. Откройте новый терминал и попробуйте прочитать из этого файла.

Обе эти команды завершили свое выполнение одновременно.

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

Зачем использовать именованные каналы? Вот список того, почему вы хотите использовать именованные каналы

Именованные каналы не занимают память на диске

Сниженный ввод-вывод

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

Связь между двумя очень разными процессами

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

Понимание каналов более низкого уровня [для опытных пользователей и разработчиков]

В следующем разделе речь идет о каналах на более глубоком уровне с фактическими реализациями. Этот раздел требует от вас базового понимания:

Мы не будем вдаваться в подробности примеров. Речь идет только о «каналах». Для большинства пользователей Linux этот раздел не нужен.

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

Рассмотрим следующий пример программы:

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

Это потому, что канал – это не что иное, как массив из двух целых чисел без знака, представляющих два файловых дескриптора. Один для письма, один для чтения. И оба они указывают на расположение буфера в памяти, которое обычно составляет 1 МБ.

Здесь мы назвали переменную fd. fd [0] – дескриптор входного файла, fd [1] – дескриптор выходного файла. В этой программе один процесс записывает строку в файловый дескриптор fd [1], а другой процесс читает из файлового дескриптора fd [0].

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

Вот пример программы, которая делает то же самое, что и предыдущая программа, но вместо анонимного канала создает именованный канал.

Здесь мы использовали системный вызов mknod для создания именованного канала. Как вы можете видеть, хотя мы удалили канал по завершении, вы вполне можете оставить его и легко использовать для связи между различными программами, просто открыв и записав в файл с именем «npipe» в моем случае.

Вам также не придется создавать два разных канала для двусторонней связи, как в случае с анонимными каналами.

Вот образец Makefile, как и было обещано. Поместите его в тот же каталог, что и предыдущие программы, с именами «pipe.c» и «fifo.c» соответственно.

Вот так. Это действительно все, что есть в каналах Unix.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Источник

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

Простым примером перенаправления является pipe (конвейер). Обозначается он символом | (прямая палочка, кто не понял 🙂 ). Используется pipe следующим образом:

При таком вызове все данные, которые при обычном запуске команды 1 выводились бы на экран будут поступать на стандартный ввод команды 2, как будто бы мы вводим эти данные с клавиатуры.

Что очень важно отметить, команды исполняются одновременно, то есть все, что поступает на вывод в первой программе немедленно поступает на вход второй, не дожидаясь завершения 1.

Если проводить ассоциации с реальным миром, то можно представить pipe в виде длинной трубы, распооженной вертикально (что-то мне подсказывает, что разработчики системы преставляли себе это именно также, потому и выбрали такое название и символ |). В эту трубу некто (команда 1) сверху кидает яблоки (данные). Второй некто (команда 2) достает из трубы эти яблоки. Ширина трубы не позволяет яблакам менять порядок, то есть в каком порядке они были отправлены командой 1, в таком порядке они будут приняты командой 2. Скорости работы команд также могут различаться. В случаи, если второй некто замешкается, яблоки будут оставаться в трубе, дожидаясь обработки. Если замешкается первый, то второй будет ждать поступления данных.

Пожалуй, это все, что можно сказать про конвейер в Linux.

Источник

Pipes: Программные каналы в Linux

Статья из цикла HuMan

Выбор термина

Предисловие

Предлагаемая вашему вниманию статья как раз для тех, кто недавно открыл для себя командную строку Линукс.

Введение в программные каналы

Того же результата можно достичь, если сначала перенаправить вывод команды dmesg во временный файл, а затем просмотреть содержимое этого файла на экране монитора.

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

Необходимо пояснить понятия, которые я походя назвал «вводом» и «выводом» программы.

Любая программа командной оболочки (шелла) оперирует с тремя потоками данных: стандартным вводом (stdin), стандартным выводом (stdout), и стандартным сообщением об ошибке (stderr). (Подробно об этом можно прочесть в статье «Перенаправление стандартных потоков данных»).

Такая цепочка вовсе не ограничивается двумя программами, но может продолжаться сколь угодно долго.

Как это работает

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

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

Как пользоваться программными каналами

Для пробы проделайте такой пример:

Понятно, что найти «вручную» что-либо в таком списке проблематично, и тут на помощь снова придут программные каналы.

Команда grep найдет нужные вам строки, если вы зададите образец для поиска:

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

Среди команд-фильтров самая употребительная, без сомнения, grep. Она применяется везде, где нужно выбрать искомое из большого объема данных. Скажем, просмотреть все, что касается USB в выводе команды dmesg:

Чтобы найти в этом списке интересующие вас процессы, следует канализировать команду ps с командой grep. Допустим, вас интересуют процессы hald:

С таким коротким списком уже легче работать. (Обратите внимание на последнюю строчку, там представлен сам запущенный нами процесс grep hald ).

Другие распространенные команды-фильтры

В этот список я включил только несколько команд-фильтров, освоив которые, можно вдоволь насладиться составлением самых замысловатых программных каналов.

Сложные программные каналы

Примечание: Символ (\) используется для объединения всех шести строк в одну командную строку.

Команда первая: wget получает содержимое HTML web страницы.

Команда вторая: sed удаляет из текста страницы все символы, не являющиеся пробелами или буквами и заменяет их пробелами.

Команда третья: tr переводит все символы верхнего регистра в нижний регистр (заглавные буквы в строчные), а также конвертирует пробелы в строках в символы новой строки, так что теперь каждое «слово» является новой строкой.

Команда четвертая: grep оставляет только строки, содержащие хотя бы один алфавитный символ (попросту букву), удаляя все пустые строки.

Немного истории

Понятие именованного канала

В отличие от анонимного программного канала, автоматически создаваемого шеллом, именованный канал обладает именем, и создается явно при помощи команд mknod или mkfifo. Создадим именованный канал fifo1:

Теперь запустим процесс, обращающийся к данному каналу:

Несмотря на нажатие клавиши ENTER ничего не происходит, что не удивительно, ведь файл fifo1 пока пуст, и команде grep нечего обрабатывать. Однако консоль оказывается занята ждущим процессом, и разблокировать ее можно только прервав процесс (скажем, нажатием клавиш CTRL+c).

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

Немедленно в первой консоли сработает команда grep:

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

и получить тот же результат.

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

Источник

Команда Pipe, Grep и Sort в Linux / Unix с примерами

Что такое пайп в Linux?

Pipe — это команда в Linux, которая позволяет вам использовать две или более команд, так что вывод одной команды служит вводом для следующей. Короче говоря, вывод каждого процесса непосредственно в качестве ввода для следующего, как конвейер.

Символ ‘|’ обозначает трубу.

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

Давайте разберемся в этом на примере.

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

Чтобы избежать этого, вы можете перенаправить вывод команды ‘cat’ в ‘less’, что покажет вам только одну длину прокрутки содержимого за раз.

cat filename | less

Иллюстрация прояснила бы это:

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Команды ‘pg’ и ‘more’

Вместо «меньше» можно также использовать.

И вы можете просмотреть файл в удобоваримых битах и ​​прокрутить вниз, просто нажав клавишу ввода.

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Команда ‘grep’

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

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

Синтаксис:

Посмотрим на это в действии:

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Здесь команда grep провела поиск в файле «sample» по строке «Apple» и «Eat».

С этой командой можно использовать следующие параметры.

ВариантФункция
-vПоказывает все строки, которые не соответствуют искомой строке
-cОтображает только количество совпадающих строк
-nПоказывает соответствующую строку и ее номер
-iУчитывать оба регистра (верхний и нижний)
-lПоказывает только имя файла со строкой

Давайте попробуем первый вариант ‘-i’ для того же файла, использованного выше —

Используя параметр «i», grep отфильтровал строку «a» (без учета регистра) из всех строк.

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Команда sort

Эта команда помогает отсортировать содержимое файла по алфавиту.

Синтаксис этой команды:

Рассмотрим содержимое файла.

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Использование команды сортировки

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

ВариантФункция
Обратная сортировка
-nСортировка численно
-fСортировка без учета регистра

Пример ниже показывает обратную сортировку содержимого в файле «abc».

Linux / Unix конвейеры, команда Grep & Sort

Что такое фильтр?

В Linux есть множество команд фильтрации, таких как awk, grep, sed, spell и wc. Фильтр принимает входные данные от одной команды, выполняет некоторую обработку и выдает выходные данные.

Когда вы передаете две команды по конвейеру, «отфильтрованный» вывод первой команды передается следующей.

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Давайте разберемся в этом на примере.

У нас есть следующий файл ‘sample’

pipe linux что это. Смотреть фото pipe linux что это. Смотреть картинку pipe linux что это. Картинка про pipe linux что это. Фото pipe linux что это

Мы хотим выделить только те строки, которые не содержат символа «а», но результат должен быть в обратном порядке.

Для этого можно использовать следующий синтаксис.

Источник

Linux pipes tips & tricks

Pipe — что это?

Pipe (конвеер) – это однонаправленный канал межпроцессного взаимодействия. Термин был придуман Дугласом Макилроем для командной оболочки Unix и назван по аналогии с трубопроводом. Конвейеры чаще всего используются в shell-скриптах для связи нескольких команд путем перенаправления вывода одной команды (stdout) на вход (stdin) последующей, используя символ конвеера ‘|’:

grep выполняет регистронезависимый поиск строки “error” в файле log, но результат поиска не выводится на экран, а перенаправляется на вход (stdin) команды wc, которая в свою очередь выполняет подсчет количества строк.

Логика

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

Размер буфера начиная с ядра версии 2.6.11 составляет 65536 байт (64Кб) и равен странице памяти в более старых ядрах. При попытке чтения из пустого буфера процесс чтения блокируется до появления данных. Аналогично при попытке записи в заполненный буфер процесс записи будет заблокирован до освобождения необходимого места.
Важно, что несмотря на то, что конвейер оперирует файловыми дескрипторами потоков ввода/вывода, все операции выполняются в памяти, без нагрузки на диск.
Вся информация, приведенная ниже, касается оболочки bash-4.2 и ядра 3.10.10.

Простой дебаг

Исходный код, уровень 1, shell

Т. к. лучшая документация — исходный код, обратимся к нему. Bash использует Yacc для парсинга входных команд и возвращает ‘command_connect()’, когда встречает символ ‘|’.
parse.y:
Также здесь мы видим обработку пары символов ‘|&’, что эквивалентно перенаправлению как stdout, так и stderr в конвеер. Далее обратимся к command_connect():make_cmd.c:
где connector это символ ‘|’ как int. При выполнении последовательности команд (связанных через ‘&’, ‘|’, ‘;’, и т. д.) вызывается execute_connection():execute_cmd.c:

PIPE_IN и PIPE_OUT — файловые дескрипторы, содержащие информацию о входном и выходном потоках. Они могут принимать значение NO_PIPE, которое означает, что I/O является stdin/stdout.
execute_pipeline() довольно объемная функция, имплементация которой содержится в execute_cmd.c. Мы рассмотрим наиболее интересные для нас части.
execute_cmd.c:
Таким образом, bash обрабатывает символ конвейера путем системного вызова pipe() для каждого встретившегося символа ‘|’ и выполняет каждую команду в отдельном процессе с использованием соответствующих файловых дескрипторов в качестве входного и выходного потоков.

Исходный код, уровень 2, ядро

Обратимся к коду ядра и посмотрим на имплементацию функции pipe(). В статье рассматривается ядро версии 3.10.10 stable.
fs/pipe.c (пропущены незначительные для данной статьи участки кода):
Если вы обратили внимание, в коде идет проверка на флаг O_NONBLOCK. Его можно выставить используя операцию F_SETFL в fcntl. Он отвечает за переход в режим без блокировки I/O потоков в конвеере. В этом режиме вместо блокировки процесс чтения/записи в поток будет завершаться с errno кодом EAGAIN.

Максимальный размер блока данных, который будет записан в конвейер, равен одной странице памяти (4Кб) для архитектуры arm:
arch/arm/include/asm/limits.h:
Для ядер >= 2.6.35 можно изменить размер буфера конвейера:
Максимально допустимый размер буфера, как мы видели выше, указан в файле /proc/sys/fs/pipe-max-size.

Tips & trics

Перенаправление и stdout, и stderr в pipe

или же можно использовать комбинацию символов ‘|&’ (о ней можно узнать как из документации к оболочке (man bash), так и из исходников выше, где мы разбирали Yacc парсер bash):

Перенаправление _только_ stderr в pipe

Shoot yourself in the foot
Важно соблюдать порядок перенаправления stdout и stderr. Например, комбинация ‘>/dev/null 2>&1′ перенаправит и stdout, и stderr в /dev/null.

Получение корректного кода завершения конвейра

По умолчанию, код завершения конвейера — код завершения последней команды в конвеере. Например, возьмем исходную команду, которая завершается с ненулевым кодом:
И поместим ее в pipe:
Теперь код завершения конвейера — это код завершения команды wc, т.е. 0.

Обычно же нам нужно знать, если в процессе выполнения конвейера произошла ошибка. Для этого следует выставить опцию pipefail, которая указывает оболочке, что код завершения конвейера будет совпадать с первым ненулевым кодом завершения одной из команд конвейера или же нулю в случае, если все команды завершились корректно:
Shoot yourself in the foot
Следует иметь в виду “безобидные” команды, которые могут вернуть не ноль. Это касается не только работы с конвейерами. Например, рассмотрим пример с grep:
Здесь мы печатаем все найденные строки, приписав ‘new_’ в начале каждой строки, либо не печатаем ничего, если ни одной строки нужного формата не нашлось. Проблема в том, что grep завершается с кодом 1, если не было найдено ни одного совпадения, поэтому если в нашем скрипте выставлена опция pipefail, этот пример завершится с кодом 1:
В больших скриптах со сложными конструкциями и длинными конвеерами можно упустить этот момент из виду, что может привести к некорректным результатам.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *