Вопрос или проблема
У меня есть монтирование FUSE, расположенное в /media/writable
, однако иногда это монтирование FUSE отключается, и некоторые программы продолжают пытаться записать в /media/writable
.
Когда я перезапускаю службу монтирования FUSE, монтирование не удается, так как директория не пуста.
Как я могу использовать аргумент --one-file-system
команды rm
, чтобы при удалении /media/writable
удалялись только файлы, расположенные на локальной файловой системе, а не на монтированной FUSE файловой системе? В /media/
находятся и другие папки, поэтому я не могу выполнить команду rm
в родительской папке.
Стоит ли переместить папку на один уровень ниже (например, в /media/writable/mount
), чтобы я мог удалить родительскую папку, или существует способ выбора файловой системы, из которой я хочу удалить файлы?
Я использую Ubuntu 18.04.1 LTS с coreutils 8.28.
Изменение: Мой текущий метод таков, но я хотел бы узнать, есть ли более эффективный способ:
ExecStartPre=-/bin/mountpoint /media/writable/ || /usr/bin/stat /media/writable/MOUNTED || /bin/rm/ --one-file-system -rf /media/writable/*
Одним из подходов было бы перейти в эту директорию с помощью команды cd
. Тогда, даже если директория будет монтироваться, пока ваш скрипт очистки выполняется, вы все равно будете видеть старую локальную директорию (при условии, что вы используете только относительные пути).
#! /bin/zsh -
zmodload zsh/stat || exit
cd /media/writable || exit
stat -H parent .. || exit
stat -H here . || exit
if (( parent[device] == here[device] )); then
# текущая директория находится на том же устройстве, что и родительская
all_files=(*(ND))
(( $#files == 0 )) ||
rm -rf --one-file-system --preserve-root=all -- $all_files
fi
Обратите внимание на модификатор D
для включения скрытых файлов, а также на параметр --preserve-root=all
как дополнение к --one-file-system
на случай, если некоторые из $all_files
сами являются точками монтирования для других файловых систем (хотя это пока не гарантирует защиту от гонок в текущей реализации, поэтому я бы избегал rm -rf --one-file-system --preserve-root=all /media/writable
).
Это все равно может завершиться с ошибкой “слишком длинный список аргументов”, если там будет много файлов, что можно обойти, написав это так:
print -rNC1 -- $all_files |
xargs -r0 rm -rf --one-file-system --preserve-root=all --
Ответ или решение
Вопрос об удалении файлов с локальной файловой системы, используя флаг --one-file-system
команды rm
, требует внимательного рассмотрения особенностей файловых систем, методов их монтирования и отключения. Чтобы успешно справиться с задачей, необходимо понять, как работает команда rm
с флагом --one-file-system
, и какие альтернативные подходы могут помочь в решении проблемы.
Теория
Команда rm
с флагом --one-file-system
позволяет ограничить удаление только файлами, находящимися на одном файловом устройстве. Эта опция полезна в ситуациях, когда необходимо защитить файлы на смонтированных устройствах, таких как FUSE, от случайного удаления. Флаг --one-file-system
предотвращает рекурсивное удаление файлов и каталогов, которые находятся на других файловых системах, если переход между файловыми системами происходит в пределах удаления.
Однако, проблема в описанной ситуации заключается в том, что директория /media/writable
может быть переполнена из-за записи программами в момент, когда FUSE-монтирование недоступно. Это приводит к невозможности монтирования FUSE в адресованную директорию, так как она не является пустой.
Пример
Ваш текущий метод включает использование команд mountpoint
, stat
и rm
для проверки состояния директории и последующего очищения её содержимого. Скрипт начинается с проверки, является ли /media/writable
точкой монтирования через команду mountpoint /media/writable
. Если она отсутствует, происходит проверка наличия структурированных данных с помощью /usr/bin/stat /media/writable/MOUNTED
. Далее, если точка монтирования не обнаружена, выполняется очистка директорий командой rm --one-file-system -rf /media/writable/*
.
В примере также предлагается использование скрипта на языке Zsh, который позволяет выполнить проверку идентичности устройств директории и её родителя для обеспечения, что операции выполняются на одном устройстве. Используется stat
для получения информации об устройствах, а операция удаляется только в случае совпадения этих значений.
Применение
Чтобы применить данную стратегию на практике, можно рассмотреть следующие шаги:
-
Создание изолированной директории для монтирования: Вы можете рассмотреть возможность создания подкаталога внутри
/media/writable
, например/media/writable/mount
. В этом случае вы сможете очищать содержимое родительской директории/media/writable
, не затрагивая другие монтированные файловые системы. -
Скрипт на Zsh с обработкой длинных списков файлов: Представленный выше скрипт на Zsh демонстрирует проверку на принадлежность директорий к одному устройству и безопасное их удаление. Использование
xargs
помогает избежать проблемы "слишком длинного списка аргументов" при работе с большим числом файлов. Это делает процесс удаление более надёжным и предсказуемым. -
Автоматизация и мониторинг: Для автоматизации такого рода операций, можно интегрировать описанные команды и скрипты в системные службы, такие как systemd, дополнив мониторингом состояния монтирования FUSE. Это позволит автоматически предпринимать действия по очистке содержимого каталогов, если FUSE-монтирование теряется.
В заключение, комбинированное использование флага --one-file-system
и грамотное управление монтированием может значительно облегчить процесс управления файловыми системами в среде Linux. Переход к более изолированной структуре директорий и отказ от работы во входной директории /media
дополнительно повышает безопасность и устойчивость системы.