Macに「watch」や「inotifywait」のようなコマンドはありますか?


287

Mac(Snow Leopard)のフォルダーを監視してから、スクリプトを実行します(フォルダーに移動したばかりのファイルの名前を(パラメーターとして... x.sh "ファイル名")を付けます)。

すべて$ bash(x.sh)で記述されたスクリプトで、入力時にいくつかのファイルやその他のものを移動します。$ 1新しいファイル/フォルダーがディレクトリに移動/作成されたときに、OSXでファイル名を指定するだけです。

そのようなコマンドはありますか?


1
DropBoxがどのようにそれを行うかを尋ねるべきです。おそらく彼らは利用可能なすべてのオプションを試したからです。
Jeff Burdges、2011年

2
@JeffBurdges私はそれが簡単な仕事になるとは思いません。ただし、AppleのFSEventsリファレンスをざっと読んだ後、Dropboxがこれを利用していなかったとしたら、ばかげたことでしょう。fswatch以下の答えは、実際の使用では、この方法の場合と同様のutilを提示しました。
Steven Lu

回答:


446

fswatch

fswatchは、Mac OS X FSEvents APIを使用してディレクトリを監視する小さなプログラムです。そのディレクトリへの変更に関するイベントを受け取ると、指定されたシェルコマンドが/bin/bash

GNU / Linuxを使用している場合、 inotifywatchinotify-toolsほとんどのディストリビューションのパッケージの一部 )が同様の機能を提供します。

更新: fswatch BSD、Debian、Windowsを含む多くのプラットフォームで使用できるようになりました。

構文/簡単な例

複数のパスを監視できる新しい方法- バージョン1.x以降の場合

fswatch -o ~/path/to/watch | xargs -n1 -I{} ~/script/to/run/when/files/change.sh

注:によって出力されない場合-o、出力される数値はxargsコマンドの最後に追加され-I{}ます。その番号を使用する場合{}は、コマンドの任意の場所に配置してください。

バージョン0.xの古い方法:

fswatch ~/path/to/watch ~/script/to/run/when/files/change.sh

Homebrewによるインストール

2013年9月12日の時点で、自作に追加されました。したがって、数式リスト(brew update)を更新すると、次の操作を行うだけです。

brew install fswatch

Homebrewを使用しないインストール

次のコマンドを入力します Terminal.app

cd /tmp
git clone https://github.com/alandipert/fswatch
cd fswatch/
make
cp fswatch /usr/local/bin/fswatch

cシステムにコンパイラがない場合は、XcodeまたはXcodeコマンドラインツールをインストールする必要があります。どちらも無料です。ただし、その場合は、おそらく自作をチェックする必要があります。

fswatchバージョン1.xの追加オプション

Usage:
fswatch [OPTION] ... path ...

Options:
 -0, --print0          Use the ASCII NUL character (0) as line separator.
 -1, --one-event       Exit fsw after the first set of events is received.
 -e, --exclude=REGEX   Exclude paths matching REGEX.
 -E, --extended        Use exended regular expressions.
 -f, --format-time     Print the event time using the specified format.
 -h, --help            Show this message.
 -i, --insensitive     Use case insensitive regular expressions.
 -k, --kqueue          Use the kqueue monitor.
 -l, --latency=DOUBLE  Set the latency.
 -L, --follow-links    Follow symbolic links.
 -n, --numeric         Print a numeric event mask.
 -o, --one-per-batch   Print a single message with the number of change events.
                       in the current batch.
 -p, --poll            Use the poll monitor.
 -r, --recursive       Recurse subdirectories.
 -t, --timestamp       Print the event timestamp.
 -u, --utc-time        Print the event time as UTC time.
 -v, --verbose         Print verbose output.
 -x, --event-flags     Print the event flags.

See the man page for more information.

あなたの指示または自作なしでインストールすることはもう働かないようです。makemakefileが見つからないというエラーをスローします。幸い、fswatchはMacPortsに対応してsudo port install fswatchいるので、Homebrewの代わりにMacPortsを使用している私たちにとっては機能します。
coredumperror 2015

静的引数を指定してコマンドを使用している場合(たとえば、srcでユニットテストを実行して変更をテストしていました)、これは機能しない可能性があります。この質問(stackoverflow.com/questions/25689589/…)は、私が必要とする2番目の質問でした。
jskulski

4
私はあなたの言うことを聞きます:fswatch ./ | xargs -I{} cp {} ~/Dropbox/backup/latest/
fionbio

fswatchは、entrやwhen_changedなどのツールよりも優れています。これらのツールには、.gitディレクトリを処理するときにいくつかのバグがあります。fswatchははるかに専門的です。単に、fswatch .現在のディレクトリを監視するだけです。
匿名

私はNULL を使用することfswatch -0 -v -o /path/to/watched/files | xargs -0 -n 1 -I {} [your command]をお勧めし-0ます。これは、コンパイルが少なくて済むように機能します
boldnik

95

そのためにlaunchdを使用できます。Launchdは、ファイルパスが変更されたときにプログラムを自動的に起動するように構成できます。

