总括:
我如何运行 handbrakecli,获得进度和ETA,管道进入对话框而不闪烁。
细节:
我有一个脚本,可以查找目录中的所有视频文件,然后一次对它们运行 handbrakecli。每次 handbrakecli 运行时,它都会吐出一堆有关文件等的信息,然后是以下行:
Encoding: task 1 of 1, 3.30 % (295.53 fps, avg 303.23 fps, ETA 00h02m54s)
在我的脚本中,我将 handbrakecli 命令通过管道传输到其他一些命令,以过滤除进度之外的所有内容,然后将其通过管道传输到对话框,如下所示:
片段1
HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST" | \
stdbuf -o0 tr -s '\r' '\n' | \
stdbuf -o0 grep -oP '(?<=, )\d+(?=\.\d\d \%)' | \
dialog --gauge "$DIALOG_MSG" 10 70;
这很好用。它显示进度并且不闪烁。第二个任务是想出一种方法来显示进度和预计到达时间,这就是我想出的:
片段2
HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" | \
stdbuf -oL tr -s '\r' '\n' | \
while read -r str; do
local REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))");
local PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)");
echo "$PROGRESS" | dialog --gauge "$DIALOG_MSG Time remaining: $REMAINING" 10 70;
done
这有效,但对话框窗口闪烁。我不知道这是否与性能有关(对此表示怀疑),或者整个阅读时循环不能很好地与对话框配合使用。
我也尝试在不通过管道连接到对话框的情况下执行此操作,但只显示一次对话框,然后根本没有更新它。
片段3
HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" | \
stdbuf -oL tr -s '\r' '\n' | \
while read -r str; do
local REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))");
local PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)");
dialog --gauge "$DIALOG_MSG Time remaining: $REMAINING" 10 70 $PROGRESS;
done
最后我尝试了这个:
片段4
HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" | \
stdbuf -o0 tr -s '\r' '\n' | (
read -r str;
local REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))");
local PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)");
echo "$PROGRESS";
) | dialog --gauge "$DIALOG_MSG Time remaining: $REMAINING" 10 70;
但效果并不好。
我知道这里存在一些根本性的问题。
答案1
片段 2 最接近。将选择在输入中dialog --gauge
查找魔术标记,然后从下一行读取新的百分比,并从后面的行中读取新的提示,直到出现新标记。XXX
所以你应该得到你想要的:
HandBrakeCLI --preset "Normal" -i "$f" -o "$DEST_FULL_FILE" |
stdbuf -oL tr -s '\r' '\n' |
while read -r str
do
REMAINING=$(echo "$str" | grep -oP "(?<=ETA )\d\dh\d\dm\d\ds(?=\))")
PROGRESS=$(echo "$str" | grep -oP "(?<=, )\d+(?=.\d\d)")
echo -e "XXX\n$PROGRESS\n$DIALOG_MSG Time remaining: $REMAINING\nXXX"
done |
dialog --gauge "$DIALOG_MSG Time remaining: " 10 70;