Bash脚本,如果速度太慢,则读取rsync进度并对文件进行保释

问题描述 投票:0回答:1

我对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)

因此解析第二行的第3列并确保它不是太慢,如果它然后终止命令,将文件名附加到EXCLUDE并再给它一次。

有人可以帮助我吗?

bash rsync
1个回答
2
投票

这是一种可怕的方法,我不认为它可以有效地解决您的问题。但是,以下是您的问题的字面答案。

#!/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
© www.soinside.com 2019 - 2024. All rights reserved.