Предположим, у вас есть конвейер, подобный следующему:
$ a | b
Если b
остановка обработки stdin, через некоторое время канал заполняется, и запись, начиная a
с его stdout, будет блокироваться (пока либо не b
начнется обработка снова, либо он не умрет).
Если бы я хотел избежать этого, у меня мог бы возникнуть соблазн использовать более крупную трубу (или, проще, buffer(1)
) следующим образом:
$ a | buffer | b
Это просто выиграет мне больше времени, но в конце a
концов остановится.
Что я хотел бы иметь (для очень специфического сценария, к которому я обращаюсь), так это иметь «негерметичный» канал, который при заполнении удалял бы некоторые данные (в идеале построчно) из буфера, чтобы позволить a
продолжить обработка (как вы, вероятно, можете себе представить, данные, которые передаются по конвейеру, являются расходуемыми, т. е. обработка данных b
менее важна, чем a
возможность работать без блокировки).
Подводя итог, я хотел бы иметь что-то вроде ограниченного, протекающего буфера:
$ a | leakybuffer | b
Я мог бы реализовать это довольно легко на любом языке, мне просто было интересно, есть ли что-то «готовое к использованию» (или что-то вроде однострочного bash), которое мне не хватает.
Примечание: в примерах я использую обычные каналы, но вопрос в равной степени относится и к именованным каналам.
Хотя я получил ответ ниже, я также решил реализовать команду leakybuffer, поскольку простое решение, приведенное ниже, имеет некоторые ограничения: https://github.com/CAFxX/leakybuffer