为 Zenity 进度格式化管道 rsync 输出
Formatting piped rsync output for Zenity progress
我正在执行 rsync 过程以从 SD 卡复制文件,我想在每个文件的 rsync 过程中显示 Zenity 中每个文件的进度。我尝试了 Zenity and rsync,这对我来说似乎很完美。它应该发送当前文件并将 % 复制到 Zenity,但我无法获取它,输出不是实时的并且不会移动进度条。而且我不明白为什么它不起作用。
我至少要做的是将文件副本的百分比发送到 Zenity 以驱动进度条。但这需要是一个没有尾随 % 的数字来驱动进度条。
这不会输出任何内容,但如果我删除 sed 和 Zenity 步骤,我会得到:0%、1%、2% 等。但是 Zenity 需要非百分比值。
sudo rsync -av --info=progress2 "$f"/*.MP4 $copydest | \
strace -e trace=read grep "[0-9]*%" 2>&1 > /dev/null | grep -o "[[:digit:]]*%" | sed 's/[^0-9]//g' | \
zenity --width=400 --height=20 --progress --percentage=0 --text="Copying...." --auto-close --auto-kill \
--title="Copying $tc from $cardname"
理想情况下,我也希望显示当前文件名,但我卡住了。例如,
Filename.MP4
.......... (progress)
在 grep 或 sed 或 awk 中必须有一个方法,我可以获取 MP4 文件名和作为数字复制的百分比,但它超出了我的范围。
这是 rsync 将在 3 个文件上输出的内容,其中 % 和剩余时间递增等
25_nn67_P1680210.MP4
1,024,202,031 100% 163.00MB/s 0:00:05 (xfr#1, to-chk=2/3)
25_nn67_P1680211.MP4
146,801,421 100% 49.12MB/s 0:00:02 (xfr#2, to-chk=1/3)
25_nn67_P1680212.MP4
一个相对简单的选项是捕获当前文件,当前文件的百分比:
rsync -av --info=progress2 ... |
tr '\r' '\n' |
awk '/^ / { print int(+) ; next } [=10=] { print "# " [=10=] }' |
zenity --progress ...
显示整体完成率更具挑战性。这将需要 运行ning rsync 两次 - 一次在 dry-运行 模式下,计算要移动的文件数,然后使用文件数计算进度百分比。
不用说,这会稍微增加实际副本的延迟。
下面的代码假定所有文件都需要相同的时间来复制。它需要一些工作来执行文件计数的实际估计,因为日志包含很少的其他消息(总字节数等)。
(
echo "5" ; echo "Calculate job Size"
file_count=$(rsync --dry-run -av feature_files/ fff/ | wc -l)
echo "F=$file_count"
rsync -av --info=progress2 feature_files/ fff/ |
tr '\r' '\n' |
awk -v "total=$file_count" '
/^ / { print 100*(count+/100)/total ; next }
[=10=] { print "# " [=10=] ; count++ ; print 100*count/total }
'
) | zenity --progress ...
好的,我修复了它,非常感谢 dash-o 提供的格式化帮助 - 辛苦了。
问题出在管道缓冲上,因此 Zenity 在缓冲区已满之前无法获取任何数据——这可能从来没有出现过我 运行 的测试文件集。
您需要将管道中所有步骤的缓冲区(在 zenity 之前)设置为 0:
sudo rsync -av --info=progress2 "$f"/*.MP4 $copydest | \
stdbuf -i0 -o0 -e0 tr '\r' '\n' | stdbuf -i0 -o0 -e0 awk -W interactive -f /path/to/rsync.awk | zenity --progress --width=400 --text="Copying...." --auto-close --title="Copying $cardname"
然后在 rsync.awk 中(它可能不需要额外的文件就可以工作)添加 fflush() 确保它刷新。
#!/bin/sh
/^ / { print int(+) ; fflush() ; next } [=11=] { print "# " [=11=] }
所以现在,执行 rsync(通过先前的 Zenity 对话)导致进度 window,其中包含当前文件名和移动进度条,同时 Rsync 复制每个文件 - 注意:不是整体进度,而是对于每个复制的文件。
现在我的脚本在插入包含 MP4 文件的 SD 卡时触发,并使用 rsync 进行复制,并显示工作进度条。
我正在执行 rsync 过程以从 SD 卡复制文件,我想在每个文件的 rsync 过程中显示 Zenity 中每个文件的进度。我尝试了 Zenity and rsync,这对我来说似乎很完美。它应该发送当前文件并将 % 复制到 Zenity,但我无法获取它,输出不是实时的并且不会移动进度条。而且我不明白为什么它不起作用。
我至少要做的是将文件副本的百分比发送到 Zenity 以驱动进度条。但这需要是一个没有尾随 % 的数字来驱动进度条。
这不会输出任何内容,但如果我删除 sed 和 Zenity 步骤,我会得到:0%、1%、2% 等。但是 Zenity 需要非百分比值。
sudo rsync -av --info=progress2 "$f"/*.MP4 $copydest | \
strace -e trace=read grep "[0-9]*%" 2>&1 > /dev/null | grep -o "[[:digit:]]*%" | sed 's/[^0-9]//g' | \
zenity --width=400 --height=20 --progress --percentage=0 --text="Copying...." --auto-close --auto-kill \
--title="Copying $tc from $cardname"
理想情况下,我也希望显示当前文件名,但我卡住了。例如,
Filename.MP4
.......... (progress)
在 grep 或 sed 或 awk 中必须有一个方法,我可以获取 MP4 文件名和作为数字复制的百分比,但它超出了我的范围。
这是 rsync 将在 3 个文件上输出的内容,其中 % 和剩余时间递增等
25_nn67_P1680210.MP4
1,024,202,031 100% 163.00MB/s 0:00:05 (xfr#1, to-chk=2/3)
25_nn67_P1680211.MP4
146,801,421 100% 49.12MB/s 0:00:02 (xfr#2, to-chk=1/3)
25_nn67_P1680212.MP4
一个相对简单的选项是捕获当前文件,当前文件的百分比:
rsync -av --info=progress2 ... |
tr '\r' '\n' |
awk '/^ / { print int(+) ; next } [=10=] { print "# " [=10=] }' |
zenity --progress ...
显示整体完成率更具挑战性。这将需要 运行ning rsync 两次 - 一次在 dry-运行 模式下,计算要移动的文件数,然后使用文件数计算进度百分比。
不用说,这会稍微增加实际副本的延迟。
下面的代码假定所有文件都需要相同的时间来复制。它需要一些工作来执行文件计数的实际估计,因为日志包含很少的其他消息(总字节数等)。
(
echo "5" ; echo "Calculate job Size"
file_count=$(rsync --dry-run -av feature_files/ fff/ | wc -l)
echo "F=$file_count"
rsync -av --info=progress2 feature_files/ fff/ |
tr '\r' '\n' |
awk -v "total=$file_count" '
/^ / { print 100*(count+/100)/total ; next }
[=10=] { print "# " [=10=] ; count++ ; print 100*count/total }
'
) | zenity --progress ...
好的,我修复了它,非常感谢 dash-o 提供的格式化帮助 - 辛苦了。 问题出在管道缓冲上,因此 Zenity 在缓冲区已满之前无法获取任何数据——这可能从来没有出现过我 运行 的测试文件集。 您需要将管道中所有步骤的缓冲区(在 zenity 之前)设置为 0:
sudo rsync -av --info=progress2 "$f"/*.MP4 $copydest | \
stdbuf -i0 -o0 -e0 tr '\r' '\n' | stdbuf -i0 -o0 -e0 awk -W interactive -f /path/to/rsync.awk | zenity --progress --width=400 --text="Copying...." --auto-close --title="Copying $cardname"
然后在 rsync.awk 中(它可能不需要额外的文件就可以工作)添加 fflush() 确保它刷新。
#!/bin/sh
/^ / { print int(+) ; fflush() ; next } [=11=] { print "# " [=11=] }
所以现在,执行 rsync(通过先前的 Zenity 对话)导致进度 window,其中包含当前文件名和移动进度条,同时 Rsync 复制每个文件 - 注意:不是整体进度,而是对于每个复制的文件。
现在我的脚本在插入包含 MP4 文件的 SD 卡时触发,并使用 rsync 进行复制,并显示工作进度条。