[macOS] Terminalでファイルを監視し更新されたら指定の処理をする - fswatch

一言で言えばGulpのようなタスクランナーっぽいことをmacOS上でやりたかったのです。

「Gulp入れればいいじゃん」という話もありますが、今回はファイルが更新されたら特定のコマンドを実行したいだけだったので、わざわざNode.jsの環境を整えてJavaScriptガリガリ書くのはちょっと面倒だったんですよね。

macOSではファイルが更新されたか監視する際にfswatchを使うのが鉄板のようなので、こちらを利用します。 github.com

インストール

HomeBrewで一発です。

$ brew install fswatch

今回は1.15.0が入りました。

$ fswatch --version                                                                                                   fswatch 1.15.0
Copyright (C) 2013-2018 Enrico M. Crisostomo <enrico.m.crisostomo@gmail.com>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Enrico M. Crisostomo.

簡易タスクランナー

今回はサンプルとして特定のディレクトリ内にあるJavaScriptのファイルが更新されたら、catコマンドで一つに結合するシェルスクリプトを作成します。

コード

Bashです。変数eventには新規に作成、または更新や削除されたファイルやディレクトリの絶対パスが入っていますので、while内でお望みのままに処理します。

#!/bin/bash

#
# 簡易タスクランナー
#

#---------------------------
# 定数
#---------------------------
# 対象のディレクトリ
readonly TARGET_DIR="src/"

#---------------------------
# タスクランナー
#---------------------------
# ディレクトリの存在チェック
if [[ ! -d $TARGET_DIR ]]; then
  echo "[error] Not Found target directory ${TARGET_DIR}" >&2
  exit
fi

# ディレクトリを監視
fswatch -0 $TARGET_DIR | while read -d "" event; do
  # この中に実行したいコマンドを書いていく
  echo ${event}

  # 拡張子が.jsのファイルなら結合する
  if [[ ${event} =~ \.js$ ]];then
    echo "** update bundle.js"
    cat $TARGET_DIR/*.js > bundle.js
  fi
done

fswatchのオプションの-0は、ファイルの区切り文字にNULを使用しxargsやシェルスクリプト内で利用しやすくする物です。

実行方法

パーミションを適当に設定します。

$ chmod 0755 task.sh

あとはそのまま実行してください。

$ ./task.sh

終了する際はCtrl+cです。

$ ./task.sh
^C

参考ページ