2011年10月31日月曜日

rsyncでサブディレクトリから順に同期する

rsync を使用するとディレクトリ間の同期をとってくれるためとても便利である。
だが、同期の順番は

上位のディレクトリ → 下位のディレクトリ

であり、指定することができない。
だが、今回は逆の順番である

下位のディレクトリ → 上位のディレクトリ

で実施したい。

実現方法の案は

シェルスクリプトでディレクトリ構造を把握して、
サブディレクトリから上位ディレクトリの順に都度 rsync を実行する

だ。

ということでまずは指定したディレクトリ以下のディレクトリ構造を取得するコマンドだが、それは簡単に取得できる。

find {調査したいディレクトリ} -type d

あとは取得したディレクトリの一覧を tac コマンドで逆順にして rsync を実行するだけである。

つまりこんな感じ。

予めディレクトリを作成しておかないとエラーになるためスクリプトを修正しました。

#!/bin/sh

RSYNC_OPT='-av --delete'
RSYNC_OPT_FOR_DIR='-dr'
SRC_ROOT_DIR=$1
DST_ROOT_DIR=$2

#create directories

RSYNC_COMMAND="rsync ${RSYNC_OPT_FOR_DIR} ${SRC_ROOT_DIR} ${DST_ROOT_DIR}"
echo "COMMAND: ${RSYNC_COMMAND}"
${RSYNC_COMMAND}

#remove last "/"
case ${SRC_ROOT_DIR} in
*/)
  SRC_ROOT_DIR_CUT_LENGTH=`expr ${#SRC_ROOT_DIR} - 1`
  SRC_ROOT_DIR=`echo ${SRC_ROOT_DIR} | cut -c1-${SRC_ROOT_DIR_CUT_LENGTH}`
  ;;
esac
case ${DST_ROOT_DIR} in
*/)
  DST_ROOT_DIR_CUT_LENGTH=`expr ${#DST_ROOT_DIR} - 1`
  DST_ROOT_DIR=`echo ${DST_ROOT_DIR} | cut -c1-${DST_ROOT_DIR_CUT_LENGTH}`
  ;;
esac

#save current directory
INITIAL_DIR=`pwd`

#move src directory
cd ${SRC_ROOT_DIR}

# find all sub directories and sort reverse
targetdirectories=`find . -type d | tac`

#move initial directory
cd ${INITIAL_DIR}

# run rsync each sub directories reversely
for targetdirectory in ${targetdirectories}
do
  if [ ${#targetdirectory} -ge 2 ]
  then
    ACTUAL_DIRECTORY=`echo ${targetdirectory} | cut -c 2-${#targetdirectory}`
  else
    ACTUAL_DIRECTORY=''
  fi
  ACTUAL_SRC_DIRECTORY="${SRC_ROOT_DIR}${ACTUAL_DIRECTORY}/"
  ACTUAL_DST_DIRECTORY="${DST_ROOT_DIR}${ACTUAL_DIRECTORY}"
  RSYNC_COMMAND="rsync ${RSYNC_OPT} ${ACTUAL_SRC_DIRECTORY} ${ACTUAL_DST_DIRECTORY}"
  echo "COMMAND: ${RSYNC_COMMAND}"
  ${RSYNC_COMMAND}
done

備考


ただ、障害時のリカバリーはどうするか…?
→ rsync実行中にエラー(ネットワークがダウンなど)が発生すると途中までの処理結果が反映されてしまう によれば、通常実行時も途中で障害が発生した場合には途中まで反映された状態となるため問題なしか…?

参考にしたページなど

と、簡単に書いた様な書き方であるが、実は初めてシェルスクリプトを本格的に作ったこともありかなり苦戦した。
以下のページを参考にさせていただいた。先人に感謝。

rsync の使い方:
http://x68000.q-e-d.net/~68user/unix/pickup?rsync

find の出力結果を逆順にして処理する方法のヒント
http://www.mkamo.org/blog/20090613/377.html

コードのハイライト方法:
http://moririn-web.blogspot.com/2010/03/bloggersyntax-hilighter.html