При использовании 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
. +
Не нужно экранировать.