find -exec против -exec {} +: почему одна команда может быть в десятки раз быстрее
Многие используют find так:
find /var/log -name "*.log" -exec gzip {} \;
Команда работает, но есть нюанс: для каждого найденного файла запускается отдельный процесс gzip.
▪️Что происходит
Если найдено 5000 файлов, Bash выполнит примерно 5000 запусков gzip.
Это лишние создания процессов, переключения контекста и заметная потеря производительности.
▪️Более эффективный вариант
find /var/log -name "*.log" -exec gzip {} +
Теперь find собирает несколько файлов и передаёт их одной команде:
gzip file1.log file2.log file3.log ...
Количество запусков сокращается в десятки или даже сотни раз.
▪️В чём разница
Вариант с \;:
gzip file1
gzip file2
gzip file3
Вариант с +:
gzip file1 file2 file3
Логика обработки не меняется, но накладные расходы становятся значительно меньше.
▪️Когда + использовать нельзя
Если команда должна выполняться отдельно для каждого файла, например:
find . -type f -exec mv {} {}.bak \;
или внутри используется сложная оболочка:
find . -type f -exec sh -c '...' \;
В таких случаях объединение аргументов может изменить поведение команды.
▪️Как выбрать
Используйте -exec {} +, когда команда умеет принимать сразу несколько файлов:
rm
chmod
chown
gzip
cp
mv (при копировании в каталог)
ls
Если же обработка должна происходить строго по одному файлу — остаётся -exec {} \;.
▪️Почему это важно
Во многих скриптах find -exec {} \; используется по привычке. Замена всего одного символа — \; на + - позволяет значительно сократить число создаваемых процессов и ускорить обработку больших каталогов без изменения логики скрипта.
BashTex 📱 #bash #linux
Многие используют find так:
find /var/log -name "*.log" -exec gzip {} \;
Команда работает, но есть нюанс: для каждого найденного файла запускается отдельный процесс gzip.
▪️Что происходит
Если найдено 5000 файлов, Bash выполнит примерно 5000 запусков gzip.
Это лишние создания процессов, переключения контекста и заметная потеря производительности.
▪️Более эффективный вариант
find /var/log -name "*.log" -exec gzip {} +
Теперь find собирает несколько файлов и передаёт их одной команде:
gzip file1.log file2.log file3.log ...
Количество запусков сокращается в десятки или даже сотни раз.
▪️В чём разница
Вариант с \;:
gzip file1
gzip file2
gzip file3
Вариант с +:
gzip file1 file2 file3
Логика обработки не меняется, но накладные расходы становятся значительно меньше.
▪️Когда + использовать нельзя
Если команда должна выполняться отдельно для каждого файла, например:
find . -type f -exec mv {} {}.bak \;
или внутри используется сложная оболочка:
find . -type f -exec sh -c '...' \;
В таких случаях объединение аргументов может изменить поведение команды.
▪️Как выбрать
Используйте -exec {} +, когда команда умеет принимать сразу несколько файлов:
rm
chmod
chown
gzip
cp
mv (при копировании в каталог)
ls
Если же обработка должна происходить строго по одному файлу — остаётся -exec {} \;.
▪️Почему это важно
Во многих скриптах find -exec {} \; используется по привычке. Замена всего одного символа — \; на + - позволяет значительно сократить число создаваемых процессов и ускорить обработку больших каталогов без изменения логики скрипта.
BashTex 📱 #bash #linux