Как создать виртуальный файл с поддержкой команд в Linux?
Каков наиболее простой способ создания "виртуального" файла в Linux, который позволял бы операции чтения в нем всегда возвращать вывод какой-либо конкретной команды (запускаться каждый раз, когда файл читается)? Таким образом, каждая операция чтения будет вызывать выполнение команды, перехватывать ее вывод и передавать его как "содержимое" файла.
4 ответа
Нет никакого способа создать так называемый "виртуальный файл". С другой стороны, вы сможете добиться этого, внедрив простую синтетическую файловую систему в пространстве пользователя через FUSE. Более того, вам не нужно использовать c, есть привязки даже для языков сценариев, таких как python.
Редактировать: И есть вероятность, что нечто подобное уже существует: см., Например, scriptfs.
Это отличный ответ, который я скопировал ниже.
По сути, именованные каналы позволяют вам делать это в скриптах, а Fuse позволяет вам легко это делать в Python.
Возможно, вы ищете именованную трубу.
mkfifo f
{
echo 'V cebqhpr bhgchg.'
sleep 2
echo 'Urer vf zber bhgchg.'
} >f
rot13 < f
Запись в канал не запускает программу прослушивания. Если вы хотите обработать ввод в цикле, вы должны поддерживать работающую программу прослушивания.
while true; do rot13 <f >decoded-output-$(date +%s.%N); done
Обратите внимание, что все данные, записанные в канал, объединяются, даже если записывается несколько процессов. Если несколько процессов читают, только один получает данные. Таким образом, труба может не подходить для одновременных ситуаций.
Именованный сокет может обрабатывать параллельные соединения, но это выходит за рамки возможностей базовых сценариев оболочки.
В самом сложном конце шкалы находятся пользовательские файловые системы, которые позволяют проектировать и монтировать файловую систему, где каждая open
, write
и т. д., запускает функцию в программе. Минимальные вложения составляют десятки строк нетривиального кодирования, например, в Python. Если вы хотите выполнять команды только при чтении файлов, вы можете использовать scriptfs или fuseflt.
Никто не упомянул об этом, но если вы можете выбрать путь к файлу, вы можете использовать стандартный ввод /dev/stdin
,
Каждый раз cat
программа запускается, она заканчивает тем, что читает выходные данные программы, записывающей в канал, который просто echo my input
Вот:
for i in 1 2 3; do
echo my input | cat /dev/stdin
done
выходы:
my input
my input
my input
Я боюсь, что это не легко возможно. Когда процесс читает файл, он использует системные вызовы, такие как open
, fstat
, read
, Вам нужно будет перехватить эти вызовы и вывести что-то отличное от того, что они вернут. Это потребует написания модуля ядра, и даже тогда это может оказаться невозможным.
Тем не менее, если вам просто нужно вызвать что-то при каждом обращении к определенному файлу, вы можете поиграть с inotifywait
:
#!/bin/bash
while inotifywait -qq -e access /path/to/file; do
echo "$(date +%s)" >> /tmp/access.txt
done
Запустите это как фоновый процесс, и вы получите запись в /tmp/access.txt
каждый раз, когда ваш файл читается.