たとえば、次のlaunchd config plistは/usr/bin/logger、ユーザーアカウントのデスクトップフォルダーが変更されたときにプログラムを起動します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>logger</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/logger</string>
        <string>path modified</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/sakra/Desktop/</string>
    </array>
</dict>
</plist>

config plistをアクティブにするには、それを「logger.plist」としてライブラリフォルダーのLaunchAgentsフォルダーに保存します。

シェルから次のコマンドlaunchctlを使用して、logger.plistをアクティブ化できます。

$ launchctl load ~/Library/LaunchAgents/logger.plist

デスクトップフォルダが監視されています。変更されるたびに、system.logに出力が表示されます(Console.appを使用)。logger.plistを非アクティブ化するには、次のコマンドを実行します。

$ launchctl unload ~/Library/LaunchAgents/logger.plist

上記の設定ファイルはWatchPathsオプションを使用しています。または、QueueDirectoriesオプションを使用することもでき ます。詳細については、launchdのマニュアルページを参照してください。


1
ファイルコンテンツの変更とファイルパスを監視する方法はありますか?
Cam

2
そうは思いません。そのためにopensnoopを使用できます。
12

1
これを機能させました/usr/bin/loggerが、Bashスクリプトに切り替えて"<string>path modified</strong>"エントリを削除したところ、bashスクリプトがデスクトップ上のどのファイルが変更されたかを知る方法が見つかりませんでした。イベントが発生しただけです。私はを調べてみましたが$0$1渡されたスクリプト名だけがわかりました。
Volomike 2016年

また、これは、変更を検出したときに起動(および停止)するだけでなく、変更を検出するとループに入りますか?私はむしろそれがオンデマンドで動作し、ループで実行し続けるのではなく、たとえば2日前に、デスクトップで何かが変更され、それをログに繰り返し書き込んだことを教えてくれません。それで、このplistである種の間隔オプションを使用する必要がありますか?
Volomike 2016年

素晴らしい仕事と説明
ChenSmile

37

Homebrewから入手できるFacebookの監視人も見栄えがする。フィルタリングもサポートします:

これらの2行は、ソースディレクトリで監視を確立し、CSSファイルが変更されるたびに「minify-css」という名前のツールを実行する「buildme」という名前のトリガーを設定します。ツールには、変更されたファイル名のリストが渡されます。

$ watchman watch ~/src

$ watchman -- trigger ~/src buildme '*.css' -- minify-css

パスは絶対パスでなければならないことに注意してください。


1
これは断然最高のツールです。
BentOnCoding 2018年

1
これはとてもいい小さなプログラムです:ドキュメントは素晴らしいです、それは無限ループを開きません(これはfswatchがするようです)、それは再起動後に作成した時計を記憶し、自動でそれらを再び起動します。
ブラッド

21

あなたは私の小さなツールを見て(そしておそらく拡張して)みたいかもしれませんkqwait。現在、それはただ座って単一のファイルで書き込みイベントを待機していますが、kqueueアーキテクチャでは階層的なイベントスタックが可能です...


これまでにマウンテンライオンで動作します。非常に素晴らしい!
スコット

これは実際に本当に素晴らしいです。私はと少し問題に遭遇したfswatchようなもの実行しているとき、それは発射でしょう(そのように光ラッパーが、また、私は確信して適切なことを行うように変更する可能性があるので、細かすぎる)git status、実際にすべての時間のzshを実行しています(プロンプトが私のマシンに表示されます...)実際には、無限のフィードバックループを作成することによって、この手の込んだスクリプトを少し台無しにしています。ただし、kqwaitは変更されたファイルに関する情報を提供し、によってトリップされませんgit status。書き込み時に発砲する必要があります。
Steven Lu

2
$ brew install kqwait && while true; do kqwait doc/my_file.md; make; done
ジョシュアクック

15

ウォッチドッグは、ファイル/ディレクトリを監視するためのクロスプラットフォームのPython APIであり、イベント(新しい追加ファイル、削除されたファイル、変更されたファイルを含む)が発生したときにアクション(シェルコマンドを含む)をトリガーできる組み込みの「トリック」ツールを備えています。


7

これは、ファイルが変更されたときに任意のコマンドを実行するためのOSXの代替手段としてentrについて言及しているだけです。シンプルで便利だと思います。



3

編集: fswに統合されましたfswatch。この回答では、への参照はすべてをfsw読む必要がありますfswatch

私はいくつかの改良を特徴fswatchとするC ++で置き換えられたものを書きましたfsw

  • これは、サポートされている任意のプラットフォーム(OS X v。> = 10.6)でビルドするGNU Build Systemプロジェクトです。

    ./configure && make && sudo make install
    
  • 複数のパスを異なる引数として渡すことができます:

    fsw file-0 ... file-n 
    
  • 次のようなすべてのイベント情報を含む詳細なレコードをダンプします。

    Sat Feb 15 00:53:45 2014 - /path/to/file:inodeMetaMod modified isFile 
    
  • その出力は解析が簡単なので、fsw出力を別のプロセスにパイプすることができます。

  • レイテンシはでカスタマイズできます-l, --latency
  • 数値イベントフラグは、テキストフラグの代わりにで書き込むことができます-n, --numeric
  • 時刻形式は、strftime形式文字列を使用してカスタマイズできます-t, --time-format
  • 時間ができ、ローカルでマシンの時間(デフォルト)またはUTC時間-u, --utc-time

