Можно ли создать непустой файл без write_close и переименовать событие?

Причина, по которой я спрашиваю, заключается в том, что я использую iwatch (чтобы не путать с устройством гаджета), чтобы следить за событиями файловой системы (в моем случае – создание / переименование файлов).

Я не могу объяснить этот журнал:

  • Копирование последовательных файлов
  • Невозможно изменить разрешения файлов / каталогов в chrooted файловой системе
  • Тестирование для определенного формата файла
  • Как перечислить символические ссылки с sftp?
  • Просмотр разрешения / владельца полного дерева каталогов
  • Как перенести файл в каталог другого пользователя?
  • /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 

    Чтобы получить его, я скопировал file.ext с удаленной машины с использованием 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 был создан с содержимым без явного переименования или копии данных?

  • Я хочу перечислить все файлы на моем Linux-сервере, которые старше 31 декабря 2014 года.
  • Права на наследование файлов каталога, на которые он скопирован?
  • Скрипт для изменения времени изменения файлов и каталогов рекурсивно
  • Аудиофайлы, измененные командой bash, переименовывая их
  • tar-файлы из другого каталога без их копирования
  • команда du показывает разные результаты, чем st_blocks
  • One Solution collect form web for “Можно ли создать непустой файл без write_close и переименовать событие?”

     $ 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 , но создание жесткой ссылки создает одно и то же событие создания, как создание нового, пустого файла (как и 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 перезаписывает целевой файл, если он существует.

    Linux и Unix - лучшая ОС в мире.