inotifywait-名前を変更するときに古いファイル名と新しいファイル名を取得する


8

ファイルの名前変更を検出し、古いファイル名と新しいファイル名の両方を取得する信頼できる方法を探しています。これは私がこれまでに持っているものです:

COUNTER=0;
inotifywait -m --format '%f' -e moved_from,moved_to ./ | while read FILE
do
if [ $COUNTER -eq 0 ]; then
    FROM=$FILE;
    COUNTER=1;
else
    TO=$FILE;
    COUNTER=0;
    echo "sed -i 's/\/$FROM)/\/$TO)/g' /home/a/b/c/post/*.md"
    sed -i 's/\/'$FROM')/\/'$TO')/g' /home/a/b/c/post/*.md
fi
done

動作しますが、監視フォルダーにファイルを移動したり、監視フォルダーからファイルを移動したりしないことを前提としています。また、イベントは、最初にmoved_from、次にmoved_toのペアで発生すると想定しています。これが常に正しいかどうかはわかりません(これまでのところ機能します)。

私はinotifyがcookieを使用してイベントをリンクすることを読みました。クッキーはどういうわけかアクセス可能ですか?クッキーがないので、タイムスタンプを使用してイベントをリンクすることを考えました。FROMとTOをより信頼できる方法で取得するためのヒントはありますか?

完全なスクリプトの要点

回答:


6

私はあなたのアプローチは正しいと思います、そしてクッキーを追跡することはこれを行う強力な方法です。ただし、cookie参照されるinotify-tools(3.14)のソース内の唯一の場所はstruct、カーネルAPIと一致するように定義するヘッダー内です。

エッジに住むのが好きな場合、このパッチ(問題#72)は3.14にきれいに適用%cされ、イベントCookieのフォーマット指定子を16進数で追加します。

--- libinotifytools/src/inotifytools.c.orig     2014-10-23 18:05:24.000000000 +0100
+++ libinotifytools/src/inotifytools.c  2014-10-23 18:15:47.000000000 +0100
@@ -1881,6 +1881,12 @@
                        continue;
                }

+               if ( ch1 == 'c' ) {
+                       ind += snprintf( &out[ind], size-ind, "%x", event->cookie);
+                       ++i;
+                       continue;
+               }
+
                if ( ch1 == 'e' ) {
                        eventstr = inotifytools_event_to_str( event->mask );
                        strncpy( &out[ind], eventstr, size - ind );

この変更によりlibinotifytools.soinotifywaitバイナリではなくが変更されます。インストール前にテストするには:

LD_PRELOAD=./libinotifytools/src/.libs/libinotifytools.so.0.4.1 \
  inotifywait  --format="%c %e %f" -m -e move /tmp/test
Setting up watches.
Watches established.
40ff8 MOVED_FROM b
40ff8 MOVED_TO a

MOVED_FROMは常にMOVED_TO前に発生したと仮定すると(それは、見ないfsnotify_move()、そしてそれはだ注文キューの独立した動きがけれども、かもしれない、あなたは(おそらくIDでインデックス化連想配列で)MOVED_FROMラインを見ると、あなたが詳細をキャッシュするスクリプトでインターリーブます)そして、情報の半分が一致するMOVED_TOが表示されたら、処理を実行します。

declare -A cache
inotifywait  --format="%c %e %f" -m -e move /tmp/test |
while read id event file; do
    if [ "$event" = "MOVED_FROM" ]; then
        cache[$id]=$file
    fi
    if [ "$event" = "MOVED_TO" ]; then
        if [ "${cache[$id]}" ]; then
            echo "processing ..."
            unset cache[$id]
        else
            echo "mismatch for $id"
        fi
    fi
done

(3つのスレッドが実行されて10,000回ずつファイルのペアをシャッフルするので、1つの順序の乱れたイベントやイベントインターリーブを見たことはありません。もちろん、ファイルシステムや他の条件に依存する場合があります。)


1
綺麗な。これほど詳細で役立つ答えを受け取ったことはありません。どうもありがとうございます!!パッチを公式バージョンに含めると、テキストファイル(html、css、mdなど)と参照されるアセット(jpg、gif、mp4など)の整合性を保つのに役立つツールの作成が容易になると思います。プルリクエストを送信していますか?:)
aBe

この機能が公式バージョンになることを願っていますが、私はそれをforkしていません。また、forkしてすべてのコメント(doxygen)を更新する時期がいつになるかわかりません。
mr.spuratic 2014年

これをアップストリームで取得するのは本当にクールでしょう!
Tim Stoop、2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.