inotifywaitを使用して、特定の拡張子のファイルが作成されるディレクトリを監視する方法


21

私はこの答えを見ました

例として、inotifywaitの使用を検討する必要があります。

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

私の質問は、上記のスクリプトは任意のタイプのファイルの作成のためにディレクトリを監視しinotifywaitますが、特定のタイプ/拡張子のファイルが作成された(またはディレクトリに移動された)ときにのみレポートするようにコマンドを変更するにはどうすればよいですか?.xmlファイルが作成されたときにレポートします。

私が試したもの:

inotifywait --helpコマンドを実行し、コマンドラインオプションを読みました。それは持っている--exclude <pattern>--excludei <pattern>するコマンドEXCLUDE(正規表現を使用して)特定の種類のファイルを、私はする方法が必要ですちょうどINCLUDE特定のタイプ/拡張子のファイルを。


ところで、pathこれをシェルで最初にプレイしたい場合、上記を使用することはおそらく最良の変数名ではありません。これを使用する場合、コマンドとすべてを使用することはできませんPATH。これは基本的に標準をオーバーライドしたためです。したがって、代わりに、別の変数名を使用することをお勧めしfpathます。つまりwhile read fpath action file、シェルから通常使用可能な標準コマンドは引き続き使用できます。
バプテストマサス

includeオプションがないのは、とんでもないことです。
erandros

回答:


17

特定のタイプ/拡張子のファイルが作成されたときにのみレポートするようにinotifywaitコマンドを変更するにはどうすればよいですか

私は今アクセスできないので、これはテストされていないコードであることに注意してくださいinotify。しかし、これに似た何かが機能するはずです:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
            echo "xml file" # If so, do your thing here!
        fi
    done

2
これは機能し、inotifywaitでテストしました。
-TheBetterJORT

1
これをどのように実行しますか?それは1回限りのコマンドですか、それともループなどで実行する必要がありますか?おそらくincron(私はそうではないことを願っています)の一部として。
SDsolar

@SDsolarさまざまです。私にとっては、通常、カスタムsystemdサービスをinotify使用して実行するか、nohupそれを開始します。ほとんどの場合、後者。
maulinglawns

9

二重否定を使用します。

inotifywait -m --exclude "[^j][^s]$" /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
    done

これにはjavascriptファイルのみが含まれます


1
ニース、inotifywaitすべてのファイルの巨大な出力を生成し、後でフィルタリングするのではなく、フィルタリングをシフトするのが好きです(他の答えのように)。試したことはありませんが、少し速くなると思います。
TMG

これはまさに私が探していたものです。--exclude入力を変更して.extファイルを監視する方法。これは一度だけ実行されますか、またはforループで実行されますか?
-kurokirasama

これはデーモンなので、クラッシュするかシャットダウンするまで実行されます:)
ジョナスアレンデル

申し訳ありませんが、最初の質問を逃しました。 inotifywait -m --exclude "[^.][^e][^x][^t]$" /home/jonas/Skrivbord/test -e create -e moved_to | while read path action file; do echo "The file '$file' appeared in directory '$path' via '$action'" done 正規表現は最適化できると確信していますが、この赤ちゃんは動作します:)
ジョナスアレンデル

ありがとう!やってみます!!
-kurokirasama

3

前の回答の二重否定アプローチは(TMGが指摘したように)実際にフィルタリングのジョブをにシフトするため、良いアイデアですがinotifywait、それは正しくありません。

たとえば、ファイルが終了asすると[^j][^s]$、最後の文字sが一致しないため一致しないため、[^s]除外されません。

ブール用語では、if Sが次のステートメントです。

「最後の手紙はs

そしてJ、ステートメントです:

「最後から2番目の手紙はj

次に、--excludeパラメータの値は、意味的にに等しくなるはずです。not(J and S)これは、De Morganの法則によりnot(J) or not(S)

別の潜在的な問題は、inがzsh$path相当する配列を表す組み込み変数$PATHであるため、while read path ...行が完全に混乱し$PATH、すべてがシェルから実行不能になることです。

したがって、正しいアプローチは次のとおりです。

inotifywait -m --exclude "[^j].$|[^s]$" /path -e create -e moved_to |
    while read dir action file; do
        echo "The file '$file' appeared in directory '$dir' via '$action'"
    done

一致が最後から2番目の位置に適用されるようにするために.必要なことに注意してください。[^j]また、POSIX拡張正規表現を使用|するため、文字(上記のブールORを表す)をここでエスケープしないでください--exclude

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.