LINUX.ORG.RU
ФорумAdmin

Генерируемый на лету файл


0

0

Надо создать некий псевдофайл в файловой системе, содержимое которого будет формироваться скриптом, по запросу. Что-то вроде файлов в /proc, но на прикладном уровне, а не на уровне ядра. Можно-ли сделать такую вещь, а если можно, то как?


Ответ на: комментарий от balodja

Сам mktemp конечно же лучше не использовать, но по SEE ALSO легко найти все, что нужно.

balodja ★★★
()
Ответ на: комментарий от hizel

Вообщем, предположения, идеи, но никто такого не делал, как я понял.

1. Fuse не подходит: 1) нечего ему на сервере делать, 2) нужно прикладное решение, на уровне команд для ОС/ФС

2. Про пайпы думал, но как подать сигнал скрипту, что пора генерировать содержимое? Или перезапустить скрипт, после чтения содержимого файла? Вот например:

 mkfifo test
 ( while (( num < 1000 )); do echo $(( num++ )); done; ) >test
Теперь в другой консоли:
 cat test
Вроде нормально, но теперь надо перезапустить скрипт, чтобы при повторном чтении файла он снова сгенерировал его содержимое. Как это сделать, если «читатель» вообще не знает, что он работает с fifo? Ну, допустим, читатель - веб-сервер, загружающий свой текстовый конфиг.

Теперь - вариант с несколькими одновременно работающими «читателями»

 cat test >1 & cat test >2 & cat test >3 &
Первый, кто успел пайп захватить, его и пользует, остальные отдыхают. А надо, чтобы на каждый процесс - свой скрипт-генератор запускался

3. mktemp - вообще не в тему

4. socket - «читатель» файла bind(), accept() и т.п. делать не будет, он думает, что работает с обычным файлом, поэтому максимум - fopen()

Вообщем, приемлимых вариантов не дождался, пойду в другие форумы поспрошаю, может на специалиста нарвусь...

xdsl
() автор топика
Ответ на: комментарий от xdsl

> 3. mktemp - вообще не в тему

Прошу прощения, неправильно понял вопрос.

> Как это сделать, если "читатель" вообще не знает, что он работает с fifo? Ну, допустим, читатель - веб-сервер, загружающий свой текстовый конфиг.

Вообще-то open на fifo блокирует процесс до того момента, пока его не откроют с другой стороны. То есть можно тупо открыть на запись, процесс заблокируется, пока не откроют на чтение, потом уже генерить содержимое. Данные соответственно получаются вполне актуальные.

balodja ★★★
()
Ответ на: комментарий от balodja

В одной консоли:

$ mkfifo hello
$ while true; do (echo hi; date) > hello; done

В другой:

$ cat hello 
hi
Пнд Окт 19 14:49:04 MSD 2009
$ cat hello 
hi
Пнд Окт 19 14:49:28 MSD 2009 

Все данные актуальны.

balodja ★★★
()
Ответ на: комментарий от balodja

Вот только для параллельной работы нескольких «юзеров» не годится. Нужна доработка.

Пример:

В одной консоли:

mkfifo fifo; i=1; while true; do echo "$i"`date` > fifo; i=$(($i+1)) ; done

В другой:

$ cat fifo & cat fifo & cat fifo &
[1] 14475
30Пнд Окт 19 17:04:13 YEKST 2009
[2] 14477
31Пнд Окт 19 17:04:16 YEKST 2009
[3] 14478
32Пнд Окт 19 17:04:16 YEKST 2009
33Пнд Окт 19 17:04:16 YEKST 2009
34Пнд Окт 19 17:04:16 YEKST 2009
35Пнд Окт 19 17:04:16 YEKST 2009
36Пнд Окт 19 17:04:16 YEKST 2009
[1]   Done                    cat fifo
[2]   Done                    cat fifo
[3]+  Done                    cat fifo

Nao ★★★★★
()
Ответ на: комментарий от xdsl

Fuse не подходит:

1) нечего ему на сервере делать,

Почему это?

