На потребительском конце именованного канала (FIFO) есть ли способ выделить guish каждого элемента и перенаправить его на собственные процессы? - PullRequest
0 голосов
/ 02 мая 2020

Лучшее, что я могу объяснить, - это пример.

  1. Создание именованного канала: mkfifo pipe
  2. Создание 5 текстовых файлов, a.txt, b.txt, c.txt , d.txt, e.txt (они могут содержать любое содержимое для этого примера)
  3. cat [a-e].txt > pipe

Конечно, поскольку канал не открыт на стороне потребителя, терминал будет казаться занятым.

В другом терминале, tail -fn +1 pipe

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

Но вместо простой распечатки контента Я хотел бы, чтобы каждый переданный по конвейеру текстовый файл перенаправлялся в команду (5 отдельных процессов), которая может обрабатывать только по одному за раз:

Что-то вроде python some-script.py < pipe, но где он будет создавать 5 разных экземпляров (один Экземпляр на содержание текстового файла).

Есть ли у потребителя возможность различать входящие объекты? Или данные добавляются и читаются как один поток?

1 Ответ

0 голосов
/ 04 мая 2020

Потенциальное решение, которое может быть в целом применимо (с нетерпением ждем возможности услышать, если есть более эффективные альтернативы.

Во-первых, пример python сценария, который описывает вопрос:

some- script.py:

import sys

lines = sys.stdin.readlines()
print('>>>START-OF-STDIN<<<')
print(''.join(lines))
print('>>>END-OF-STDIN<<<')

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

Пример производителей:

cat a.txt | echo $(base64 -w 0) | cat > pipe &
cat b.txt | echo $(base64 -w 0) | cat > pipe &
cat c.txt | echo $(base64 -w 0) | cat > pipe &
cat d.txt | echo $(base64 -w 0) | cat > pipe &
cat e.txt | echo $(base64 -w 0) | cat > pipe &

Описание производителей:

  • cat объединяет весь файл, а затем передает в echo
  • echo, отображает текст, полученный из подкоманды $(base64 -w 0), и передает в cat
  • base64 -w 0 кодирует все содержимое файла в одну строку
  • cat, используемую в этом случае, объединяет полную строку перед перенаправлением вывода в канал. Без этого потребитель не ' не работает должным образом (попробуйте сами)

Пример потребителя:

tail -fn +1 pipe | while read line ; do (echo $line | base64 -d | cat | python some-script.py) ; done

Описание потребителя:

  • tail -fn +1 pipe следует (-f) по трубе с начала (-n +1) с После завершения процесса и передачи содержимого в read в пределах while l oop
  • , в то время как есть строки для чтения (при условии, что закодированы base64 одиночные строки, поступающие от производителей), каждая строка передается в подпрограмму -shell
  • В каждом подоболочке
  • echo передает линию в base64 -d (-d обозначает декодирование)
  • base64 -d передает в декодированную строку (которая теперь может занимать несколько строк) до cat
  • cat объединяет строки и направляет их как одну к python some-script.py
  • Наконец, пример сценария python может читать строки строка точно таким же образом, как cat example.txt | python some-script.py

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

Пример команды Docker, включающей символы канала, et c:

"bash -c 'tail -fn +1 pipe | while read line ; do (echo $line | base64 -d | cat | python some-script.py) ; done'"

...