Понимание опции (-ключ) find (1) (фигурные скобки и знак плюс)

Используя следующую команду, может кто-то объяснить, что именно является целью для завершения фигурных скобок ({}) и знака плюс (+)?

И как команда будет действовать иначе, если они будут исключены из команды?

find . -type d -exec chmod 775 {} + 

  • Добавить путь к имени файла
  • Черный экран после запуска команды
  • Как найти файлы / каталоги с определенным списком ACL
  • Широкая поддержка поиска с помощью «-exec ... +»?
  • найти на множестве каналов, которые могут не существовать
  • лучшее использование find - rvm.sh
  • comm сбой при вводе переменной bash
  • Скопировать файлы в разные подкаталоги, исключающие строку
  • 2 Solutions collect form web for “Понимание опции (-ключ) find (1) (фигурные скобки и знак плюс)”

    Кудрявые фигурные скобки будут заменены результатами команды find , и chmod будет запущен на каждом из них. Команда + make пытается выполнить как можно меньше команд (так что chmod 775 file1 file2 file3 в отличие от chmod 755 file1 , chmod 755 file2 , chmod 755 file3 ). Без них команда просто дает ошибку. Все это объясняется в man find :

      -exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. -exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca‐ tions of the command will be much less than the number of matched files. 

    В дополнение к ответу тердона,

    • «Очевидно» -exec … должно быть завершено либо точкой с запятой ( ; ), либо знаком плюса ( + ). Точка с запятой – это особый символ в оболочке (или, по крайней мере, каждая оболочка, которую я когда-либо использовал), поэтому, если она должна использоваться как часть команды find , она должна быть экранирована или процитирована ( \; ";" , или ';' ).
    • С -exec … ; , строка {} может появляться любое количество раз в команде, включая ноль или два или более, в любой позиции. См. Это пример того, почему вы, возможно, захотите сделать -exec не используя {} . Наличие двух или более явлений полезно главным образом потому, что в (по крайней мере) некоторых версиях find {} не обязательно должно быть одним словом; он может иметь другие символы в начале или конце; например,

       find . -type f -exec mv {} {}.bak ";" 

      С -exec … + строка {} должна отображаться как последний аргумент перед символом + . Команда вроде

       find . -name "*.bak" -exec mv {} backup_folder + 

      приводит к загадочной find: missing argument to '-exec' сообщения об ошибке find: missing argument to '-exec' .

      • Обходной путь для этого, специфичный для команд cp и mv

         find . -name "*.bak" -exec mv -t backup_folder {} + 

        или

         find . -name "*.bak" -exec mv --target-directory=backup_folder {} + 

      {} Должно быть одним словом; он не может иметь других символов в начале или в конце. И, в (по крайней мере) некоторые версии find , у вас может быть не более одного {} .

    • Замечание о здравомыслии: вы можете сказать

        найти .  -name "* .sh" -type f -executable -exec {} необязательные аргументы здесь ";" 

      для запуска каждого из ваших сценариев. Но

        найти .  -name "* .sh" -type f -executable -exec {} + 

      запускает один из ваших сценариев, а имена всех остальных – как параметры. Это похоже на высказывание

       ./*.sh 

      как команда оболочки, кроме find не гарантирует, что он сортирует свои результаты, поэтому вам не гарантируется запуск aaa.sh (ваш первый по алфавиту файл *.sh ), как и при запуске ./*.sh .

    • Аспект find который может быть совершенно непонятным для новичков, заключается в том, что командная строка является, фактически, исполняемым заявлением на тайном языке. Например,

       find . -name "*.sh" -type f -executable -print 

      означает

       for each file if the file's name matches `*.sh` (ie, if it ends with `.sh`) then if it is a plain file (ie, not a directory) then if it is executable (ie, the appropriate `---x--x--x` bit is set) then print the file's name end if end if end if end loop 

      или, просто,

       for each file if the file's name matches `*.sh` AND it is a plain file AND it is executable then print the file's name end if end loop 

      Некоторые из ключевых слов являются исполняемым действием и тестом. В частности, это верно для -exec … ; ; например,

       find . -type f -exec grep -q cat {} ";" -print 

      переводит на

        для каждого файла
           если это простой файл (т. е. не каталог)
           тогда
               выполнить команду grep -q cat filename
               если процесс завершается успешно (т.е. выходит со статусом 0)
               тогда
                   распечатать имя файла
               конец, если
           конец, если
       конец петли 

      который будет печатать имена всех файлов, содержащих строку « cat ». И, хотя это то, что grep может сделать сам по себе (с опцией -l (нижний регистр L )), может быть полезно использовать его с find для поиска файлов, содержащих определенную строку И имеют определенный размер И принадлежащие определенному владельцу И были изменены в определенный временной диапазон, ….

      Однако это не работает для -exec … + . Поскольку -exec … + выполняет одну команду для нескольких файлов, нет смысла использовать ее в качестве логического условия внутри a for each file … loop.

    • Оборотная сторона вышесказанного заключается в том, что find обычно выходит с статусом выхода 0, если вы не передадите ему недопустимые аргументы или обнаруживает каталог, который он не может прочитать. Даже если программа, которую вы выполняете, завершается с ошибкой (завершается с ненулевым статусом выхода), find выйдет с статусом выхода 0. Если программа, которую вы выполняете с -exec … + не работает (завершается с ненулевым выходом status), find выйдет с ненулевым статусом выхода.

    В дополнение к миллионам версий find(1) и проверке того, что на самом деле find в нескольких системах, в базовых спецификациях Open Group Issue 7, 2013 Edition была предоставлена ​​некоторая информация о том, что find должен, может и не должен делать.

    Linux и Unix - лучшая ОС в мире.