2) нужно прикладное решение, на уровне команд для ОС/ФС

и в чем fuse не соответствует?

sdio ★★★★★
()
Ответ на: комментарий от xdsl

>bind(), accept() и т.п. делать не будет

Запускай "nc -U ... | читатель" -- и даже open не понадобится.

DonkeyHot ★★★★★
()
Ответ на: комментарий от sdio

Сходил поспрошал у специалистов, тоже руками разводят или умными словам, уже здесь озвученными, сыплют.

и в чем fuse не соответствует?

Нечего множить сущности. Если, конечно, удастся решить на уровне стандартных утилит и возможностей FS/OS

Запускай «nc -U ... | читатель» — и даже open не понадобится.

«Читатели» (bind,xinetd,httpd2,squid) работают стабильно много лет, а первое правило электрика гласит: «Работает - не трожь!!!». Поэтому вмешиваться в их работу не хочу, но вот на лету генерировать им конфиги или часть конфигов, подключаемых из основных с помощью разных include, $INCLUDE и т.п. - совсем другое дело. Потом в нужный момент service blablabla reload(condreload), или, как bind, само конфиг перечитает.

Похоже, проблема на уровне fifo должна решаться, если отказаться от многопоточного одновременного доступа, что для моих задач вторично. Остается понять, как сгенерировать признак конца файла, чтобы «читатель» корректно завершил загрузку. В примере

 while true; do (echo hi; date) > hello; done 
конец файла генерируется, как я понимаю, по окончанию вызова внешней программы. Если сделать так:
 while true; do (echo hi; exit 0; ) > hello; done 
то вроде должно работать, но почему-то
 cat hello
вместо одного hi иногда выдает
hi
hi
Понять-бы в чем дело, а то придется идти учить матчасть по пайпам, что полезно, но по времени затратно

xdsl
() автор топика
Ответ на: комментарий от xdsl

Тогда бери в руки incrond (inotify)

Делай триггер для именного пайпа на событие IN_ACCESS — File was accessed (read) или IN_OPEN  — File was opened.

По этому событию твой скрипт начинает лить в пайп данные.

Для каждого клиента свой пайп или пусть клиенты становятся в очередь.

sdio ★★★★★
()
Ответ на: комментарий от sdio

>Тогда бери в руки incrond (inotify) Делай триггер для именного пайпа на событие IN_ACCESS -- File was accessed (read) или IN_OPEN -- File was opened. По этому событию твой скрипт начинает лить в пайп данные. Для каждого клиента свой пайп или пусть клиенты становятся в очередь.

О! Большое спасибо, это вроде то, что нужно - пойду проверять.

xdsl
() автор топика
Ответ на: комментарий от xdsl

>на лету генерировать им конфиги или часть конфигов

Для такой задачи вообще ничего не нужно. Просто генерируй конфиг в обычном файле на обычном месте, и потом "reload" (хотя бы тем же incron-ом, только наоборот -- реакция на MOVED_TO/CLOSE_WRITE "service reload") . При должной паранойе бонус: если что-то поломается, на месте последний рабочий конфиг.

DonkeyHot ★★★★★
()
Ответ на: комментарий от DonkeyHot

Для такой задачи вообще ничего не нужно. Просто генерируй конфиг в обычном файле на обычном месте, и потом «reload» (хотя бы тем же incron-ом, только наоборот — реакция на MOVED_TO/CLOSE_WRITE «service reload») . При должной паранойе бонус: если что-то поломается, на месте последний рабочий конфиг.

Открыв для себя inotify, так возможно и сделаю. Тем более, что пайп не желает реагировать ни на IN_ACCESS, ни на IN_OPEN до тех пор, пока в него не пойдут данные:

Консоль1:

mkfifo /tmp/h
inotifywait /tmp/h
ждемс, а пока

Консоль2:

cat /tmp/h

Консоль1 - тишина, никаких событий.

Консоль3:

echo bla >/tmp/h 

Консоль1 -

/tmp/h OPEN

xdsl
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.