Мне нужно удалить все скомпилированные данные:
- каталоги называются
build
, - каталоги называются
obj
, - * .so файлы.
Я написал команду
find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;
он рекурсивно просматривает все каталоги и удаляет все, что мне нужно.
Почему у меня такой вывод в конце? Может быть, я должен написать другую команду.
find: `./3/obj': No such file or directory
find: `./3/build': No such file or directory
find: `./1/obj': No such file or directory
find: `./1/build': No such file or directory
find: `./2/obj': No such file or directory
find: `./2/build': No such file or directory
find
это,find /search_directory options
опуская каталог поиска - не очень хорошая идеяОтветы:
Используйте
-prune
каталоги, которые вы в любом случае собираетесь удалить, чтобыfind
не пытаться искать в них файлы:Также обратите внимание, что
*.so
нужно заключать в кавычки, так как в противном случае оболочка может быть расширена до списка.so
файлов в текущем каталоге.Эквивалентом вашего
-regex
типа GNU будет:Обратите внимание, что если вы собираетесь использовать синтаксис, специфичный для GNU, вы можете использовать
-delete
вместо-exec rm -rf {} +
. С-delete
, GNUfind
включается-depth
автоматически. Он не запускает внешние команды, поэтому он более эффективен, а также безопаснее, так как устраняет условие гонки, при котором кто-то может заставить вас удалить неправильные файлы, изменив каталог между символическими ссылками в промежутке времени.find
находит файл иrm
удаляет его (см.info -f find -n 'Security Considerations for find'
подробности).источник
-delete
также лучше обрабатывает такие вещи, как пробелы-exec rm -rf {} +
которые не имеют проблем с ними.{}
- они должны быть процитированы или нет? Кажется, что он работает без кавычек, но GNU Findutils Manual использует'{}'
в качестве примера. Не могли бы вы уточнить?csh
, но я никогда не смог проверить это утверждение. Они не нужны ни в одной современной оболочке, которую я знаю. Они определенно не требуются POSIX. В примерах POSIX не используют их.-delete
не может использоваться с каталогами.Я предполагаю, что причина в том, что
find
сначала удаляется дерево каталогов и пытается проверить содержимое каталога, что, очевидно, не самый лучший порядок. Вы можетеfind
сначала проверить содержимое:Вы должны рассмотреть возможность использования
-delete
для файлов и-exec rmdir
для каталогов.источник
Мое решение.
+ против \; в команде -exec
источник
-exec … {} +
выполняет команду для нескольких файлов одновременно, столько, сколько помещается в командной строке. Если файлов слишком много (или точнее, если общая длина путей слишком велика), ониfind
будут выполнять несколько экземпляровrm
и, следовательно, могут в конечном итоге удалить каталог, который он пересекает. Это просто менее вероятно,+
чем с;
, но+
не решает проблему.