运行 定期远程备份
Run remote backup on regulary base
我写了一个 shell 脚本来检查是否可以访问远程服务器。
如果可以访问,它 运行 通过 ssh 命令在不同的服务器上发送。
之后,它会执行一些 rsync 任务。
一切正常,所以我每 4 小时向 运行 全体员工写了一个 plist 文件。
工作内容:
- 脚本按预期触发(我在标准输出文件中看到它)。
- launchctl start myjob 也工作正常(我在标准输出文件中看到它)。
我的问题:
如果作业在 mac本书休眠期间启动,则 ping 工作正常,但 ssh 命令不会返回。该命令在服务器上执行,但脚本停在那里。
如果我使用 ssh-command 终止进程,脚本会很好地完成。
我该怎么做才能获得更多信息。可能是什么错误?另一种解决方案是什么(Timemachine 不是一个选项,因为我想要一个一般可读的备份)?
Mac OS BigSur 11.4 M1-芯片
这是我的 plist 文件
?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>de.stanetz.backup</string>
<key>Program</key>
<string>/usr/local/sbin/remoteBackup.nsh</string>
<key>RunAtLoad</key>
<false/>
<key>StandardOutPath</key>
<string>/var/log/launch-stdout.log</string>
<key>StandardErrorPath</key>
<string>/var/log/launch-stderr.log</string>
<key>Debug</key>
<true/>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>15</integer>
</dict>
</array>
<key>ExitTimeOut</key>
<integer>360</integer>
<key>TimeOut</key>
<integer>360</integer>
</dict>
</plist>
更新:我将 ssh 命令更改为 ssh -vv pooh 'echo "this runs remotely"' >/tmp/so-debug.log 2>&1
。哪个工作正常。
如果我通过 ssh 调用 debug1: Sending command: /usr/local/sbin/handleBackupPlatte.nsh open
(运行s 10 秒),完整的 shell-脚本完成,但我在日志中发现:
debug2: channel 0: send eof
debug2: channel 0: input drain -> closed
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 2 clearing O_NONBLOCK
Killed by signal 15.
远程脚本完成之前的持续时间似乎是问题所在。
#!/bin/bash
echo "this runs remotely"
sleep 10
echo "for 10 seconds"
显示效果。但是我无法使脚本更快:-/ 除了将 ssh 命令发送到后台之外还有什么想法吗?
更新 2:如果 mac 书处于睡眠状态,似乎每个需要 10 秒的网络调用都会挂起并且永远不会完成。
我改用另一种方法。我安装了 sleepwatcher,它通知 macbook 是否被唤醒。此外,我将其与一个脚本结合使用,该脚本可确保并非每次唤醒时备份都是 运行。
这里的脚本
#!/bin/bash
#set -x
set -eu
## RETURN_CODES
# 11 -> BACKUP_ALREADY_RUNNING
# 12 -> NIGHT -> No Backup
# 13 -> Last backup is too young.
#VARIABLES
LOCK_FILE="/tmp/.backup.lock"
LAST_SUCCESS_FILE="/var/log/.backup.last_success"
RUN_CONTROL="/var/log/throttle.log"
MIN_BACKUP_AGE=240
cleanup() {
exitCode=$?
date +"Exit Throttle at %d.%m.%Y %H:%M:%S with $exitCode" >> ${RUN_CONTROL}
if [[ "$exitCode" -ne 11 ]]; then
rm ${LOCK_FILE}
fi
echo "$(tail -n 100 ${RUN_CONTROL})" > ${RUN_CONTROL}
exit $exitCode
}
trap cleanup EXIT
test -e ${LOCK_FILE} && echo "${LOCK_FILE} exists" && exit 11
touch ${LOCK_FILE}
hour=$(date +%H)
if [ "$hour" -gt 22 ] || [ "$hour" -lt 7 ]; then
exit 12
fi
test -e "$(find ${LAST_SUCCESS_FILE} -mmin -${MIN_BACKUP_AGE})" && exit 13 || true
/usr/local/sbin/remoteBackup.nsh
echo "$(tail ${LAST_SUCCESS_FILE})" > ${LAST_SUCCESS_FILE}
date >> ${LAST_SUCCESS_FILE}
和/Library/LaunchDaemons/de.bernhard-baehr.sleepwatcher.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>de.bernhard-baehr.sleepwatcher</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/sbin/sleepwatcher</string>
<string>-V</string>
<string>-w /usr/local/sbin/throttledBackup.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/sleepwatcher-stdout.log</string>
<key>StandardErrorPath</key>
<string>/var/log/sleepwatcher-stderr.log</string>
</dict>
</plist>
我写了一个 shell 脚本来检查是否可以访问远程服务器。 如果可以访问,它 运行 通过 ssh 命令在不同的服务器上发送。 之后,它会执行一些 rsync 任务。
一切正常,所以我每 4 小时向 运行 全体员工写了一个 plist 文件。
工作内容:
- 脚本按预期触发(我在标准输出文件中看到它)。
- launchctl start myjob 也工作正常(我在标准输出文件中看到它)。
我的问题:
如果作业在 mac本书休眠期间启动,则 ping 工作正常,但 ssh 命令不会返回。该命令在服务器上执行,但脚本停在那里。 如果我使用 ssh-command 终止进程,脚本会很好地完成。
我该怎么做才能获得更多信息。可能是什么错误?另一种解决方案是什么(Timemachine 不是一个选项,因为我想要一个一般可读的备份)?
Mac OS BigSur 11.4 M1-芯片
这是我的 plist 文件
?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>de.stanetz.backup</string>
<key>Program</key>
<string>/usr/local/sbin/remoteBackup.nsh</string>
<key>RunAtLoad</key>
<false/>
<key>StandardOutPath</key>
<string>/var/log/launch-stdout.log</string>
<key>StandardErrorPath</key>
<string>/var/log/launch-stderr.log</string>
<key>Debug</key>
<true/>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>15</integer>
</dict>
</array>
<key>ExitTimeOut</key>
<integer>360</integer>
<key>TimeOut</key>
<integer>360</integer>
</dict>
</plist>
更新:我将 ssh 命令更改为 ssh -vv pooh 'echo "this runs remotely"' >/tmp/so-debug.log 2>&1
。哪个工作正常。
如果我通过 ssh 调用 debug1: Sending command: /usr/local/sbin/handleBackupPlatte.nsh open
(运行s 10 秒),完整的 shell-脚本完成,但我在日志中发现:
debug2: channel 0: send eof
debug2: channel 0: input drain -> closed
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 2 clearing O_NONBLOCK
Killed by signal 15.
远程脚本完成之前的持续时间似乎是问题所在。
#!/bin/bash
echo "this runs remotely"
sleep 10
echo "for 10 seconds"
显示效果。但是我无法使脚本更快:-/ 除了将 ssh 命令发送到后台之外还有什么想法吗?
更新 2:如果 mac 书处于睡眠状态,似乎每个需要 10 秒的网络调用都会挂起并且永远不会完成。
我改用另一种方法。我安装了 sleepwatcher,它通知 macbook 是否被唤醒。此外,我将其与一个脚本结合使用,该脚本可确保并非每次唤醒时备份都是 运行。 这里的脚本
#!/bin/bash
#set -x
set -eu
## RETURN_CODES
# 11 -> BACKUP_ALREADY_RUNNING
# 12 -> NIGHT -> No Backup
# 13 -> Last backup is too young.
#VARIABLES
LOCK_FILE="/tmp/.backup.lock"
LAST_SUCCESS_FILE="/var/log/.backup.last_success"
RUN_CONTROL="/var/log/throttle.log"
MIN_BACKUP_AGE=240
cleanup() {
exitCode=$?
date +"Exit Throttle at %d.%m.%Y %H:%M:%S with $exitCode" >> ${RUN_CONTROL}
if [[ "$exitCode" -ne 11 ]]; then
rm ${LOCK_FILE}
fi
echo "$(tail -n 100 ${RUN_CONTROL})" > ${RUN_CONTROL}
exit $exitCode
}
trap cleanup EXIT
test -e ${LOCK_FILE} && echo "${LOCK_FILE} exists" && exit 11
touch ${LOCK_FILE}
hour=$(date +%H)
if [ "$hour" -gt 22 ] || [ "$hour" -lt 7 ]; then
exit 12
fi
test -e "$(find ${LAST_SUCCESS_FILE} -mmin -${MIN_BACKUP_AGE})" && exit 13 || true
/usr/local/sbin/remoteBackup.nsh
echo "$(tail ${LAST_SUCCESS_FILE})" > ${LAST_SUCCESS_FILE}
date >> ${LAST_SUCCESS_FILE}
和/Library/LaunchDaemons/de.bernhard-baehr.sleepwatcher.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>de.bernhard-baehr.sleepwatcher</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/sbin/sleepwatcher</string>
<string>-V</string>
<string>-w /usr/local/sbin/throttledBackup.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/sleepwatcher-stdout.log</string>
<key>StandardErrorPath</key>
<string>/var/log/sleepwatcher-stderr.log</string>
</dict>
</plist>