![如果之前的输出包含特定字符串,我需要自动重新运行命令](https://linux22.com/image/167228/%E5%A6%82%E6%9E%9C%E4%B9%8B%E5%89%8D%E7%9A%84%E8%BE%93%E5%87%BA%E5%8C%85%E5%90%AB%E7%89%B9%E5%AE%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E6%88%91%E9%9C%80%E8%A6%81%E8%87%AA%E5%8A%A8%E9%87%8D%E6%96%B0%E8%BF%90%E8%A1%8C%E5%91%BD%E4%BB%A4.png)
我已经构建了一个 After Effects 渲染农场,它使用 adobe 终端命令“aerender”。我让它在两台 Mac Pro 上运行,总共有 24 个 aerender 实例。
它工作得很好,但偶尔渲染实例会失败(由于原因),我需要敲击键盘来重新运行命令。我基本上必须照顾每个渲染,这显然不理想。如果我在一天中检测到错误,我宁愿让它自动重新启动。
我尝试过使用双管||如果当前渲染失败则启动另一次渲染,但这不起作用,因为当 aerender 失败时,它仍然以干净的方式退出到终端。仅当我 Control-C 当前渲染时,双管才起作用。
我的渲染命令是...
/Applications/Adobe\ After\ Effects\ 2020/aerender -project "/Volumes/Videos/Test.aep" -sound ON
如果渲染失败,它会显示类似...
WARNING:After Effects warning: logged 2 errors, please check log.
我假设我需要使用 grep 来搜索输出"WARNING:After Effects warning"
我还假设我需要将我的初始命令包装在另一个命令中来监视这个字符串。
我有点迷失了。任何帮助,将不胜感激。
答案1
OP 也想看到输出,所以我们需要一个小脚本
#!/bin/bash
exec 3>&1 # Make a copy of the stdout fd on fd 3
while "/Applications/Adobe After Effects 2020/aerender" -project "/Volumes/Videos/Test.aep" -sound ON |
tee /dev/fd/3 |
grep 'WARNING:After Effects warning' >/dev/null
do
echo "Repeating the command"
done
这里发生了一些事情,我正在猜测 macOS 上支持什么。这exec
使得 fd 3 与脚本的标准输出相同。我希望 Macos 可以将其作为 /dev/fd/3 提供。tee
用于将 aerender 输出的副本发送到此,因此脚本输出与原始代码相同的内容。
然后将 tee 的输出提供给 grep。我故意不使用,grep -q
因为一旦它看到第一个匹配模式,它就会停止处理,这可能导致tee
获得 SIGPIPE,这可能导致 aerender 获得 SIGPIPE。如果 aerender 不会创建太多输出,并且仅在一次输出消息,这会使您过于谨慎,但也没有什么坏处。
如果macos不支持/dev/fd/3,那么可以尝试
#!/bin/bash
while O="$("/Applications/Adobe After Effects 2020/aerender" -project "/Volumes/Videos/Test.aep" -sound ON)"
echo "$O"
echo "$O" | grep 'WARNING:After Effects warning' >/dev/null
do
echo "Repeating the command"
done
这样做的缺点是,aerender 的所有 stderr 都会被输出,然后所有的 stdout 也会被输出,而不是按照预期的交错方式输出。
所有这些都未经测试,因为我没有合适的系统来尝试。