Вопрос или проблема
В терминале 24.10 выполнение
sudo find /media/steve/saved_data/rsync_backups/ubuntu/ -mindepth 1 ! -regex '^/media/steve/saved_data/rsync_backups/ubuntu/ubuntu_101524\(/.*\)?' -delete
запустит резервное копирование rsync и удалит все другие папки в целевом каталоге, кроме новосозданной резервной копии. Однако выполнение команды:
sudo find /media/steve/saved_data/rsync_backups/ubuntu/ -mindepth 1 ! -regex "^/media/steve/saved_data/rsync_backups/ubuntu/ubuntu_101524\(/.*\)?" -delete
удалит все, включая резервную копию. Что вызывает такое поведение?
Ответ или решение
Команда find
является мощным инструментом в Unix-подобных системах, предназначенным для поиска файлов и каталогов в файловой системе. Синтаксис команды может быть сложным, особенно когда используются дополнительные параметры и регулярные выражения.
Синтаксис команды find
Общая форма команды find
выглядит следующим образом:
find [путь] [условия] [действия]
- путь – начальный каталог, в котором начинается поиск.
- условия – условия, по которым осуществляется поиск. Это могут быть параметры, такие как
-name
,-type
,-regex
и т.д. - действия – действия, которые следует выполнить над найденными файлами или каталогами, например,
-delete
,-print
, или выполнение команды через-exec
.
Рассмотрение конкретных команд
В приведенном вами примере команды:
-
Первая команда:
sudo find /media/steve/saved_data/rsync_backups/ubuntu/ -mindepth 1 ! -regex '^/media/steve/saved_data/rsync_backups/ubuntu/ubuntu_101524\(/.*\)?' -delete
-mindepth 1
: Указывает, что поиск должен начинаться с уровня глубже корневого (то есть пропускается сам каталогubuntu
).! -regex '^/media/steve/saved_data/rsync_backups/ubuntu/ubuntu_101524\(/.*\)?'
: Используется регулярное выражение для исключения из удаления. Оно говорит, что нужно не удалять каталоги или файлы, которые соответствуют паттерну, начинающимся сubuntu_101524
и возможно имеющим подкаталоги.-delete
: Это действие удаляет все найденные элементы, которые не соответствуют регулярному выражению.
-
Вторая команда:
sudo find /media/steve/saved_data/rsync_backups/ubuntu/ -mindepth 1 ! -regex "^/media/steve/saved_data/rsync_backups/ubuntu/ubuntu_101524\(/.*\)?" -delete
Обратите внимание, что в этой команде используется двойная кавычка вместо одинарной. Это может привести к различию в интерпретации регулярного выражения.
Причина различий
Проблема, с которой вы столкнулись, заключается в различии между одинарными и двойными кавычками в контексте регулярных выражений:
- Одинарные кавычки (как в первой команде): Это позволяет интерпретации регулярного выражения выполняться буквально, оставляя все специальные символы, такие как
(
и)
, без изменений и как часть регулярного выражения. - Двойные кавычки (как во второй команде): В этом случае оболочка может интерпретировать некоторые символы перед передачей их
find
. Это может привести к неправильному интерпретированию регулярного выражения и, как следствие, к более широкому набору файлов или каталогов, которые подходят под условия, что в конечном итоге приводит к удалению в том числе и нужных данных.
Рекомендации
- Всегда используйте одинарные кавычки, если хотите сохранить точный формат регулярного выражения, чтобы избежать нежелательной интерпретации оболочки.
- Перед выполнением команды с
-delete
, рекомендуется делать тестовый запуск команды с-print
, чтобы убедиться, какие файлы и каталоги будут удалены.
Понимание этих нюансов существенно уменьшает риск случайного удаления данных и помогает эффективно использовать команду find
в различных сценариях.