我对bash脚本的经验很少,以至于很可笑。
我花了3天时间将文件从我的NAS上的故障硬盘(LVM中的3个中的1个)传输到新硬盘。大多数(百分比)文件传输正常,但许多(数千)受到影响,而不是失败的i / o错误,他们将速度降低到令人痛苦的速度。
我使用的是一个简单的cp命令,但之后我切换到rsync并使用--progress选项至少能够确定何时发生这种情况。
目前,我手动观看屏幕(当我们正在谈论DAYS时很糟糕),^ C出现挂机时,然后复制文件名并将其粘贴到排除文件中并重新启动rsync的。
我需要自动执行此操作!
我对bash脚本没有任何了解,但我认为我可以"观看"标准输出,解析费率信息并使用如下逻辑:
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)
因此解析第二行的第三列并确保它不会太慢,如果它然后终止命令,则将文件名附加到EXCLUDE并再给它一次。
有人可以帮助我吗?
答案 0 :(得分:2)
This is a horrible approach, and I do not expect it to usefully solve your problem. However, the following is a literal answer to your question.
#!/usr/bin/env bash
[[ $1 ]] || {
echo "Usage: rsync -P --exclude=exclude-file ... | $0 exclude-file" >&2
exit 1
}
is_too_slow() {
local rate=$1
case $rate in
*kB/s) return 0 ;;
[0-4][.]*MB/s) return 0 ;;
*) return 1 ;;
esac
}
exclude_file=$1
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