web-dev-qa-db-ja.com

ファイルの変更を監視してコマンドを実行するBashスクリプト

多数のサブフォルダーがあるフォルダーがあります。これらのフォルダーには、.adoc拡張子でasciidoctor形式のファイルがあります。

ファイルを変更するたびに(多くの場合)、実行する必要があります

asciidoctor -q filename.adoc

hTML形式にコンパイルします。

プロセスを自動化しようとしています。これまでのところ、私は entr を使用してこれを実現しています:

ls *.adoc | entr asciidoctor -q *.adoc

ただし、既存のフォルダーでのみ機能し、サブフォルダーでは機能しません。私はこのバリエーションを試しましたが、うまくいきません:

find . -name '*.adoc' | entr asciidoctor -q *.adoc

すべてのサブフォルダーにこの自動化プロセスを実装する方法はありますか?

10
bran

Linuxは、ファイルの作成、変更、削除など、すべてのファイルシステムイベントを監視するための素晴らしいインターフェイスを提供します。インターフェースはシステムコールのinotifyファミリーです。これらのコールを活用するユーザースペースユーティリティは、Ubuntuのinotify-toolsパッケージ(ユニバースリポジトリで利用可能)によって提供されます。まだお持ちでない場合は、次の方法でインストールしてください。

Sudo apt-get install inotify-tools

inotify-toolsinotifywaitおよびinotifywatchバイナリを提供します。最初のバイナリが必要です。


したがって、asciidoctor -q some_fileファイルがディレクトリ.adocにあると仮定した場合、some_fileファイルが変更されたときにコマンド.adocを実行します(/foo/barはそれで置き換えられます)。 ] _、ウォッチを設定できます。

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
  • -qはQuietモードを有効にし、inotifywait自体からの情報はありません

  • -mは監視モードを有効にします。そうでない場合、最初のイベントの後に終了します

  • --event modify、興味があるのはmodifyイベント、つまりファイルが変更されたときだけです。その他の可能な値には、opencloseなどがあります。

  • --format %w、ファイル名を別のコマンドへの入力として使用するため、他の情報の束ではなく、変更されたファイル名のみが必要です

  • /foo/bar/*.adocは、.adocディレクトリの下のすべての/foo/barファイルに展開されます


これで、ファイル名が変更されるたびにファイル名が表示され、ファイル名でコマンドを実行できます(コマンドがSTDIN経由で引数を取る場合)。

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | asciidoctor -q

ディレクトリで再帰監視を設定することもできます。その場合は、grepを使用して必要なファイルのみをフィルタリングする必要があります。ここで、ディレクトリ-rで時計を再帰的に設定(/foo/bar)し、grepを使用して.adocファイルのみをフィルタリングします。

inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | asciidoctor -q

ディレクトリを監視する場合、出力形式指定子%wはディレクトリ名に解決されるため、ファイル名を取得するには%fが必要です。ファイルの監視中、%fは空の文字列に解決されます。

デーモン(-d)モードでinotifywaitを実行したり、スクリプト全体を実行したり、バックグラウンドで実行したり、他のオプションを使用したりすることもできます。

また、必要に応じて、asciidoctorを任意の他のコマンドに置き換えることができます。

man inotifywaitをチェックして、より多くのアイデアを得てください。

14
heemayl

inotifywaitを使用するのが一般的なアプローチですが、ファイル(またはディレクトリ)が変更されたときにコマンドを実行できるinotify-hookableと呼ばれる別のユーティリティもあります。

inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'

コマンドを一度トリガーすると終了するようです。継続的な監視のオプションが表示されないため、次のようなことができます。

while true; do
    inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
    echo "== $(date) : executed, continuing to monitor..."
done

複数のファイルまたはディレクトリを再帰的に監視するオプションと、ファイル/パスを無視するオプションがあることに注意してください。

3
michael

特にリポジトリを検索する場合は、多くのツールがあります

apt-cache search monitor | grep file

多くのツールを提供します。しかし、私がそれをしたので、それらをテストする必要はありません。

これらのツールや他の多くのツールをテストしました。

  • inotify
  • fswatch
  • ファイルウォッチ
  • 見本
  • 変更されたファイル
  • entr

これらのツールの中で、そのうち3つが便利で信頼性が高いことがわかりました。

  • direvent | GNU Cで記述
  • iWatch | Perlで
  • fsniper

そして、これら3つの間で、 direvent が間違いなく最高です。

使用すると非常に便利で信頼できるので、自分のマイクロサービスで単純なpipelineに使用しました。

direvent.conf視聴用ファイル

syslog {
    facility local0;
    tag "direvent";
    print-priority yes;
}

watcher {
    path /var/www/html/ir/jsfun/build/react recursive;
    file "*.js";
    event write;
    command "/usr/bin/xdotool search --onlyvisible  --class firefox key F5";
    option (stdout, stderr, wait);
}

これは、writeに変更があるたびに、このコマンドが実行される設定ファイルの1つにすぎません。これは bash スクリプトも同様です。

whileループなどを使用する必要はありません。


特徴

  • ディレクトリを再帰的に監視する
  • デーモンとしてforegroundまたはbackgroundで実行できます
  • ポータブル。 UbuntuとCentOS7サーバーにあります
  • ファイル名レポート
  • ファイルマッチングをサポートする正規表現
  • 複数ファイルの監視(1種類以上のファイルを監視)
  • コマンドの実行を同期する(マルチウォッチャーがある場合)
  • syslog処理(必要に応じてsyslogに記録)
  • 簡単で使いやすいCLIおよび構成ファイルの設計

Sergey Poznyakoff によって開発されました。


インストール中

Sudo apt install direvent

しかし、そのソースコードを使用してインストールするのは非常に簡単で簡単で、最後のバージョンが得られます(現在は5.1です)。

1
Shakiba Moshiri