Bash 读取 rsync 进度并在太慢时放弃文件的脚本
Bash script that reads rsync progress and bails on the file if too slow
我对 bash 脚本编写的经验太少了,这很可笑。
我花了 3 天时间将文件从我 NAS 上发生故障的硬盘驱动器(LVM 中的 3 个硬盘驱动器中的 1 个)传输到新硬盘驱动器。大多数(按百分比计算)文件传输正常,但许多(数千)文件受到影响,而不是因 i/o 错误而失败,它们将速度降低到令人痛苦的速度。
我使用的是一个简单的 cp 命令,但后来我切换到 rsync 并使用 --progress 选项至少能够确定发生这种情况的时间。
目前,我正在手动观看屏幕(当我们谈论 DAYS 时很糟糕),挂断时 ^C,然后复制文件名并将其粘贴到排除文件中并重新启动 rsync。
我需要来自动化!
我对 bash 脚本一无所知,但我想我可能 "watch" 标准输出,解析速率信息并使用这样的逻辑:
if rate is less than 5Mbps for 3 consecutive seconds, bail and restart
这是我正在使用的 rsync 命令:
rsync -aP --ignore-existing --exclude-from=EXCLUDE /mnt/olddisk/ /mnt/newdisk/
这是进度的示例输出:
path/to/file.ext
3434,343,343 54% 144.61MB/s 0:00:05 (xfr#1, ir-chk=1024/1405)
因此解析第 2 行的第 3 列并确保它不会太慢,如果太慢则终止命令,将文件名附加到 EXCLUDE 并再试一次。
有人可以帮我吗?
这是一种糟糕的方法,我不希望它能有效地解决您的问题。但是,以下是对您问题的字面回答。
#!/usr/bin/env bash
[[ ]] || {
echo "Usage: rsync -P --exclude=exclude-file ... | [=10=] exclude-file" >&2
exit 1
}
is_too_slow() {
local rate=
case $rate in
*kB/s) return 0 ;;
[0-4][.]*MB/s) return 0 ;;
*) return 1 ;;
esac
}
exclude_file=
last_slow_time=0
filename=
too_slow_count=0
while IFS=$'\n' read -r -d $'\r' -a pieces; do
for piece in "${pieces[@]}"; do
case $piece in
"sending incremental file list") continue ;;
[[:space:]]*)
read -r size pct rate time <<<"$piece"
if is_too_slow "$rate"; then
if (( last_slow_time == SECONDS )); then
continue # ignore multiple slow results in less than a second
fi
last_slow_time=$SECONDS
if (( ++too_slow_count > 3 )); then
echo "$filename" >>"$exclude_file"
exit 1
fi
else
too_slow_count=0
fi
;;
*) filename=$piece; too_slow_count=0 ;;
esac
done
done
我对 bash 脚本编写的经验太少了,这很可笑。
我花了 3 天时间将文件从我 NAS 上发生故障的硬盘驱动器(LVM 中的 3 个硬盘驱动器中的 1 个)传输到新硬盘驱动器。大多数(按百分比计算)文件传输正常,但许多(数千)文件受到影响,而不是因 i/o 错误而失败,它们将速度降低到令人痛苦的速度。
我使用的是一个简单的 cp 命令,但后来我切换到 rsync 并使用 --progress 选项至少能够确定发生这种情况的时间。
目前,我正在手动观看屏幕(当我们谈论 DAYS 时很糟糕),挂断时 ^C,然后复制文件名并将其粘贴到排除文件中并重新启动 rsync。
我需要来自动化!
我对 bash 脚本一无所知,但我想我可能 "watch" 标准输出,解析速率信息并使用这样的逻辑:
if rate is less than 5Mbps for 3 consecutive seconds, bail and restart
这是我正在使用的 rsync 命令: rsync -aP --ignore-existing --exclude-from=EXCLUDE /mnt/olddisk/ /mnt/newdisk/
这是进度的示例输出:
path/to/file.ext
3434,343,343 54% 144.61MB/s 0:00:05 (xfr#1, ir-chk=1024/1405)
因此解析第 2 行的第 3 列并确保它不会太慢,如果太慢则终止命令,将文件名附加到 EXCLUDE 并再试一次。
有人可以帮我吗?
这是一种糟糕的方法,我不希望它能有效地解决您的问题。但是,以下是对您问题的字面回答。
#!/usr/bin/env bash
[[ ]] || {
echo "Usage: rsync -P --exclude=exclude-file ... | [=10=] exclude-file" >&2
exit 1
}
is_too_slow() {
local rate=
case $rate in
*kB/s) return 0 ;;
[0-4][.]*MB/s) return 0 ;;
*) return 1 ;;
esac
}
exclude_file=
last_slow_time=0
filename=
too_slow_count=0
while IFS=$'\n' read -r -d $'\r' -a pieces; do
for piece in "${pieces[@]}"; do
case $piece in
"sending incremental file list") continue ;;
[[:space:]]*)
read -r size pct rate time <<<"$piece"
if is_too_slow "$rate"; then
if (( last_slow_time == SECONDS )); then
continue # ignore multiple slow results in less than a second
fi
last_slow_time=$SECONDS
if (( ++too_slow_count > 3 )); then
echo "$filename" >>"$exclude_file"
exit 1
fi
else
too_slow_count=0
fi
;;
*) filename=$piece; too_slow_count=0 ;;
esac
done
done