| ... | @@ -18,7 +18,8 @@ let | ... | @@ -18,7 +18,8 @@ let |
| 18 | # Dedicated passphraseless key so the launchd job runs unattended; the | 18 | # Dedicated passphraseless key so the launchd job runs unattended; the |
| 19 | # interactive key keeps its passphrase. IdentitiesOnly stops ssh from | 19 | # interactive key keeps its passphrase. IdentitiesOnly stops ssh from |
| 20 | # offering the passphrased key first. | 20 | # offering the passphrased key first. |
| 21 | SSH=(ssh -i "$HOME/.ssh/id_sandwich_backup" -o IdentitiesOnly=yes -o BatchMode=yes) | 21 | SSH=(ssh -i "$HOME/.ssh/id_sandwich_backup" -o IdentitiesOnly=yes -o BatchMode=yes |
| | 22 | -o ConnectTimeout=30 -o ServerAliveInterval=30 -o ServerAliveCountMax=4) |
| 22 | | 23 | |
| 23 | # Single-instance guard: the initial sync takes hours, far longer than the | 24 | # Single-instance guard: the initial sync takes hours, far longer than the |
| 24 | # hourly interval. mkdir is atomic; recover if a previous run died uncleanly. | 25 | # hourly interval. mkdir is atomic; recover if a previous run died uncleanly. |
| ... | @@ -38,7 +39,7 @@ let | ... | @@ -38,7 +39,7 @@ let |
| 38 | # machine; anything else is a real failure and aborts before the snapshot. | 39 | # machine; anything else is a real failure and aborts before the snapshot. |
| 39 | rsync_one() { | 40 | rsync_one() { |
| 40 | local rc=0 | 41 | local rc=0 |
| 41 | rsync -a --delete --partial --human-readable --stats \ | 42 | rsync -a --delete --partial --timeout=600 --human-readable --stats \ |
| 42 | -e "''${SSH[*]}" \ | 43 | -e "''${SSH[*]}" \ |
| 43 | --exclude '.DS_Store' \ | 44 | --exclude '.DS_Store' \ |
| 44 | --exclude '.Spotlight-V100' \ | 45 | --exclude '.Spotlight-V100' \ |