gpt4 book ai didi

linux - 在 bash 脚本中执行命令,直到输出超过特定值

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:38:46 26 4
gpt4 key购买 nike

我使用一个命令来解析特定帧的视频文件,并在找到时返回它们的时间码。目前,我必须执行命令,等待,直到打印到 stdout 的值达到所需位置,然后使用 Ctrl+C 中止执行。

因为我必须观察过程并在适当的时候中止执行以获得我需要的信息,所以我想,我可以通过创建一个 bash 脚本在某种程度上自动化它。

我不确定,如果它可以在 bash 中完成,因为我不完全知道,如何中止与它写入标准输出的值相关的执行。

命令的输出看起来像

0.040000
5.040000
10.040000
15.040000
18.060000
(...)

我试过了

until [[ "$timecode" -gt 30 ]]; do
timecode=$(mycommand)
sleep 0.1
done

echo "Result: $timecode"

while [[ "$timecode" -le 30 ]]; do
timecode=$(mycommand)
sleep 0.1
done

echo "Result: $timecode"

这两者似乎都导致命令被执行直到它完成,然后循环的其余部分被处理。但我想在命令执行时评估输出并根据输出中断执行。

附加信息

该命令无法在流中的特定点停止。它解析整个文件并给出结果,除非发出停止信号。这是我的第一枪。

命令的执行时间很长,因为我解析的文件是~2GB。由于我不需要文件的所有帧,只需要给定时间码周围的几帧,所以我从不让它执行直到完成。

命令的输出因文件而异,因此我无法查找确切的值。如果我知道确切的值,我可能就不必寻找它了。

目标时间代码 - 在示例中由“-gt 30”指定 - 对于我必须解析的每个文件都是不同的,因此一旦脚本运行,我必须将其放入命令行参数。我还必须确保返回的不仅仅是执行的最后一个值,而是大约最后 5 个值。对于这两个我已经有了想法。

我完全被那个问题困住了,甚至不知道要用谷歌搜索什么。

感谢您的参与!

曼纽尔


通过 PSkocik 和 Kyle Burton 的回答,我能够将建议的解决方案整合到我的脚本中。它不起作用,我不明白为什么。

这里是完整的脚本,包括提供输出的外部命令:

 #!/usr/bin/env bash
set -eu -o pipefail

parser () {
local max="$1"
local max_int

max_int="${max%.*}"

while read tc;
do
local tc_int
tc_int="${tc%.*}"
echo $tc

if (( "$tc_int" >= "$max_int" )); then
echo "Over 30: $tc";
exec 0>&-
return 0
fi

done
}

ffprobe "$1" -hide_banner -select_streams v -show_entries frame=key_frame,best_effort_timestamp_time -of csv=nk=1:p=0:s="|" -v quiet | sed -ne "s/^1|//p" | parser 30

我没有从“echo $tc”获得任何输出,但 ffprobe 正在运行 - 我可以在顶部看到它。它会一直运行,直到我使用 Ctrl+C 停止脚本。


感谢凯尔为此付出的巨大努力。我永远不会得出这样的结论。我根据您的建议更改了 ffprobe 的命令行

 ffprobe "$1" -hide_banner -select_streams v -show_entries frame=key_frame,best_effort_timestamp_time -of csv=nk=1:p=0:s="|" -v quiet | cut -f2 -d\| | parser 30

现在,我在 ffprobe 运行时得到结果。但是...您更改命令的方式返回所有帧,ffprobe 发现而不仅仅是关键帧。 ffprobe 命令的原始输出看起来像

 1|0.000000
0|0.040000
0|0.080000
0|0.120000
0|0.160000
0|0.200000
(...)

行首的 0 表示:这不是关键帧。行首的 1 表示:这是一个关键帧。

该脚本旨在仅提供视频文件特定时间码周围的关键帧。您更改命令的方式,它现在提供视频文件的所有帧,这使得结果输出无用。必须过滤掉所有以零开头的行。

由于我不太明白,为什么这不适用于 sed,我只能尝试通过试错法找到解决方案,以便于使用不同的工具来过滤输出。但如果过滤本身导致问题,我们可能会在这里碰壁。

最佳答案

如果您有进程 a 将内容输出到标准输出,进程 b 通过管道读取输出的内容:

a | b

all b 通常必须在输出某个项目时杀死 a就是关闭它的标准输入。

样本b:

b()
{
while read w;
do case $w in some_pattern)exec 0>&-;; esac;
echo $w
done
}

stdin(文件描述符 0)的关闭将导致生产者进程在尝试进行下一次写入时被 SIGPIPE 杀死。

关于linux - 在 bash 脚本中执行命令,直到输出超过特定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45304233/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com