write_closeと名前変更イベントなしで空でないファイルを生成できますか?

write_closeと名前変更イベントなしで空でないファイルを生成できますか?

私が尋ねる理由は私が使っているからです。私は読んだ(ガジェットデバイスと混同しないでください)ファイルシステムイベント(私の場合はファイルの作成/名前変更)を監視します。

私が説明できないのはこのログです。

/path/to/file.ext.filepart 0 IN_MODIFY 
/path/to/file.ext.filepart 0 IN_MODIFY 
/path/to/file.ext.filepart 0 IN_MODIFY 
/path/to/file.ext.filepart 0 IN_MODIFY 
/path/to/file.ext.filepart 0 IN_CLOSE_WRITE 
/path/to/file.ext 0 IN_CREATE 
/path/to/file.ext.filepart 0 IN_DELETE 
/path/to/file.ext 0 IN_ATTRIB 

それを取得するために、WinSCPを使用してリモートコンピュータからファイルをコピーし、一時ファイルを生成するオプションをオンにしました(転送が終了するか、ファイル全体がターゲットにある場合はファイルがまったくfile.extないことを確認します)。file.ext)。

私を混乱させるのは、/path/to/file.extそれが生成されただけで、IN_CREATEその属性が変更されるということですIN_ATTRIB(どれもわかりませんが、すべての魔法が起こる場所だと仮定します)。

ここで最も奇妙なことは次のとおりです。

  1. これはfile.ext移動の結果ではありませんfile.ext.filepart。他の移動イベントがある可能性があります。
  2. これはfile.extコピーの結果ではありませんfile.ext.filepart。後で書き込みイベントがたくさん発生します。IN_CLOSE_WRITE

だから私の質問は - 後ろで何が起こっているかです。file.ext明示的な名前の変更やデータのコピーなしでコンテンツ生成を使用するには?

ベストアンサー1

$ inotifywait -m /tmp
Setting up watches.
Watches established.
/tmp/ CREATE file.ext.filepart
/tmp/ OPEN file.ext.filepart
/tmp/ MODIFY file.ext.filepart
/tmp/ CLOSE_WRITE,CLOSE file.ext.filepart
/tmp/ CREATE file.ext
/tmp/ DELETE file.ext.filepart

ランニング履歴

$ echo hello >/tmp/file.ext.filepart
$ ln /tmp/file.ext.filepart /tmp/file.ext         
$ rm /tmp/file.ext.filepart

ファイルを移動するとmoveイベントが生成されますが、ハードリンクを作成すると、create新しい空のファイルを生成するのと同じイベントが生成されます(mkfifo他のファイルの生成方法と同様)。

SCPまたはSFTPサーバーがハードリンクを作成してから一時ファイルを所定の場所に移動するのではなく、一時ファイルを削除するのはなぜですか? OpenSSH(Portable 6.0)ソースコードのsftp-server.c関数では、process_rename次のコードを見ることができます(表示したい部分を説明するためにフォーマットを変更して単純化しました)。

if (S_ISREG(sb.st_mode)) {
    /* Race-free rename of regular files */
    if (link(oldpath, newpath) == -1) {
         if (errno == EOPNOTSUPP || errno == ENOSYS) {
            /* fs doesn't support links, so fall back to stat+rename.  This is racy. */
            if (stat(newpath, &st) == -1) {
                rename(oldpath, newpath) == -1)
            }
        }
    } else {
        unlink(newpath);
    }
}

つまり、一時ファイル名から目的のファイル名へのハードリンクを作成し、一時ファイルを削除します。オペレーティングシステムまたはファイルシステムがサポートされておらず、ハードリンクを生成できない場合は、別のアプローチを使用してください。必要なファイルがあるかどうかをテストしていない場合は、一時ファイルの名前を変更してください。したがって、コピープロセス中に作成された可能性があるファイルを上書きする危険なしに、一時ファイルの名前を最終的な場所に変更することが重要です。renameターゲットファイルがある場合は上書きされるため、名前を変更しても効果はありません。

おすすめ記事