logo
Published on

gulp・expect・rsyncでファイルが更新されたらサーバーにアップロードするスクリプト

Authors

今回は、Bash on ubuntu on windowsで、/mnt/c/noteの中のファイルの変更を、再帰的に、gulpを使って監視し、gulpが作動するとexpectを使ってrsyncコマンドを実行し、VPSに更新されたファイルをアップロードする。という動作をプログラムしたいと思います。

経緯

リモートデスクトップしてるときに、PC1のatomの文字をコピーして、PC2でペーストすると、変な感じになるバグがあります。 解決策として、ファイルを2つのPC間で同期する、というものがあります。

簡単なのは、windowsの標準機能の、sambaを使ったファイル共有をすることです。 一方のファイルを変更して保存すると、もう一方のファイルも更新をしなくても内容が切り替わって便利。 しかし、これはローカルでしか使用できません。同じwifiのPCでしか使用できないということです。

リモートでもできるかもしれませんが、リモートでできるようにする、ということは、パソコンのグローバルIPアドレスを世界に公開するということです。 要はパソコンが簡単に狙われるようになり、ハッキングの対象となります。

僕はこういうのが嫌なので、自分のパソコンの他に、VPSのサーバーを借りて、そこでファイルの編集をする、という方法を考えました。

2つのPCで同一ファイルの編集をしたい場合に、VPSを通して作業する形になります。

具体的な手順

sudo su -

cd /mnt/c/note

apt install -y nodejs npm nodejs-legacy expect rsync

npm install -g gulp
npm install -D gulp
npm init -y
npm install child_process

gulpfile.js

<br />var gulp = require("gulp");
var ps = require('child_process').exec;

gulp.task('exec_file', function() {
  var command = "'/mnt/c/pg/expect/rsync_mnt_c_note'";
  ps(command , function (err, stdout, stderr) {
    console.log(stdout);
  });
});

gulp.task("watch", function() {
  var targets = [
    './**'
  ];
  gulp.watch(targets, ['exec_file']);
});


ここでちょっと注意なのが、. /mnt/c/pg/expect/rsync_mnt_c_noteとしてしまわないこと。/mnt/c/pg/expect/rsync_mnt_c_note自体がexpectのインタプリタで実行されなければいけないので、. hogehogeとしてしまうと、Bash(sh/zsh)で実行すること、つまり、bash hogehogeや、source hogehogeと同じ意味になってしまうので、クセでやってしまわないように注意。

touch /mnt/pg/expect/rsync_mnt_c_noteでexpectファイルを作成し、以下のような内容。(YOUR_OWNを各自変更)

#!/usr/bin/expect

# C:\pg\expect\rsync_mnt_c_note

set PW "YOUR_OWN"
set Prompt "\[#$%>\]"
# set RemoteHost [lindex $argv 0]

set timeout 5

spawn rsync -av -e "ssh" -r "/mnt/c/note" root@YOUR_OWN:/root/lib/DESKTOP-PS5DVT5

expect {
    -glob "(yes/no)?" {
        send "yes\n"
        exp_continue
    }
    -glob "password:" {
        send -- "${PW}\n"
    }
}

expect {
    -glob "${Prompt}" {
        interact
        exit 0
    }
}

では、/mnt/c/noteディレクトリで、gulp watchを実行してみましょう。

そして、 cat > /mnt/c/note/everything_note.mdでファイルを作り、 cat >> /mnt/c/note/everything_note.mdでファイルを更新してみましょう。

では、ちゃんとVPSサーバーにアップロードされているか確認しましょう。

ssh root@YOUR_OWN
cat DESKTOP-PS5DVT5/note/everything_note.md

catで入力した文字が出力されれば、アップロードは成功です。

アップロードはだいたい3秒位かかります。フォルダ全体の重さにもよりますが、更新のあった部分だけをアップロードする差分アップロードではなく、全てのファイルをアップロードするフルアップロードのためです。

注意点

また、注意点として、画像はいいとして、動画ファイルは対象フォルダ…今回の例で言えば、/mnt/c/noteに入れてはいけません。gulp watchしている間は。

なぜか。動画も二バイト文字の一つのファイルなので、ファイルが更新されているということは、文字が更新されているということです。 つまり、動画をアップロードしている間は、凄まじい速度で文字が増えている状態なわけで、この時にgulp watchをしていると、文字が増えるたびにVPSへアクセスするコマンドを実行することになります。よって、サーバーに相当な負荷がかかります。

気をつけましょう。