Во-первых, не обрабатывайте динамически сгенерированные списки файлов в цикле for
.
Во-вторых, ваш код поврежден - у вас 2 done
.
В-третьих,Приношу свои извинения, не знаком с инструментом, но я склонен думать, что ваша проблема в более широком фрагменте кода, чем представлен.
В-четвертых, (получая незначительные и придирчивые :) предпочитаю $(
... )
через кавычки.Очень редко есть причина не делать этого в bash.
Тем не менее, почти ничего из этого не имеет отношения к вашему вопросу, кроме, возможно, третьей вещи ... Посмотрите, поможет ли это -
find . -name "*.jpg" -type f |
while read -r file; do jpegoptim "$file"; done >> jpg.log 2>&1
Или, может быть, лучше,
find . -name "*.jpg" -type f | xargs jpegoptim >> jpg.log 2>&1
Обновление
Бенджамин У. указывает, что они ломаются, когда имена файлов имеют встроенные символы новой строки,что совершенно верно.Я считаю, что имена файлов со встроенными символами новой строки являются отвратительной ересью высшего порядка, но иногда вы не можете это контролировать, поэтому, согласно его совершенно обоснованному предложению:
find . -name "*.jpg" -type f |
while read -r -d '' file; do jpegoptim "$file"; done >> jpg.log 2>&1
или
find . -name "*.jpg" -type f -print0 | xargs -0 jpegoptim >> jpg.log 2>&1
или лучше всего, для простоты и (следовательно) безопасности
find . -name "*.jpg" -type f -exec jpegoptim {} \; >> jpg.log 2>&1
(Пожалуйста, проверьте мой синтаксис по этим ...)
Хотя есть еще соображения эффективности, если вы обрабатываете большое количествофайлов.Следует также учитывать возможность того, что целевая программа может или не может быть в состоянии обрабатывать аргументы командной строки.Рассмотрим разницу между ними:
$: find /tmp -type f -exec echo {} \;
/tmp/.mintty-version
/tmp/AdobeARM.log
/tmp/foo
. . .
$: find /tmp -type f | xargs echo
/tmp/.mintty-version /tmp/AdobeARM.log /tmp/foo ...