find -exec с функцией в bash скрипте
Суть вопроса. Есть bash-скрипт в котором я объявил функцию printtestpath.
function printtestpath(){
echo "Im working $1"
}
по одиночке функция запускается прекрасно.
printtestpath "/test/path"
мне нужно чтобы параметр, который попадает в функцию брался из find на каждом этапе поиска файла. Т.е. нашел 1 файл, запустил функцию 1 раз. Нашел ещё файл ещё раз запустил функцию.
find -type f -exec printtestpath {} \;
логичным выводом сделать для поиска атрибут -exec но входе этого появляется ошибка:
find: ‘printtestpath’: Нет такого файла или каталога
есть ли возможность это как-то исправить?
ps. Вывод из find в файл, а потом чтение из файла с запуском функции работает недостаточно быстро
Ответы (1 шт):
find -type f -exec cmd args ... внутри себя делает fork и порождает процесс с исполняемым файлом cmd и параметрами argv сконструированными из args ...
Функция printtestpath задана внутри bash и не является исполняемым файлом. Именно об этом вам сообщает find ‘printtestpath’: Нет такого файла или каталога
План А: Вам нужно сделать бинарник или скрипт с именем printtestpath. Сразу скажу, что это будет сравнительно неторопливый вариант, так как отдельный процесс будет порождаться для каждого файла.
План Б: написать цикл, как предложил @Fat-Zer. Я бы делал именно так, если обработка одноразовая. Этот вариант довольно быстро работает, если в printtestpath не создаются процессы (то есть не запускаются программы).
План В: если вы боретесь за высокую скорость, то переписать скрипт на python. Что-нибудь вроде
import os
import os.path
def printtestpath(path):
print(f"Im working {path}")
for subdir, _, subdir_files in os.walk('.'):
for fname in subdir_files:
fullname = os.path.join(subdir, fname)
printtestpath(fullname)
Так как библиотеки Python позволяют очень многое без запуска внешних процессов, то в большинстве случаев сложная обработка файлов на Python будет быстрее, чем средствами bash и утилит. Я бы делал так, если бы нужен был скрипт, который будет исполняться в будущем много раз. Потерять некоторое время на разработку, зато сэкономить в будущем на запусках.