私が尋ねる理由は私が使っているからです。私は読んだ(ガジェットデバイスと混同しないでください)ファイルシステムイベント(私の場合はファイルの作成/名前変更)を監視します。
私が説明できないのはこのログです。
/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
(どれもわかりませんが、すべての魔法が起こる場所だと仮定します)。
ここで最も奇妙なことは次のとおりです。
- これは
file.ext
移動の結果ではありませんfile.ext.filepart
。他の移動イベントがある可能性があります。 - これは
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
ターゲットファイルがある場合は上書きされるため、名前を変更しても効果はありません。