Linuxにはファイル同期ツールとしてrsyncが有名ですが、ファイルの変更を検知してリアルタイムに同期する機能はありません。そこでinotifywaitというツールを使います。これはlinuxのinotify APIを利用してファイルに対するイベントを検知します。

manページを見て捕捉したいイベントを探します。

イベント名 詳細
access
modify
attrib
close_write 書き込みモードで開かれたファイルが閉じたとき
close_nowrite 読み込み専用モードで開かれたファイルが閉じたとき
close `close_write
open
moved_to
moved_from
move `moved_to
move_self
create
delete
delete_self
unmount

同期するときはおそらく再帰的にやりたいので-rオプションをつけます。

1
inotifywait -r --exclude=.git --event modify,create,delete,move /hoge

このコマンドはファイルの変更を検知するまでブロックし、変更があると終了コード0を返します。

そのため次のようなスクリプトで自動同期が完成します。

1
2
3
4
while inotifywait -r --event modify,create,delete,move /hoge
do
rsync /hoge remote:/hoge -avh --delete
done

私の場合は普段git管理しているディレクトリで.gitignoreされているものもバックアップしたかったので次のようにしました。また、リモートのnextcloudで読み取れるように移動後にchmodしています。

1
2
3
4
while inotifywait -r --exclude=.git --event modify,create,delete,move /hoge
do
rsync /hoge remote:/hoge -avh --exclude=.git --chmod=D755,F644 --delete
done

あとはPC起動時にこれを自動実行してくれるようにすればいいので、systemdのUnitファイルを書きます。まあこんな感じでしょう。自分の.ssh/configを見てほしいのでユーザは自分にしておきます。

1
2
3
4
5
6
7
8
9
10
11
12
# /etc/systemd/system/dirsync.service
[Unit]
Description=Directory Sync Service
After=network.target

[Service]
User=you
WorkingDirectory=/home/you
ExecStart=bash -c 'while inotifywait -r --event modify,create,delete,move /hoge;do rsync /hoge remote:/hoge -avh --delete;done'

[Install]
WantedBy=default.target
1
2
3
sudo systemctl daemon-reload
sudo systemctl start dirsync.service
sudo systemctl enable dirsync.servide

参考