2

Уже есть программа, которая читает несколько каналов или файловых дескрипторов и записывает в стандартный вывод (не разбивая строки).

Как cat , но читает все файлы одновременно и сохраняет строки.

Что-то вроде:

until(all fds are EOF) {
    select(multiple fds);
    read a line from triggered fd;
    write the line to the stdout;
}

Необходимо избегать кодирования циклов select/epoll или использования многопоточности в простых программах. Как "выбрать цикл для Bash".

Обновление: я также создал аналогичный вопрос по Unix.SE.

3 ответа3

2

Частичным решением может быть использование:

tail -fq file1 file2 file3 | grep -v ^$ | yourprogram

Я называю это частичным решением, потому что grep удаляет пустую строку, которую tail добавляет каждый раз, когда меняет файл. Если ваш ввод содержит пустые строки, они удаляются.

1

Альтернатива с использованием xargs(1) и tail(1):

Создайте источники данных:

$>touch datafile.txt
$>mkfifo pipe1
$>mkfifo pipe2

Запустите хвостовые процессы с помощью xargs:

$>echo datafile.txt pipe1 pipe2 | xargs -n 1 -P 0 tail -f >> datasink.txt

Вставить данные в источники:

$>echo dataset1 > pipe1
$>echo dataset2 > datafile.txt
$>echo dataset3 > pipe1
$>echo dataset4 > pipe2

Показать данные из приемника:

$>cat datasink.txt 
dataset1
dataset2
dataset3
dataset4
0

Создана программа для этого: fdlinecombine. Он читает указанные файловые дескрипторы и выводит данные аналогичным образом.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .