Неблокуюча буферизована названа труба?


20

Я шукаю те, чого я підозрюю, що не існує: неблокуючий буфер з ім'ям pipe (fifo) для використання з командного рядка. Чи є таке?

Ось випадок використання: Припустимо, у мене є процес, який триватиме довгий час у фоновому режимі і вимагає багато результатів stdout. Мені не дуже важливо вихід і не хочу зберігати його (можливо, мені не вистачає місця), але я хотів би періодично "запускатись" і слідкувати за тим, що він робить, а потім знову відмовитися. і залиште це робити свою роботу. Тож я хотів би перенаправити свій вихід на цю теоретичну буферизовану, не блокуючу названу трубу, а потім періодично натискати на неї.

Тому в основному я хочу почати так ( 10Mз розміром буфера):

mkmagicfifo magicfifo 10M
spewingprocess > magicfifo &

... і періодично заходьте, щоб побачити, що відбувається ...

tail -f magicfifo

... без magicfifo збереження всього виводу (значить, не звичайний файл) і не блокуючи процес вилучення, коли він заповнюється і не натискається (значить, не зовсім нормальна названа труба).

Я не думаю, що рішення, які передбачають це, tailабо pruneбудуть робити це (добре, я можу придумати вирішення проблеми, що стосується tail), тому tailщо все-таки потрібно буде десь зберігати всі дані (якщо я хочу зайти і відмовитися від перегляду), і pruneповинен переписати файл, мабуть (я визнаю, я не намагався / довів це), порушивши перенаправлення процесу, генеруючи весь вихід.

Я сподіваюся, що я можу написати якусь утиліту для цього, але * nix має дуже багато цікавих аспектів файлів і труб, і я просто не можу допомогти, але думаю, що це існує, і я просто не знаю про це.

Отже: Чи є таке, і якщо так, що це?


1
Те, що ви описуєте, - це "кільцевий буфер" або "круговий буфер". Мені невідомі будь-які інструменти командного рядка для підтримання подібної речі, хоча це було б тривіально.
Шон Дж. Гофф

2
Погляньте на рішення, описані в "Linux неблокуючій фіфолі (за записом журналу запитів)", stackoverflow.com/questions/7360473/… .

1
Дивиться , як це було вирішено на StackOverflow: stackoverflow.com/questions/7360473 / ...
Джеймс Blackburn

@JamesBlackburn: Дякую! Дуже цікаво.
TJ Crowder

Відповіді:


16

Я думаю, що ти шукаєш - це GNU screen. Він підтримує буфер, щоб утримувати останній екран повним або двома вихідними сигналами з однієї або декількох програм, і дозволяє відключитися та повернутися пізніше.


+1 для пропонування екрана До речі, ви можете налаштувати його на велику кількість "рядків історії".
Містер Шунц,

1
Спасибі. Чи можете ви навести приклад того, як ви застосували це до команд, які я показав у своєму запитанні? Сторінка man говорить про те, що це віконний менеджер (я думаю, що вони мають на увазі термінальний сенс, а не графічний сенс, але все ж). А чи зможу я все-таки зайти (через ssh) і випасти за необхідності? (Напр., На віддалених серверах.)
TJ Crowder

Так, ви можете використовувати екран GNU таким чином. Ви створили б новий (потенційно названий) сеанс, запустили команду всередині цього сеансу, а потім від'єдналися.
TML

2
Там же tmuxі dtach- що - небудь в тому ж класі програми керуючого терміналу мультиплексора / сеансу повинні бути в змозі досягти того ж.
jw013

5

Ви можете використовувати pv, він забезпечує стільки буферизації, скільки вам потрібно в конвеєрі. Ви можете використовувати його так:

sprewingprocess | pv -B 1g > ordinaryfifo &

Це дозволить отримати до 1 ГБ буферизації між spewingprocessта фіфо. Більшість дистрибутивів Linux пропонують pvу пакеті під назвою, вірте чи ні pv,.


Дякую, але чи не був би цей блок, коли буфер був заповнений, якби я не читав цільову назву pipe?
TJ Crowder

1
Так, але який у вас вибір? У кінцевому Всесвіті ви не можете мати буквально необмежену буферизацію.
Девід Шварц

Інший вибір - це я, як я описав у своєму запитанні: Не зберігати весь результат. Коли буфер заповнений, найдавніший матеріал викидається.
TJ Crowder

Хм, я тестував це, і це, на жаль, не працює повністю. Якщо процес зчитування файлу на деякий час припиняє читання, pv блокує спробу записувати на фіфо, і оскільки він не є багатопотоковим, він також блокує зчитування даних у буфер pv. Таким чином, буфер pv буде продовжувати заповнюватися лише тоді, коли процес читання файлу продовжує читати. pv може вміти читати та буферувати деякі дані, але це не заважає автору повністю блокувати.
Даніель С. Стерлінг

1

У мене була така ж проблема. Це моє перше рішення. Спочатку запишіть вихід у файл, який ми усікаємо після кожного рядка, щоб він не зростав нескінченно:

spewingprocess | while read line; do echo $line > buffer.txt ; done

Потім читайте з файлу за допомогою хвоста (де 2> /dev/nullпозбавляється повідомлення про помилку "усічений файл"):

tail -f ./buffer.txt 2> /dev/null

Таким чином буфер не росте, і ми можемо мультиплексувати, наприклад, виконувати стільки хвостів, скільки нам хочеться. Однак проблема такого підходу полягає в тому, що ми можемо втрачати дані, коли усікаємося швидше, ніж хвост може прочитати, як показує цей тест:

for ((i=0; ; i++)) ; do echo "$i" ; done | while read line; do  echo $line > buffer.txt ; done
tail -f ./buffer.txt 2> /dev/null > log.txt

Після деякого пробігу перший і останній рядки:

$ head -n 1 log.txt
0
$ tail -n 1 log.txt
78783

Але файл має менше рядків, тому деякі втрачаються:

$ wc log.txt
67087  67087 392819 log.txt

Однак це здається приємним рішенням, якщо ви не так сильно піклуєтесь про втрату даних або коли ваш процес вивертання недостатньо швидкий для того, щоб втратити дані.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.