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

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

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

Два варианта использования вчерашнего дня:

  1. Мне хотелось увидеть субъекты нескольких SSL-сертификатов, объединенных в PEM-файл.

     cat mypemfile.crt |
     (openssl x509 -noout -text | fgrep Subject:)
    

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

    Почему я просто не могу сказать

     cat mypemfile.crt |
     csplit-tee '/BEGIN/ .. /END/' |
     on-each ( openssl x509 -noout -text | fgrep Subject: ) |
     merge --cat
    

    ?

  2. Мы запускаем экземпляр JupyterHub, который разделяет серверы блокнотов как контейнеры Docker. Я хочу посмотреть их журналы с временными метками. Это достаточно просто для одного контейнера:

     sudo docker logs -t -f $container_id
    

    ( -tДобавляет временную метку и оставляет -fканал открытым, например tail -f.)

    Достаточно просто составить список журналов всех контейнеров, отсортированных по временным меткам:

     sudo docker ps | awk '{print $1}' |
     while read container_id
     do
       sudo docker logs -t $container_id
     done |
     sort
    

    или

     sudo docker ps | awk '{print $1}' |
     xargs -n1 sudo docker logs -t |
     sort
    

    или

     sudo docker ps | awk '{print $1}' |
     parallel sudo docker logs -t {} |
     sort
    

    но ничто из этого не позволит мне использовать -fвозможность просмотра журналов по мере их поступления.

    Почему я не могу просто использовать

     sudo docker ps | awk '{print $1}' |
     csplit-tee /./ |
     on-each (xargs echo | sudo docker logs -t -f) |
     merge --line-by-line --lexicographically
    

    или

     sudo docker ps | awk '{print $1}' |
     parallel --multipipe sudo docker logs -t -f {} |
     merge --line-by-line --lexicographically
    

    ?

Очевидно, что для этого необходимо

  1. Специфическая поддержка оболочки. Возможно, нам понадобится отдельный символ "многоканальный".
  2. Новые инструменты ( csplit-tee, on-eachи merge), которые разделяют и объединяют конвейеры.
  3. Фиксированное соглашение о том, как указать в инструментах произвольное количество дескрипторов входных и выходных файлов, чтобы эта оболочка воспринимала их как параллельные конвейеры.

Было ли это сделано? Или что-то эквивалентное, что я могу применить к своим вариантам использования?

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

Осуществимо ли это, зная, чтоGNU-параллельосуществимо?

решение1

С помощью GNU Parallel:

cat mypemfile.crt |
  parallel --pipe -N1 --recstart '-----BEGIN' 'openssl x509 -noout -text | fgrep Subject:'

Непроверено:

sudo docker ps | awk '{print $1}' |
  sudo parallel -j0 --lb docker logs -t -f {}

sudo docker ps | awk '{print $1}' |
  sudo parallel -j0 --tag --lb docker logs -t -f {}

решение2

Нет, оболочка не может этого сделать. Труба — это просто поток от источника к месту назначения, обычно в разных процессах.

Давайте рассмотрим ваш первый пример:

cat mypemfile.crt |
(openssl x509 -noout -text | fgrep Subject:)

Вы хотите, чтобы входной файл был разделен по строкам, содержащим BEGIN и END, но catне заботитесь о содержимом, а каналы в любом случае не имеют индикации выхода за пределы разделителей записей.

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

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

Связанный контент