構成例
./ ├── rsync-remote.sh └── sync/
rsync-remote.sh
の中身:
#!/bin/bash
if [ -z $(command -v watchman-wait) ]; then
echo "require watchman"
exit 1
fi
if [ -z $(command -v rsync) ]; then
echo "require rsync"
exit 1
fi
ssh_port=22
argv=()
while [ $# -gt 0 ]
do
case $1 in
--init-copy)
init_copy=true
;;
--ssh-port)
ssh_port=$2
shift
;;
-*)
opterr=true
echo "invalid option: $1"
;;
*)
argv+=("$1")
;;
esac
shift
done
if [ $opterr ]; then
exit 1
fi
if [[ "${#argv[@]}" -lt 1 ]]; then
echo "Too few arguments."
exit 1
elif [[ "${#argv[@]}" -gt 2 ]]; then
echo "Too many arguments."
exit 1
fi
source_path=${argv[0]}
target_path=${argv[1]}
if [ ! -d $source_path ]; then
echo "not exists directory: $source_path"
exit 1
fi
if [[ $source_path =~ [^/]$ ]]; then
echo "bad path: $source_path"
exit 1
fi
if [[ $target_path =~ [^/]$ ]]; then
echo "bad path: $target_path"
exit 1
fi
cd $source_path
if [ $init_copy ]; then
echo -e "copy from $target_path to $source_path"
rsync -v -e "ssh -p $ssh_port" -azph --delete $target_path ./
fi
echo -e "----------------------------------------------"
echo -e "start watch loop(watchman)"
echo -e "source:\t$(pwd)/"
echo -e "target:\t$target_path"
echo -e "----------------------------------------------\n"
while :
do
result=$(watchman-wait ./)
rsync -e "ssh -p $ssh_port" -azphv --delete ./ $target_path
done
使い方:
# ./sync/foo/ を リモート先の ~/foo/ に同期する bash ./rsync-remote.sh ./sync/foo/ user@remotehost:~/foo/ # ssh のポートを指定する場合 bash ./rsync-remote.sh --port 2222 ./sync/foo/ user@remotehost:~/foo/ # 監視前に1回だけ リモート先の ~/foo/ を ./sync/foo/ に同期する(逆流) bash ./rsync-remote.sh --port 2222 --init-copy ./sync/foo/ user@remotehost:~/foo/
watchman trigger
を使えば、whileでループする必要はなさそうだけれど、色々な記事に書かれている通りにやっても想定通り動いてくれなく、いまいち使い方がわからなかったので、素朴にループすることにした。