замените `while` более подходящей функцией, поэтому цикл будет ждать завершения каждого процесса

У меня есть сценарий bash, который рекурсивно ищет файлы в папках с несколькими подписями, а затем используйте ffmpeg для каждого файла. при отладке он отлично работает, если я использую echo ffmpeg но дело в том, что на реальной работе, где на самом деле нужно использовать ffmpeg и ждать полчаса, чтобы закончить для каждого видео, сценарий bash не может успешно запустить ffmpeg для каждого файла

Мой фрагмент ниже:

 find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' ! -name '*-[900p-by-ZiriusPH].mkv' \) -print | while IFS= read file ## IFS= prevents "read" stripping whitespace do ffmpeg -i "$file" "$target" && rm -rf "$file" done 

дело в том, потому что ffmpeg занимает слишком много времени, чтобы отвечать, и в while же while просто продолжал перечислять и выполнять. Поэтому я надеюсь, что я могу сделать, чтобы убедиться, что цикл будет процессом только после того, как done закончится?

Может ли кто-нибудь помочь? Благодаря!

Geez, я не знаю, почему он был помечен как возможный дубликат с другим моим вопросом: Преобразование `для файла в` to `find`, чтобы мой скрипт мог применяться рекурсивно

Я прошу действия цикла, которые позволят моему сценарию bash дождаться завершения каждой функции внутри цикла до ее повторения к следующему объекту. Это очень далеко не вопрос, как find файлы рекурсивно. Благодаря!

Вместо того, чтобы находить трубку в цикле, вы можете пройти через промежуточный файл. Это гарантирует, что шаг поиска и шаг петли происходят последовательно, без перекрытия. Что-то вроде следующего (я изменил ваше выражение для краткости):

 find \( -name '*.mkv' -o -name '*avi' \) >files <files while IFS= read file do ffmpeg -i "$file" "$target" && rm -f "$file" done 

Обратите внимание, что это все еще не полностью безопасно; использование find -exec было бы проще, если бы ваши требования не включали запуск find строго до первого вызова ffmpeg . С этим требованием использование find -print0 вместе с xargs или GNU-параллелью могло бы выполнить эту работу.

Причина, по которой код не работает должным образом, – это несоответствие групп AND и OR в исходной команде find :

 find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' ! -name '*-[900p-by-ZiriusPH].mkv' \) -print 

Связывание параметров – это распечатать файлы, сопоставленные для

  • Имя * .mkv
  • ИЛИ Имя * .avi
  • ИЛИ Имя * mp4
  • ИЛИ Имя * flv
  • ИЛИ Имя * .ogg
  • ИЛИ Имя * .ogg
  • ИЛИ (Имя * .mov И имя NOT * – [900p-by-ZiriusPH] .mkv)

Последнее условие будет верно для многих файлов, которые, как я подозреваю, не то, что вы хотели. Если вы перемещаете условие AND NOT за пределы условий, заключенных в скобки, вы обнаружите, что оно работает так, как вы ожидали.

 find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! -name '*-[900p-by-ZiriusPH].mkv' -print