我想设置一个 cron 作业来将远程系统同步到备份分区,例如:
bash -c 'rsync -avz --delete --exclude=proc --exclude=sys root@remote1:/ /mnt/remote1/'
我希望能够“设置后就忘记它”,但是如果
/mnt/remote1
被卸载了怎么办? (重新启动或其他操作后)如果 /mnt/remote1
未安装,我想出错,而不是填充本地文件系统。
编辑:
这是我为脚本想出的内容,值得赞赏的清理改进(特别是对于空的 then ...否则,我不能将它们留空或 bash 错误)
#!/bin/bash
DATA=data
ERROR="0"
if cut -d' ' -f2 /proc/mounts | grep -q "^/mnt/$1\$"; then
ERROR=0
else
if mount /dev/vg/$1 /mnt/$1; then
ERROR=0
else
ERROR=$?
echo "Can't backup $1, /mnt/$1 could not be mounted: $ERROR"
fi
fi
if [ "$ERROR" = "0" ]; then
if cut -d' ' -f2 /proc/mounts | grep -q "^/mnt/$1/$DATA\$"; then
ERROR=0
else
if mount /dev/vg/$1$DATA /mnt/$1/data; then
ERROR=0
else
ERROR=$?
echo "Can't backup $1, /mnt/$1/data could not be mounted."
fi
fi
fi
if [ "$ERROR" = "0" ]; then
rsync -aqz --delete --numeric-ids --exclude=proc --exclude=sys \
root@$1.domain:/ /mnt/$1/
RETVAL=$?
echo "Backup of $1 completed, return value of rsync: $RETVAL"
fi
mountpoint
似乎是最好的解决方案:如果路径是挂载点,则返回 0:
#!/bin/bash
if [[ `mountpoint -q /path` ]]; then
echo "filesystem mounted"
else
echo "filesystem not mounted"
fi
发现于LinuxQuestions。
if cut -d' ' -f2 /proc/mounts | grep '^/mnt/remote1$' >/dev/null; then
rsync -avz ...
fi
从
/proc/mounts
获取已挂载分区的列表,仅匹配/mnt/remote1
(如果已挂载,则将grep的输出发送到/dev/null
),然后运行您的rsync
作业。
最近的
grep
有一个 -q
选项,您可以使用它来代替将输出发送到 /dev/null
。
快速谷歌让我找到了这个 bash 脚本,它可以检查文件系统是否已安装。看来 grep df 或 mount 的输出是正确的方法:
if df |grep -q '/mnt/mountpoint$'
then
echo "Found mount point, running task"
# Do some stuff
else
echo "Aborted because the disk is not mounted"
# Do some error correcting stuff
exit -1
fi
chmod +x backup.sh
)backup.sh [username (for rsync)] [backup source device] [backup source location] [backup target device] [backup target location]
!!!注意!!!在不理解代码的情况下,不要以 root 用户身份执行脚本!
我觉得没什么好解释的。代码简单明了并且文档齐全。
#!/bin/bash
##
## COMMAND USAGE: backup.sh [username] [backup source device] [backup source location] [backup target device] [backup target location]
##
## for example: sudo /home/manu/bin/backup.sh "manu" "/media/disk1" "/media/disk1/." "/media/disk2" "/media/disk2"
##
##
## VARIABLES
##
# execute as user
USER="$1"
# Set source location
BACKUP_SOURCE_DEV="$2"
BACKUP_SOURCE="$3"
# Set target location
BACKUP_TARGET_DEV="$4"
BACKUP_TARGET="$5"
# Log file
LOG_FILE="/var/log/backup_script.log"
##
## SCRIPT
##
function end() {
echo -e "###########################################################################\
#########################################################################\n\n" >> "$LOG_FILE"
exit $1
}
# Check that the log file exists
if [ ! -e "$LOG_FILE" ]; then
touch "$LOG_FILE"
chown $USER "$LOG_FILE"
fi
# Check if backup source device is mounted
if ! mountpoint "$BACKUP_SOURCE_DEV"; then
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Backup source device is not mounted!" >> "$LOG_FILE"
end 1
fi
# Check that source dir exists and is readable.
if [ ! -r "$BACKUP_SOURCE" ]; then
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Unable to read source dir." >> "$LOG_FILE"
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Unable to sync." >> "$LOG_FILE"
end 1
fi
# Check that target dir exists and is writable.
if [ ! -w "$BACKUP_TARGET" ]; then
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Unable to write to target dir." >> "$LOG_FILE"
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Unable to sync." >> "$LOG_FILE"
end 1
fi
# Check if the drive is mounted
if ! mountpoint "$BACKUP_TARGET_DEV"; then
echo "$(date "+%Y-%m-%d %k:%M:%S") - WARNING: Backup device needs mounting!" >> "$LOG_FILE"
# If not, mount the drive
if mount "$BACKUP_TARGET_DEV" > /dev/null 2>&1 || /bin/false; then
echo "$(date "+%Y-%m-%d %k:%M:%S") - Backup device mounted." >> "$LOG_FILE"
else
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Unable to mount backup device." >> "$LOG_FILE"
echo "$(date "+%Y-%m-%d %k:%M:%S") - ERROR: Unable to sync." >> "$LOG_FILE"
end 1
fi
fi
# Start entry in the log
echo "$(date "+%Y-%m-%d %k:%M:%S") - Sync started." >> "$LOG_FILE"
# Start sync
su -c "rsync -ayhEAX --progress --delete-after --inplace --compress-level=0 --log-file=\"$LOG_FILE\" \"$BACKUP_SOURCE\" \"$BACKUP_TARGET\"" $USER
echo "" >> "$LOG_FILE"
# Unmount the drive so it does not accidentally get damaged or wiped
if umount "$BACKUP_TARGET_DEV" > /dev/null 2>&1 || /bin/false; then
echo "$(date "+%Y-%m-%d %k:%M:%S") - Backup device unmounted." >> "$LOG_FILE"
else
echo "$(date "+%Y-%m-%d %k:%M:%S") - WARNING: Backup device could not be unmounted." >> "$LOG_FILE"
fi
# Exit successfully
end 0
我正在浏览这个,但我认为你更愿意 rsync -e ssh 并设置密钥来接受帐户。
对现有答案的改进是使用
..
,如下所示:rsync [opts] /mnt/source/ /mnt/target/.somedirectory/../
first
mkdir /mnt/{source,target}/.empty
在第一次运行之前(或者选择一个永远不会从源中删除的文件夹并在目标中 mkdir ),那么它应该仅在目标已安装时才有效,否则在尝试遍历路径时操作将失败如果源是一个挂载点,--delete是危险的,因为它可能会被卸载,删除整个目标,所以对于源应该使用相同的方法:
rsync [opts] /mnt/source/.somedirectory/../ /mnt/target/.somedirectory/../