Как {} и + раскрываются внутри find с опцией -execdir

Как {} и + раскрываются внутри find с опцией -execdir

При использовании findпрограммы с -execdirопцией я видел, как люди говорили, что {}будет заменено на каталог, а +на имя файла, но в руководстве не говорится, что они делают. Есть ли какая-то официальная документация, которая это объясняет? Также я хочу узнать, расширяются ли они как относительные или абсолютные пути. Я попытался создать скрипт, который будет принимать и {}как +параметры и сохранять их содержимое в отдельных файлах. Я предполагал, что они будут передаваться как два отдельных параметра, и это позволит мне увидеть, как каждый из них расширяется, но результаты, которые я получаю, заставляют думать, что скрипту передается только один параметр, поэтому я все еще не могу полностью доказать себе, что это такое и как они расширяются.

Вот команда, которую я запускаю:find '/home/jesse/hacking/sh_sandbox' -type f -execdir /home/jesse/hacking/sh_sandbox/save_params.sh {} +

Скрипт save_params.sh — это исполняемый скрипт оболочки со следующим кодом:

echo $0 >> /home/jesse/hacking/sh_sandbox/zero_param.txt
echo $1 >> /home/jesse/hacking/sh_sandbox/first_param.txt
echo $2 >> /home/jesse/hacking/sh_sandbox/second_param.txt
echo $3 >> /home/jesse/hacking/sh_sandbox/third_param.txt

Текстовый файл zero_param заполняется именем исполняемого скрипта, что и ожидалось. Файл first_param.txt заполняется ./filenameразными именами файлов. Текстовые файлы second_param и third_param заполнены пустыми строками, каждый с тем же количеством строк, что и другие файлы. Это наводит меня на мысль, что второй параметр не передается в save_params.sh.

решение1

+является конечным маркером, {}заменяется именами файлов, текущим каталогом является путь.

так

  • $PWD"="/home/jesse/hacking/sh_sandbox/
  • $0"="/home/jesse/hacking/sh_sandbox/save_params.sh
  • $1"="./zero_param.txt
  • $2"="./first_param.txt
  • $3"="./second_param.txt
  • $4"="./third_param.txt

или что-то в этом роде... перечитывая вопрос, кажется, что скрипт написан для изменения каталога, в котором выполняется поиск, так что на самом деле все может быть сложнее.

при первом запуске найден только один файл

  • $PWD"="/home/jesse/hacking/sh_sandbox/
  • $0"="/home/jesse/hacking/sh_sandbox/save_params.sh
  • $1"="./save_params.sh

поэтому файлы будут созданы с содержанием, отражающим это.

решение2

find ... -execdir command {} +ничего подобного не делает.

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

Запустите man find(или, если используете GNU find, info findили pinfo findдля получения более подробной документации) и найдите -execdir.

Из страницы руководства GNU find:

-execdir command ;

-execdir command {} +

Как и -exec, но указанная команда запускается из подкаталога, содержащего совпадающий файл, который обычно не является каталогом, в котором вы начали find. Это гораздо более безопасный метод вызова команд, поскольку он позволяет избежать условий гонки во время разрешения путей к совпавшим файлам.

Как и в случае с -execдействием, +форма -execdirсоздаст командную строку для обработки более одного соответствующего файла, но любой вызов команды выведет только список файлов, которые существуют в том же подкаталоге.

Если вы используете эту опцию, вы должны убедиться, что ваша $PATHпеременная окружения не ссылается на .; в противном случае злоумышленник может выполнить любые команды по своему усмотрению, оставив соответствующим образом названный файл в каталоге, в котором вы будете запускать -execdir.

То же самое относится к $PATHпустым записям или записям, которые не являются абсолютными именами каталогов. Если find обнаруживает ошибку, это иногда может привести к немедленному выходу, поэтому некоторые ожидающие команды могут вообще не быть запущены.

Результат действия зависит от того, используется ли вариант + или ; всегда возвращает true, тогда как возвращает true только в том случае, если команда возвращает 0.;-execdir command {} +-execdir command {} ;

Обратите внимание, что, хотя в отрывке из страницы руководства об этом не упоминается, необходимо ;экранировать, как \;при запуске из командной строки оболочки или скрипта, чтобы оболочка не интерпретировала его как конец команды find, а не передала в качестве аргумента для findуказания конца findкоманды -exec. +Не нужно экранировать.

Связанный контент