Конвейер (Unix)
В Unix-подобных компьютерных операционных системах конвейер — это механизм межпроцессного взаимодействия с использованием передачи сообщений. Конвейер — это набор процессов, связанных вместе своими стандартными потоками , так что выходной текст каждого процесса ( stdout ) передается непосредственно в качестве входных данных ( stdin ) следующему. Второй процесс запускается, поскольку первый процесс все еще выполняется, и они выполняются одновременно .
Концепция конвейеров была поддержана Дугласом Макилроем в , , прародине Unix Bell Labs во время разработки Unix, формируя философию ее набора инструментов . Он назван по аналогии с физическим конвейером . Ключевой особенностью этих конвейеров является «скрытие внутренних компонентов». Это, в свою очередь, обеспечивает большую ясность и простоту системы.
Каналы ), где данные, записанные одним процессом , в конвейере являются анонимными каналами (в отличие от именованных каналов буферизуются операционной системой до тех пор, пока они не будут прочитаны следующим процессом, и этот однонаправленный канал исчезает после завершения процессов. Стандартный синтаксис оболочки для анонимных каналов состоит в перечислении нескольких команд, разделенных вертикальными чертами (« каналы » в обычном словоблудии Unix).
История
[ редактировать ]Концепцию трубопровода придумал Дуглас Макилрой. [1] и впервые описан на страницах руководства Unix версии 3 . [2] [3] большую часть времени Макилрой заметил, что командные оболочки передают выходной файл одной программы в качестве входных данных для другой. Концепция конвейеров была поддержана Дугласом Макилроем в , , прародине Unix Bell Labs во время разработки Unix, формируя философию ее набора инструментов . [4] [5]
Его идеи были реализованы в 1973 году, когда («в одну лихорадочную ночь», как писал Макилрой) Кен Томпсон добавил pipe()
системный вызов и каналы к оболочке и несколько утилит в версии 3 Unix. «На следующий день, — продолжал Макилрой, — мы увидели незабываемую оргию острот, когда все присоединились к восторгу от сантехнических работ». Макилрой также приписывает Томпсону |
нотации, что значительно упростило описание синтаксиса канала в Версии 4 . [6] [2]
Несмотря на то, что каналы Unix разработаны независимо, они связаны с «коммуникационными файлами», разработанными Кеном Лохнером, и им предшествовали. [7] в 1960-х годах для Дартмутской системы разделения времени . [8]
Другие операционные системы
[ редактировать ]Эта функция Unix была заимствована другими операционными системами, такими как MS-DOS и пакетом CMS Pipelines на VM/CMS и MVS , и в конечном итоге стала называться шаблоном проектирования каналов и фильтров разработки программного обеспечения .
Дальнейшее развитие концепции
[ редактировать ]В (CSP) Тони Хоара последовательных процессах связи каналы Макилроя получили дальнейшее развитие. [9]
Выполнение
[ редактировать ]Механизм конвейера используется для межпроцессного взаимодействия с использованием передачи сообщений. Конвейер — это набор процессов, связанных вместе своими стандартными потоками , так что выходной текст каждого процесса ( stdout ) передается непосредственно в качестве входных данных ( stdin ) следующему. Второй процесс запускается, поскольку первый процесс все еще выполняется, и они выполняются одновременно . Он назван по аналогии с физическим конвейером . Ключевой особенностью этих конвейеров является «скрытие внутренних компонентов». [10] Это, в свою очередь, обеспечивает большую ясность и простоту системы.
В большинстве Unix-подобных систем все процессы конвейера запускаются одновременно, их потоки соответствующим образом связаны и управляются планировщиком вместе со всеми другими процессами, выполняемыми на машине. Важным аспектом этого, отличающим каналы Unix от других реализаций каналов, является концепция буферизации : например, передающая программа может выдавать 5000 байт в секунду , а принимающая программа может принимать только 100 байт в секунду, но не данные потеряны. Вместо этого выходные данные отправляющей программы сохраняются в буфере. Когда принимающая программа готова прочитать данные, следующая программа в конвейере считывает данные из буфера. Если буфер заполнен, программа-отправитель останавливается (блокируется) до тех пор, пока получатель не удалит из буфера хотя бы часть данных. В Linux размер буфера составляет 65 536 байт (64 КБ). Доступен сторонний фильтр с открытым исходным кодом под названием bfr, который при необходимости обеспечивает буферы большего размера.
Сетевые трубы
[ редактировать ]Такие инструменты, как netcat и socat, могут подключать каналы к сокетам TCP/IP .
Конвейеры в интерфейсах командной строки
[ редактировать ]
Все широко используемые оболочки Unix имеют специальную синтаксическую конструкцию для создания конвейеров. При любом использовании команды записываются последовательно, разделенные ASCII . вертикальной чертой |
(который по этой причине часто называют «персонажем трубы»). Оболочка запускает процессы и организует необходимые соединения между их стандартными потоками (включая некоторый объем буферной памяти).
Конвейер использует анонимные каналы . Для анонимных каналов данные, записанные одним процессом, буферизуются операционной системой до тех пор, пока они не будут прочитаны следующим процессом, и этот однонаправленный канал исчезает после завершения процессов; это отличается от именованных каналов , где сообщения передаются в канал или из канала, которому присвоено имя путем создания файла, и остаются после завершения процессов. Стандартный синтаксис оболочки для анонимных каналов состоит в перечислении нескольких команд, разделенных вертикальными чертами («каналы» в обычном словоблудии Unix):
command1 | command2 | command3
Например, чтобы вывести список файлов в текущем каталоге ( ls ), сохраняют только строки вывод ls , содержащий строку "ключ" ( grep ) и просмотреть результат на странице с прокруткой ( less ), пользователь вводит в командную строку терминала следующее:
ls -l | grep key | less
Команда ls -l
выполняется как процесс, выходные данные (stdout) которого передаются по конвейеру на вход (stdin) процесса для grep key
; и то же самое для процесса less
. Каждый процесс принимает входные данные от предыдущего процесса и создает выходные данные для следующего процесса через стандартные потоки . Каждый |
сообщает оболочке о необходимости соединить стандартный вывод команды слева со стандартным вводом команды справа с помощью механизма межпроцессного взаимодействия , называемого (анонимным) каналом , реализованного в операционной системе. Трубы однонаправленные; данные проходят по конвейеру слева направо.
Пример
[ редактировать ]Ниже приведен пример конвейера, реализующего своего рода проверку орфографии для веб- ресурса, указанного URL-адресом . Ниже приводится объяснение того, что он делает.
curl "https://en.wikipedia.org/wiki/Pipeline_(Unix)" |
sed 's/[^a-zA-Z ]/ /g' |
tr 'A-Z ' 'a-z\n' |
grep '[a-z]' |
sort -u |
comm -23 - <(sort /usr/share/dict/words) |
less
curl
получает HTML- содержимое веб-страницы (можно использоватьwget
в некоторых системах).sed
заменяет все символы (из содержимого веб-страницы), не являющиеся пробелами или буквами, на пробелы. ( Новые строки сохраняются.)tr
меняет все прописные буквы на строчные и преобразует пробелы в строках текста в символы новой строки (каждое «слово» теперь находится на отдельной строке).grep
включает только строки, содержащие хотя бы один строчный буквенный символ (все пустые строки удаляются).sort
сортирует список «слов» в алфавитном порядке, а-u
переключатель удаляет дубликаты.comm
находит общие строки между двумя файлами,-23
подавляет строки, уникальные для второго файла, а также те, которые являются общими для обоих, оставляя только те, которые встречаются только в первом названном файле.-
вместо имени файла вызываетcomm
использовать его стандартный ввод (в данном случае из трубопровода).sort /usr/share/dict/words
сортирует содержимоеwords
файл в алфавитном порядке, какcomm
ожидает, и<( ... )
выводит результаты во временный файл (через подстановку процесса ), которыйcomm
читает. Результатом является список слов (строк), которых нет в /usr/share/dict/words.less
позволяет пользователю пролистывать результаты.
Поток ошибок
[ редактировать ]По умолчанию стандартные потоки ошибок (« stderr ») процессов в конвейере не передаются через канал; вместо этого они объединяются и направляются на консоль . Однако многие оболочки имеют дополнительный синтаксис для изменения этого поведения. в оболочке csh , используя Например, |&
вместо |
означает, что стандартный поток ошибок также должен быть объединен со стандартным выводом и передан следующему процессу. Оболочка Bash также может объединять стандартные ошибки с |&
начиная с версии 4.0 [11] или используя 2>&1
, а также перенаправить его в другой файл.
Трубный завод
[ редактировать ]В наиболее часто используемых простых конвейерах оболочка соединяет ряд подпроцессов через каналы и выполняет внешние команды внутри каждого подпроцесса. Таким образом, сама оболочка не выполняет прямую обработку данных, проходящих через конвейер.
Однако оболочка может выполнять обработку напрямую, используя так называемую мельницу или трубную мельницу (поскольку while
используется для «обработки» результатов исходной команды). Обычно эта конструкция выглядит примерно так:
command | while read -r var1 var2 ...; do
# process each line, using variables as parsed into var1, var2, etc
# (note that this may be a subshell: var1, var2 etc will not be available
# after the while loop terminates; some shells, such as zsh and newer
# versions of Korn shell, process the commands to the left of the pipe
# operator in a subshell)
done
Такая конвейерная мельница может работать не так, как предполагалось, если тело цикла содержит такие команды, как cat
и ssh
, который прочитал из stdin
: [12] на первой итерации цикла такая программа (назовем ее стоком ) прочитает оставшийся вывод из command
, после чего цикл завершится (результаты зависят от особенностей стока). Есть несколько возможных способов избежать такого поведения. Во-первых, некоторые стоки поддерживают возможность отключения чтения из stdin
(например ssh -n
). В качестве альтернативы, если стоку не нужно читать какие-либо входные данные из stdin
чтобы сделать что-то полезное, это можно дать < /dev/null
в качестве ввода.
Поскольку все компоненты канала выполняются параллельно, оболочка обычно создает подпроцесс (подоболочку) для обработки его содержимого, что делает невозможным распространение изменений переменных во внешнюю среду оболочки. Чтобы решить эту проблему, вместо этого «pipemill» может быть загружен из документа here, содержащего команду замены , которая ожидает завершения работы конвейера, прежде чем перерабатывать содержимое. В качестве альтернативы именованный канал или подстановку процесса для параллельного выполнения можно использовать . GNU bash также имеет lastpipe
возможность отключить разветвление для последнего компонента трубы. [13]
Программное создание конвейеров
[ редактировать ]Конвейеры могут создаваться под управлением программы. Юникс pipe()
системный вызов просит операционную систему создать новый объект анонимного канала . В результате в процессе появляются два новых открытых файловых дескриптора: конец канала, доступный только для чтения, и конец канала, доступный только для записи. Концы канала кажутся обычными анонимными файловыми дескрипторами , за исключением того, что у них нет возможности поиска.
Чтобы избежать тупиковой ситуации и использования параллелизма, процесс Unix с одним или несколькими новыми каналами обычно вызывает fork()
создавать новые процессы. Затем каждый процесс закроет конец(а) канала, который он не будет использовать, перед созданием или потреблением каких-либо данных. Альтернативно, процесс может создавать новые потоки и использовать канал для связи между ними.
Именованные каналы также могут быть созданы с помощью mkfifo()
или mknod()
а затем представляется в качестве входного или выходного файла программам при их вызове. Они позволяют создавать многопутевые каналы и особенно эффективны в сочетании со стандартным перенаправлением ошибок или с tee
.
Популярная культура
[ редактировать ]Робот на значке Apple Automator , который также использует концепцию конвейера для объединения повторяющихся команд, представляет собой дань уважения оригинальной концепции Unix.
См. также
[ редактировать ]- Все есть файл – описывает одну из определяющих особенностей Unix; конвейеры действуют на «файлы» в смысле Unix
- Анонимный канал — структура FIFO, используемая для межпроцессного взаимодействия.
- GStreamer — мультимедийная платформа на основе конвейера
- Конвейеры CMS
- итеративный
- Именованный канал – постоянные каналы, используемые для межпроцессного взаимодействия.
- Подмена процесса — синтаксис оболочки для подключения нескольких каналов к процессу.
- GNU-параллель
- Конвейер (вычисления) - другие конвейеры, связанные с компьютером.
- Перенаправление (вычисления)
- Tee (команда) – общая команда для получения данных из конвейера.
- XML-конвейер – для обработки XML-файлов.
- xargs
Ссылки
[ редактировать ]- ^ «Создание операционной системы UNIX» . Лаборатории Белла. Архивировано из оригинала 14 сентября 2004 года.
- ^ Jump up to: а б Макилрой, доктор медицины (1987). Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (Технический отчет). CSTR. Лаборатории Белла. 139.
- ^ Томпсон К. , Ричи Д.М. (февраль 1973 г.). Руководство программиста UNIX, третье издание (PDF) (технический отчет) (3-е изд.). Лаборатории Белла. п. 178.
- ^ Махони, Майкл С. «Проект устной истории Unix: Release.0, Начало» .
Макилрой: Это было одно из немногих мест, где я практически осуществлял управленческий контроль над Unix, давил на эти вещи, да.
- ^ «Пророческие петроглифы» . www.bell-labs.com . Архивировано из оригинала 8 мая 1999 года . Проверено 22 мая 2022 г.
- ^ «Трубы: Краткое введение» . Информационный проект Linux. 23 августа 2006 г. [Создано 29 апреля 2004 г.] . Проверено 7 января 2024 г.
- ^ «Дартмутское разделение времени» (DOC) . Рочестерский технологический институт . Проверено 7 января 2024 г.
- ^ "Данные" . www.bell-labs.com . Архивировано из оригинала 20 февраля 1999 года . Проверено 22 мая 2022 г.
- ^ Кокс, Расс. «Лаборатории Bell и темы CSP» . Распределительный щит . Проверено 7 января 2024 г.
- ^ Ричи и Томпсон, 1974 г.
- ^ «Примечания к выпуску Bash» . tiswww.case.edu . Проверено 14 июня 2017 г.
- ^ «Взаимодействие цикла оболочки с SSH» . 6 марта 2012 г. Архивировано из оригинала 6 марта 2012 г.
- ^ Джон1024. «Как сохранить результаты команды «найти» в виде массива в Bash» . Переполнение стека .
{{cite web}}
: CS1 maint: числовые имена: список авторов ( ссылка )
- Сал Согоян в MacBreak, эпизод 3 «Enter the Automatrix»
Внешние ссылки
[ редактировать ]- История обозначения каналов Unix. Архивировано 8 апреля 2015 г. на Wayback Machine.
- Оригинальная записка Дуга Макилроя 1964 года , в которой впервые предлагается концепция трубки.
- Единая спецификация UNIX , версия 4 от The Open Group : создать межпроцессный канал — Справочник по системным интерфейсам,
- Pipes: краткое введение от Linux Information Project (LINFO)
- Unix Pipes – мощная и элегантная парадигма программирования (Softpanorama)
- Специальный анализ данных из командной строки Unix в Wikibooks — показывает, как использовать конвейеры, состоящие из простых фильтров, для выполнения сложного анализа данных.
- Использование и злоупотребление каналами с аудиоданными — знакомит с использованием и злоупотреблением каналами с netcat, nettee и fifos для воспроизведения звука по сети.
- stackoverflow.com — вопросы и ответы об обработке конвейера bash.