差分更新されたファイルのみを同期するシェルスクリプト

差分更新されたファイルのみを同期するシェルスクリプト

例えば、あるファイルが置かれているディレクトリに権限がついていて気軽に編集させたくない場合に
そのディレクトリ配下のファイルを更新したいとなったらどうしますか?
よくある話が、別のディレクトリを作業用ディレクトリとして作成し更新したら更新先ディレクトリにコピーなりするという手順です。
運用の観点で見られるケースですね。

図にするとこんな感じ。
手動で更新するよりもシェルを書いて自動化したほうが運用上も扱いやすいので今回は
「差分があった場合のみ更新するシェルスクリプト」を書いてみたいと思います。

このようになりました。

 1 #!/bin/bash
 2
 3 # 変数指定
 4 SRC=/home/test.txt
 5 DST=/home/task/test.txt
 6
 7 # 引数1の時テスト実行
 8 if [ $1 -eq 1 ] ; then
 9         DRY=–dry-run
10 fi
11
12 # 処理実行
13 diff ${SRC} ${DST}
14 EDCODE=$?
15
16         if [ ${EDCODE} -eq 1 ] ; then
17                 rsync ${DRY} -av –checksum ${SRC} ${DST}
18                 EDCODE=$?
19
20                         if [ ${EDCODE} -eq 0 ] ; then
21                                 PASSCODE=0
22
23                         else
24                                 echo “同期に失敗しました”
25                                 logger “ERROR 同期に失敗しました”
26                         fi
27
28         elif [ ${EDCODE} -eq 2 ] ; then
29                 echo “コマンドエラーが発生しました”
30                 logger “ERROR コマンドエラーが発生しました”
31                 EDCODE=1
32
33         else
34                 echo “差分はありませんでした”
35
36         fi
37
38 # エラー判定
39 if [ ${PASSCODE} -eq 0 ] ; then
40         echo “処理正常終了”
41         logger “INFO 処理正常終了”
42         exit 0
43 fi
44
45 if [ ${EDCODE} -eq 1 ] ; then
46         echo “処理異常終了”
47         logger “ERROR 処理異常終了”
48         exit 1
49 fi
50
解説
差分確認はdiffを使用しました。
戻り値から差分の有り無しで条件分岐しています。
diffには以下のように3つの戻り値があります。

0 : 差分無し
1 : 差分有り
2 : コマンドエラー

0の場合、更新を行わないのでそのまま処理を終了させます。
1の場合、rsyncコマンドにより同期させています。
2の場合、CLI上とsyslog上にエラーログを出力させています。

以下、詳細

4,5行目:作業用ファイル(SRC)と更新先ファイル(DST)のパスを変数に代入
8,9行目:引数に1を入れてシェルを実行するとrsyncをテスト用に実行させる
13,14行目:diffコマンドを実行し戻り値($?)を変数に代入する
16-36行目:差分があった場合の同期処理
38-48行目:全体のエラー判定

rsyncにチェックサムオプションを付けていますが実際にはいらないです。
diffで差分があることを確認しているためですね。
二重チェックのために入れておきました。
rsyncの基本動作確認を行った記事(rsyncコマンドで基本動作と–checksumオプションの動作を理解する)をシェルに組み込みたかったのでこうなりました。

それでは、実際に動かしてみたいと思います。

①差分が無い場合
差分がなければそのまま処理を終了します。
この時、CLI上にログが出力されるので必ず確認しましょう。

diffの戻り値0でそのまま処理が終了しています。

②差分が有る場合
作業用ファイルを編集してからシェルを実行します。

戻り値1が入り、rsyncの処理へと進み処理が正常に終了しました。
rsyncのsending ~欄を見るとtest.txtが出力されているためきちんと更新先ディレクトリに同期されています。
また、syslogにもログが出力され想定通りの動きをしました。

③比較対象ファイルが無い場合
いわば①②は正常系だったわけですが、異常系も確認しておきます。
どうやってエラーを起こすか考えると2パターンあります。

・比較対象ファイルが存在しない
・同期に失敗する

今回は比較対象ファイルが存在しないことを想定して動かしてみます。
どちらでもいいのですが作業用ファイルのtest.txtを削除してからシェルを実行します。

ファイルが存在しないためdiffコマンドがエラーとなり戻り値2が入ります。
この時、CLI上とsyslog上にログが出力されるので必ず確認します。

④引数1を入れテスト用で動作させる場合
引数に1を入れるとrsyncコマンドはテスト用で動作します。

実行後、更新先ディレクトリのtest.txtを確認し更新されていないことを確認しています。

以上までで、まずまず使えるシェルが作れました。
細かいところを見ると8行目と39行目で変数入ってないよ!って怒られてるので直さないといけないですね。
まだまだシェルは勉強中なので指摘があればコメントを頂けると助かります。

ITカテゴリの最新記事

%d人のブロガーが「いいね」をつけました。
TOP