Почему моя "находка" не работает, как я ожидаю, используя -exec?

Я пытаюсь удалить все .svn-каталоги из рабочего каталога.

Я думал, что просто буду использовать find и rm следующим образом:

find . -iname .svn -exec 'rm -rf {}' \;

Но результат:

find: rm -rf./src/.svn: Нет такого файла или каталога

Очевидно, файл существует, или find не найдет его... Что мне не хватает?

Ответ 1

Нельзя помещать rm -rf {} в одинарные кавычки.

Как вы сказали, оболочка обрабатывает все аргументы -exec как команду, а не команду плюс аргументы, поэтому ищет файл с именем "rm -rf ./src/.svn" и не находит его.

Try:

find . -iname .svn -exec rm -rf {} \;

Ответ 2

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

find . -iname .svn -print | xargs rm -rf

или, так как теперь я использую Macintosh и чаще встречаю имена файлов или каталогов с пробелами в них

find . -iname .svn -print0 | xargs -0 rm -rf 

"xargs" гарантирует, что "rm" вызывается только один раз каждые "N" файлы, где "N" обычно 20. Это не огромная победа в этом случае, потому что rm невелика, но если программа вам нужна для выполнения на каждом файле было большой или много обработки при запуске, это могло сделать вещи намного быстрее.

Ответ 3

может быть, это только я, но старый find и rm script не работает в моей текущей конфигурации, a la:

find/data/bin/test -type d -mtime +10 -name "[0-9] *" -exec rm -rf {} \;

тогда как решение xargs, a la:

find/data/bin/test -type d -mtime +10 -name '[0-9] *' -print | xargs rm -rf;

не знаю, почему, но я обновил свой скриптLib, поэтому я не трачу еще пару часов на избиение моя голова на чем-то так просто....

(запуск RHEL под ядром 2.6.18-194.11.3.el5)

РЕДАКТИРОВАТЬ: узнал, почему - мой RHEL distro по умолчанию vi вставляет страшный cr в разрывы строк (whch разрывает команду) - после предложений от nx5000 и jliagre на linuxquestions.org добавлено следующее на ~/.vimrc:

: установить fileformat = unix

map < F4 > : установить fileformat = unix <CR>

map < F5 > : set fileformat = dos <CR>

который позволяет поведению поворачиваться на F4/F5.

чтобы проверить, встроены ли CR в ваш файл:

head -1 scriptFile.sh | od -c | head -1

http://www.linuxquestions.org/questions/linux-general-1/bad-interpreter-no-such-file-or-directory-213617/

Ответ 5

Попробуйте

find . -iname .svn -exec rm -rf {} \;

и, вероятно, должен работать IIRC.

Ответ 6

Вы можете передать все, что хотите в кавычках, со следующим трюком.

find . -iname .svn -exec bash -c 'rm -rf {}' \;

Опция exec будет рада видеть, что вы просто вызываете исполняемый файл с аргументом, но ваш аргумент будет содержать script в основном любого размера и формы.

find . -iname .svn -exec bash -c '
  ls -l "{}" | wc -l
' \;