Last active
March 25, 2017 20:41
-
-
Save sasrai/96a9b55f34b5fa233d665aeb107ab56a to your computer and use it in GitHub Desktop.
SSDの世代バックアップをHDDに自動で取るやつ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
########################################################### | |
# Config | |
########################################################### | |
SEND_LOG_EMAIL=foobar@example.com | |
SENDER_EMAIL=report@example.com | |
TARGET=/hoge | |
BACKUP_DIR=/backups/hoge | |
BACKUP_WEEKLY_NUM=3 | |
TIME_FORMAT="+%Y-%m-%d" | |
NEWBACKUP=$(date ${TIME_FORMAT}) | |
NEWBACKUP_DIR=${BACKUP_DIR}/${NEWBACKUP} | |
# 火曜日がフルバックアップ日 | |
LATEST_FULLBAKCUP=$(date ${TIME_FORMAT} -d "$(date '+%Y/%m/%d' -d 'tuesday') 1 week ago") | |
OLDEST_FULLBAKCUP=$(date ${TIME_FORMAT} -d "$(date '+%Y/%m/%d' -d 'tuesday') $((${BACKUP_WEEKLY_NUM} + 1)) week ago") | |
RSYNC_OPT="-av --delete" | |
########################################################### | |
# 関数 | |
########################################################### | |
# http://wordpress.ideacompo.com/?p=4936 | |
function date_diff() { | |
# 開始日の1900/1/1からの秒数を求める | |
START=$(date -d "$1" +%s) | |
# 終了日の1900/1/1からの秒数を求める | |
FINISH=$(date -d "$2" +%s) | |
# 終了日 - 開始日 の差分秒を求める | |
DIFF=$(($FINISH - $START)) | |
# 秒分時で割ることで日数が求められる(小数点切り捨て) | |
DAYS=$(($DIFF / 60 / 60 / 24)) | |
# 結果表示 | |
echo $DAYS | |
} | |
function send_error_mail() { | |
cat <<- _EOT_ | sendmail -t | |
Delivered-To: ${SEND_LOG_EMAIL} | |
Return-Path: <${SENDER_EMAIL}> | |
To: ${SEND_LOG_EMAIL} | |
From: Rsync Backup <${SENDER_EMAIL}> | |
Subject: Backup ERROR. | |
Date: ${BACKUP_DATE} | |
Unknown error!! | |
_EOT_ | |
} | |
########################################################### | |
# 実処理 | |
########################################################### | |
# PATHにsbin追加(cron上でのsendmailとsmartctl用) | |
PATH=/usr/local/sbin:/usr/sbin:$PATH | |
# フルバックアップ日はここが一致 | |
if [ ${NEWBACKUP} != ${LATEST_FULLBAKCUP} ]; then | |
# 前日からの差分を作らせる | |
YESTERDAY_BAKCUP=$(date ${TIME_FORMAT} -d '1 day ago') | |
if [ -d ${BACKUP_DIR}/${YESTERDAY_BAKCUP} ]; then | |
RSYNC_OPT="${RSYNC_OPT} --link-dest=../${YESTERDAY_BAKCUP}" | |
fi | |
fi | |
BACKUP_DATE=$(date -R) | |
SECONDS=0 | |
RSYNC_LOG=$(rsync ${RSYNC_OPT} "${TARGET}"/* "${NEWBACKUP_DIR}") | |
if [ ! $? ]; then | |
send_error_mail | |
exit | |
fi | |
# 古いバックアップを削除 | |
find ${BACKUP_DIR} -mindepth 1 -maxdepth 1 -type d | while read DIR; do | |
if [ 0 -gt $(date_diff ${OLDEST_FULLBAKCUP} $(basename ${DIR})) ]; then | |
echo ${DIR} is old... | |
if [[ $(basename ${DIR}) =~ ^20[0-9]{2}-[0-1][0-9]-[0-3][0-9]$ ]]; then | |
rm -rvf ${DIR} | |
fi | |
fi | |
done | |
# バックアップにかかった時間を保存 | |
COPYTIME=${SECONDS} | |
# rsyncのログからサブディレクトリの一覧と内部のコピー数を取得 | |
declare -A SUBDIRS | |
TMP_TARGET=${TARGET#*/} | |
RSYNC_LOG_FOOTER=$(tail -2 <<- _EOT_ | |
${RSYNC_LOG} | |
_EOT_ | |
) | |
RSYNC_LOG_HEADER_SKIP_LINES=2 | |
if [ ! -d ${NEWBACKUP_DIR} ]; then | |
RSYNC_LOG_HEADER_SKIP_LINES=$((${RSYNC_LOG_HEADER_SKIP_LINES} + 1)) | |
fi | |
RSYNC_FILE_LOG=$(tail -n +${RSYNC_LOG_HEADER_SKIP_LINES} <<- _EOT_ | head -n -2 | |
${RSYNC_LOG} | |
_EOT_ | |
) | |
IFS_ORIG="$IFS" | |
IFS=$'\n'; | |
for LOG in ${RSYNC_FILE_LOG}; do | |
# 空行はファイルリストの最後(のはず) | |
if [ -z ${LOG} ]; then | |
break | |
fi | |
if [ -d ${NEWBACKUP_DIR}/${LOG%%/*} ]; then | |
SUBDIR=${LOG%%/*} | |
if [ ! -z ${SUBDIR} ]; then | |
SUBDIRS[${SUBDIR}]=$(( ${SUBDIRS[${SUBDIR}]:=0} + 1 )) | |
fi | |
fi | |
done | |
IFS="$IFS_ORIG" | |
# サブディレクトリ毎のコピーレポート作成 | |
DIRS_LOG=$(for KEY in ${!SUBDIRS[@]}; do | |
_SIZE=$(du -sk "${BACKUP_DIR}/${NEWBACKUP}/${KEY}" | awk '{print"%\047d",$1}') | |
echo ${KEY}: ${SUBDIRS[$KEY]} records. \(${SIZE} kb\) | |
unset _SIZE | |
done) | |
# レポートメール本文作成 | |
cat << _EOT_ | sendmail -t | |
Delivered-To: ${SEND_LOG_EMAIL} | |
Return-Path: <${SENDER_EMAIL}> | |
To: ${SEND_LOG_EMAIL} | |
From: Rsync Backup <${SENDER_EMAIL}> | |
Subject: Backup report. | |
Date: ${BACKUP_DATE} | |
Rsync backup report. | |
Backup time is ${COPYTIME}sec. | |
${RSYNC_LOG_FOOTER} | |
==== ==== | |
Backup dirs report. | |
${DIRS_LOG} | |
==== ==== | |
Latest full backup: ${LATEST_FULLBAKCUP} | |
Backup nums: $(ls -1d ${BACKUP_DIR} | wc -l) | |
Use storage: $(du -s ${BACKUP_DIR} | cut -d ' ' -f 1 | awk '{printf"%\047d",$1}') bytes | |
Reallocate sector: $(smartctl -A $(df ${BACKUP_DIR} | cut -d ' ' -f 1 | tail -1) | grep Reallocated | awk '{print $10}') | |
==== ==== | |
Storage status. | |
$(df -h ${LATEST_FULLBAKCUP} ${TARGET}) | |
==== ==== | |
Raw S.M.A.R.T. Report. | |
$(smartctl --scan | cut -d ' ' -f 1 | while read dev; do sudo smartctl -A $dev; echo ; echo; done) | |
_EOT_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment