fswatch でファイル変更を自動検知する — macOS開発者のための実践ガイド

fswatch とは

fswatch は macOS・Linux・Windows(WSL)で動作するオープンソースのファイルシステム監視ツールです。OS ネイティブの監視 API(macOS なら FSEvents、Linux なら inotify)をラップし、指定したパス配下でファイルが変更されるたびにイベントを通知します。

WordPress テーマ・プラグイン開発、静的サイトジェネレーター、デプロイスクリプトなど「ファイルを保存したら何かを実行したい」あらゆる場面で活躍します。


インストール

brew install fswatch

基本的な使い方

変更されたファイルのパスを出力する

fswatch /path/to/watch

ファイルを保存するたびに、変更されたファイルのフルパスが標準出力に流れてきます。

/path/to/watch/style.css
/path/to/watch/functions.php

変更を検知したらコマンドを実行する

fswatch -o /path/to/watch | xargs -n1 -I{} echo "変更を検知しました"
  • -o : パスの代わりに「イベント発生回数」を数値で出力するモード。xargs でトリガーとして使うのに便利です。

rsync と組み合わせてファイルを自動同期する

fswatch -o /path/to/src | xargs -n1 -I{} rsync -av --delete /path/to/src/ /path/to/dst/

ファイルを保存するたびに rsync が走り、宛先に即時反映されます。


主要オプション

オプション説明
-oパスではなくイベント数を出力(トリガー用途)
-rサブディレクトリも再帰的に監視(デフォルトで有効)
-e <パターン>監視から除外するパターン(正規表現)
-i <パターン>監視対象に含めるパターン(正規表現)
--event <種類>特定のイベント種別のみ通知(Created, Updated, Removed など)
-1最初の1イベントで終了

実践例:WordPress プラグイン開発の自動同期

開発ディレクトリをローカルの WordPress 環境に自動同期するシェルスクリプトです。

#!/usr/bin/env bash
# dev-sync.sh — プラグイン開発用ファイル同期スクリプト

SRC="/path/to/your-plugin/src/"
DST="/path/to/local-wp/wp-content/plugins/your-plugin/"

# 初回フル同期
rsync -av --delete "$SRC" "$DST"
echo "[dev-sync] 初回同期完了。ファイル監視を開始します..."

# 変更監視 & 差分同期
fswatch -o "$SRC" | while read -r _; do
    rsync -av --delete "$SRC" "$DST"
    echo "[dev-sync] 同期完了: $(date '+%H:%M:%S')"
done

実行方法:

chmod +x dev-sync.sh
./dev-sync.sh

よくある落とし穴

.gitnode_modules も監視してしまう

fswatch -o -e "\.git" -e "node_modules" /path/to/src | xargs -n1 -I{} rsync ...

-e で除外パターンを指定しましょう。

イベントが連続して rsync が何度も走る

エディタによっては保存時に複数のイベントが発火します。xargs -n1 の代わりに短い sleep を挟んでデバウンスするか、--delay-updates オプション付きの rsync を使うと安定します。


まとめ

ユースケースコマンド例
変更検知の確認fswatch /path/to/watch
変更時にスクリプト実行fswatch -o /path/to/watch | xargs -n1 -I{} ./deploy.sh
ディレクトリ自動同期fswatch -o /path/to/src | while read _; do rsync -av /path/to/src/ /path/to/dst/; done

シンプルな CLI ツールながら、監視 → 実行のパイプラインとして非常に強力です。ビルドツールや watch モードが用意されていないレガシーな環境でも手軽に導入できる点が魅力です。

コメント

タイトルとURLをコピーしました