fswの取得:

fswGitHubホストされており、リポジトリのクローンを取得できます。

    git clone https://github.com/emcrisostomo/fsw

fswのインストール:

fsw 次のコマンドを使用してインストールできます。

    ./configure && make && sudo make install

さらに詳しい情報:

また、動作に関するいくつかの例を紹介するブログの紹介記事を書きましたfsw


2

Apple OSX フォルダアクションを使用すると、フォルダで実行されたアクションに基づいてタスクを自動化できます。


9
ええ、わかっています。何度か使ってみましたが、うまく機能しませんでした。例を挙げていただけませんか。
造幣局

1
それはリンクであり、答えではありません
Dan Rosenstark

2

私のfswatchのフォークは、解析に適した出力inotifywait -mをわずかに少なく(待ち時間なし、もっと!Linuxで多くの問題を抱えていinotifywaitます...)機能を提供します。

fswatch変更されたファイルの実際のパスをSTDOUT経由で送信するため、オリジナルの改良版です。フォークするプログラムを提供する必要はありません。

それは、私がものを自動化するために使用する一連の恐ろしいbashスクリプトの基礎として堅実です。

(これはトピック外です)inotifywait一方、Linuxでは、その上に多くのクラッジが必要であり、それを管理するための良い方法がまだわかりnode.jsませんが、チケットに基づいて何かに基づいていると思います。


1
右、fswatchのフォーク。であることは、自作に?
ファトホク

1
答えはいいえだ; しかし、彼らはそれに取り組んでいます。本当にすぐにインストールするには brew install https://raw.github.com/mlevin2/homebrew/116b43eaef08d89054c2f43579113b37b4a2abd3/Library/Formula/fswatch.rb
fatuhoku

1

これにはGISTがあり、使い方はかなり簡単です

watchfiles <cmd> <paths...>

たとえば、次のコマンドはHello Worldそのfile1ORがfile2変更されるたびにエコーします。デフォルトの間隔チェックは1秒です

watchfiles 'echo Hello World' /path/to/file1 /path/to/file2 

5秒ごとにチェックする場合は、-tフラグを使用できます

watchfiles -t 'echo Hello World' /path/to/file1 /path/to/file2 
  • -vverboseデバッグ情報を表示するモードを有効にします
  • -qせるにはwatchfiles(静かに実行する#ユーザーは、プログラムが実行されて見ることができるように表示されます)
  • -qqMAKESはwatchfiles完全に静かに実行します
  • -h ヘルプと使用法を示します

https://gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55


0

私はこれをmacOSのためにやってしまいました。これは多くの点で恐ろしいことだと思います:

#!/bin/sh
# watchAndRun
if [ $# -ne 2 ]; then
    echo "Use like this:"
    echo "   $0 filename-to-watch command-to-run"
    exit 1
fi
if which fswatch >/dev/null; then
    echo "Watching $1 and will run $2"
    while true; do fswatch --one-event $1 >/dev/null && $2; done
else
    echo "You might need to run: brew install fswatch"
fi

時間がないとfswatchの構文を理解できませんでした。これは煩わしく、スクリプトを停止するのを難しくします。
Dan Rosenstark

0

NodeJSを使用する場合は、監視用にchokidar(または実際にはchokidar-cli)というパッケージを使用してから、rsync(Macに含まれている)を使用できます。

Rsyncコマンド:

$ rsync -avz --exclude 'some-file' --exclude 'some-dir' './' '/my/destination'

Chokidar cli(npmを介してグローバルにインストール):

chokidar \"**/*\" -c \"your-rsync-command-above\"


-3

watch3秒ごとにコマンドを実行するコマンドを持たないユーザーのための簡単な1行の代替案を次に示します。

while :; do your-command; sleep 3; done

これは無限ループであり、基本的には次の処理と同じです。

watch -n3 your-command


3
これは、ファイルシステムからのイベントをリッスンするライブラリを使用することと同じではありません。あなたの例でyour-commandは、ディスクI / Oを行う場合、それは保証されたディスクの3秒ごとの読み取り/書き込み、つまり1 時間あたり 10,800回です。(一般的にだけ数回時間です)あなたがファイルを変更したときにのみ起こるI / O(および他の高価な操作)ことが保証されるだろうファイルシステムイベントを使用することにより
ノアサスマン

真実であり、考慮に値する。私は通常、watch何かが何をしているのかを確認するために、一時的に何かをする必要があります。私の言及した手法は、製品版アプリなどには使用しません。たとえば、の進捗状況を確認したいのですddが、私のテクニックはそれを実現します(your-command適切な信号をに送信するように適宜置き換えますdd)。
trusktr 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.