Эмуляция именованных процессов

Допустим, у меня есть большой GZIP-файл data.txt.gz, но часто разархивированную версию нужно давать программе. Конечно, вместо создания отдельного без упаковки data.txt можно использовать синтаксис замены процесса:

./program <(zcat data.txt.gz)

Однако, в зависимости от ситуации, это может быть утомительно и подвержено ошибкам.

Есть ли способ эмулировать подстановку именованного процесса? То есть создать псевдофайл data.txt это "развернется" в процесс замены zcat data.txt.gz всякий раз, когда к нему обращаются. В отличие от символической ссылки, операция чтения перенаправляется в другой файл, но в этом случае это должен быть временный именованный канал.

Благодарю.

PS. Несколько похожий вопрос


Редактировать (из комментариев) Фактический вариант использования имеет большой сжатый корпус, который, помимо использования в необработанном виде, также иногда необходимо обрабатывать с помощью ряда легких операций (токенизация, нижний регистр и т. Д.), А затем передавать их в некоторый "более тяжелый" код. Хранение предварительно обработанной копии приводит к бесполезному использованию дискового пространства, а повторный повторный ввод полного конвейера предварительной обработки может привести к ошибкам. В то же время, запуск конвейера на лету влечет за собой небольшие вычислительные затраты, отсюда и идея долгоживущего псевдофайла, который скрывает детали под капотом.

2 ответа

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

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

Есть целый ряд вариантов, в зависимости от того, что вам нужно и сколько усилий вы готовы приложить.

Если вам нужен одноразовый файл, вы можете просто использовать mkfifo чтобы создать файл, запустите перенаправление вашего архива в fifo и передайте имя файла fifo тому, кто захочет прочитать из него.

Если вам нужно многократно обращаться к файлу (возможно, одновременно), вы можете настроить сокет, используя netcat, который будет снова и снова обслуживать распакованный файл.

С "традиционным netcat" это так же просто, как while true; do nc -l -p 1234 -c "zcat myfile.tar.gz"; done, С BSD netcat это немного раздражает:

# Make a dummy FIFO
mkfifo foo

# Use the FIFO to track new connections
while true; do cat foo | zcat myfile.tar.gz | nc -l 127.0.0.1 1234 > foo; done

В любом случае, когда сервер (или файловый сокет) запущен, вы просто делаете nc localhost 1234 прочитать распакованный файл. Вы можете, конечно, использовать nc localhost 1234 как часть процесса замены в другом месте.

Похоже, это в действии (изображение, вероятно, лучше всего просматривать в отдельной вкладке):

демо сервер Netcat

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

Наконец, и это, пожалуй, самое "экзотическое" решение, вы можете написать файловую систему FUSE, которая представляет виртуальные файлы, подкрепленные любой логикой, которую пожелает ваше сердце. На этом этапе вам, вероятно, следует хорошо подумать о том, действительно ли затраты на обслуживание и сложность того, куда вы идете, компенсируют необходимость звонить zcat несколько лишних раз.

Другие вопросы по тегам