Используя файловую систему FUSE (Файловую систему в пользовательском пространстве ), вы можете написать программу, использующую библиотеку libfuse для реализации большинства операций с файлами. Вы эффективно монтируете программу в каталоге, и любые операции, которые вы выполняете в каталоге, передаются через ядро программе, которая предоставляет ответ. Существует несколько пакетов Perl и Python с примерами программ, которые довольно просто изменить в соответствии с вашими требованиями.
В частности, для моей Fedora 25 есть fuse-python
rpm, содержащий пример программы, xmp.py , которая «просто» дублирует каждую операцию, выполняемую под точкой монтирования, в указанный вами реальный каталог. на старте.
Например, если запустить (не от root, а от обычного пользователя)
mkdir -p /tmp/myfs/under /tmp/myfs/write
xmp.py /tmp/myfs/write -o root=/tmp/myfs/under
тогда все, что вы делаете с файлом в точке монтирования /tmp/myfs/write
, также будет видно в реальном дублирующем «корневом» каталоге /tmp/myfs/under
. Например
echo abc >/tmp/myfs/write/file1
создает file1
в реальном каталоге. Конечно, если вы ls /tmp/myfs/*/file1
файл отображается в обоих, так как xmp.py
также показывает вам реальный каталог:
-rw-r--r-- 1 4 Aug 1 18:43 /tmp/myfs/under/file1
-rw-r--r-- 1 4 Aug 1 18:43 /tmp/myfs/write/file1
Если вы посмотрите на пример кода Python, он довольно короткий. Вы можете увидеть внедрение системного вызоваwrite()
здесь:
def write(self, buf, offset):
self.file.seek(offset)
self.file.write(buf)
return len(buf)
Чтобы подавить фактическую запись в файл, вам нужно только закомментировать третью строку:
def write(self, buf, offset):
self.file.seek(offset)
# self.file.write(buf)
return len(buf)
Размонтируйте файловую систему fuse с помощью
fusermount -u /tmp/myfs/write
, затем запустите новый xmp.py
, и теперь, когда вы записываете в файл, кажется, что это удалось, но данные не записываются в базовый реальный каталог. Вероятно, не стоит пытаться заглушить другие операции с файлами, такие как создание каталогов и т. д., поскольку ваша программа может столкнуться с ложными проблемами.
Примечание.Я использовал xmp.py
, поставляемый с пакетом, который я установил в своей системе. Ссылки на код github предназначены только для просмотра. У вас не должно возникнуть проблем с повторением этого эксперимента, если вы найдете и используете подходящий пакет для вашей системы. Обратите внимание, что для FUSE существует несколько библиотек Python. Убедитесь, что вы установили тот, который содержит приведенный выше пример кода.
Ваш логин должен быть в группе fuse , чтобы иметь возможность использовать программу. Вы должны увидеть это в выводе команды id
. Если группы нет, добавьте ее с помощью sudo usermod -a -G fuse $USER
(, где $USER — ваш логин ), и снова войдите в систему.
В Ubuntu это пакет python-fuse
. Однако мои тесты в 18.04.2 LTS не сработали. Пример xmp.py
без изменений создаст файл, но не запишет в него, говоря Invalid argument
. Кажется, это связано с несовместимостью версий this и libfuse. Когда я запустил xmp.py
с дополнительной опцией отладки -o debug
, я увидел ошибки
AttributeError: 'XmpFile' object has no attribute 'direct_io'
AttributeError: 'XmpFile' object has no attribute 'keep_cache'
Вы можете попробовать другие способы исправить это, но я просто добавил отсутствующие атрибуты в xmp.py
, добавив в class XmpFile
, функцию def __init__
, после строки self.fd = self.file.fileno()
следующие 2 строки:
self.direct_io = None
self.keep_cache = None
Убедитесь, что вы сохраняете одинаковый отступ для этих строк, используя только пробелы, а не табуляцию.