Создайте виртуальный файл, который на самом деле является командой

18

Есть ли способ создать виртуальный файл, такой, что чтение из файла фактически читает из stdoutкоманды; запись в файл - это запись в stdinкоманду?

До сих пор я помещал это inotifywaitв файл on, который вызывает команду при изменении файла, берет его входные данные из файла и записывает обратно в него.

Мне не нравится, что inotifywaitего нужно постоянно перезапускать (и я должен убедиться, что он всегда работает). Я использую этот файл только два раза в неделю.

JSJ
источник

Ответы:

17

Возможно, вы ищете именованную трубу .

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 .

Жиль "ТАК - перестань быть злым"
источник
3

Некоторые вещи, которые следует знать о именованных каналах: канал не может иметь - в отличие от файла - несколько читателей. Как только его содержимое прочитано, оно исчезло. Таким образом, вам нужно выполнить цикл, то есть вам нужно будет постоянно выдвигать контент в канал от писателя.

Я сам искал ответ на этот вопрос, и единственное, что я смог придумать, это scriptfs, основанный на fuse .

unixhacker2010
источник
1

То, что вы описываете, по сути является специальным файлом FIFO, см fifo(7). Они создаются mkfifo(1), и процесс может затем открыть их в Linux для R / W (не все системы Unixy справляются с этим). Два независимых процесса могут использовать его для связи.

vonbrand
источник
0

Самый простой способ «создать виртуальный файл, который на самом деле является командой» - это расширить файловую систему FUSE. Это очень легко сделать с такими библиотеками, как fusepy.

Вот пример файловой системы FUSE, которая позволяет вам читать файлы HTTP / HTTPS / FTP, как если бы они присутствовали на вашем собственном компьютере с Linux. Вы также можете создать что-то, что выполняет любую команду для того же самого при чтении.

Если вы посмотрите на исходный код, то вряд ли это 50 строк кода (исключая любой шаблонный код).

supersan
источник