diff --git a/tests/test_transfer.py b/tests/test_transfer.py index c1257b4..3551aa9 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -366,3 +366,7 @@ def test_count_files_only_files(tmp_path): (tmp_path / "a.txt").write_text("x") (tmp_path / "dir1").mkdir() assert transfer.count_files(str(tmp_path)) == 1 # 目录不计 + +def test_parse_args_retry_infinite(): + args = transfer.parse_args(["--retry", "-1", "s", "d"]) + assert args.retry == -1 # 无限重试 diff --git a/transfer.py b/transfer.py index f2d9176..abe9a7d 100644 --- a/transfer.py +++ b/transfer.py @@ -442,7 +442,7 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser.add_argument("--verify", action="store_true", help="传输完成后校验 (-c)") parser.add_argument("--retry", type=int, default=0, - help="失败自动补传轮数 (默认 0)") + help="失败自动补传轮数 (-1=无限, 默认 0 不重试)") parser.add_argument("--mode", choices=["cli", "tui"], default=None, help="运行模式 (默认: 有任务=cli, 无任务=tui)") parser.add_argument("--keep-logs", type=int, default=20, @@ -591,18 +591,24 @@ class TaskRunner: def run(self) -> int: """执行传输: 失败自动补传(retry) + 完成后校验(verify)""" rc = 0 - for attempt in range(self.cfg.retry + 1): + attempt = 0 + retry_label = "∞" if self.cfg.retry < 0 else str(self.cfg.retry) + while True: if attempt > 0: - self.lm.write(f"=== 补传轮次 {attempt}/{self.cfg.retry} ===") + self.lm.write(f"=== 补传轮次 {attempt}/{retry_label} ===") if self.on_log: - self.on_log(f"[yellow]补传轮次 {attempt}/{self.cfg.retry}[/]") + self.on_log(f"[yellow]补传轮次 {attempt}/{retry_label}[/]") time.sleep(3) # 等守护恢复设备 rc = self._run_once() if rc == 0 or self._stop.is_set(): break - self.lm.write(f"attempt {attempt + 1} failed rc={rc}") - if self.on_error and attempt < self.cfg.retry: - self.on_error(f"本轮退出码 {rc}, 将自动补传 ({attempt + 1}/{self.cfg.retry})") + attempt += 1 + # retry=-1 无限重试; retry=N 重试 N 轮; retry=0 不重试 + if self.cfg.retry >= 0 and attempt > self.cfg.retry: + break + self.lm.write(f"attempt {attempt} failed rc={rc}") + if self.on_error: + self.on_error(f"本轮退出码 {rc}, 将自动补传 ({attempt}/{retry_label})") if rc == 0 and self.cfg.verify and self.cfg.backend in ("rsync",): self._verify() return rc