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(포터블 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대상 파일이 있으면 덮어쓰므 로 이름을 바꾸면 아무런 효과가 없습니다 .

관련 정보