将 `while` 替换为更合适的函数,以便循环将等待每个进程结束

将 `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].mkv' \) -print |
while IFS= read file    ## IFS= prevents "read" stripping whitespace
do
    ffmpeg -i "$file" "$target" && rm -rf "$file"
done

问题是,因为 ffmpeg 响应时间太长,并且while只会继续列出和执行。所以我希望我能做些什么来确保循环仅在done结束后才进行处理?

有人可以帮忙吗?谢谢!

天哪,我不知道为什么它被标记为可能与我的另一个问题重复:将“for file in”转换为“find”,以便我的脚本可以递归应用

我要求一个循环操作,允许我的 bash 脚本等待循环内的每个函数完成,然后再迭代到下一个对象。这远不是询问如何find递归归档。谢谢!

答案1

您可以遍历中间文件,而不是通过管道将 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 parallel 一起使用就可以完成这项工作。

答案2

代码无法正常运行的原因是初始find命令中 AND 和 OR 组不匹配:

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
  • OR(名称 *.mov 且名称 NOT *-[900p-by-ZiriusPH].mkv )

最后一个条件对于许多文件都是成立的,我怀疑这不是你想要的。如果将 AND NOT 条件移到括号中的 OR 条件之外,您会发现它按您的预期工作。

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

相关内容