vim과 함께 inotifywait 사용


14

변경 사항을 파일을 모니터링하고 원격 복사로 rsync하는 간단한 스크립트가 있습니다.

#!/bin/bash

while inotifywait -e close_write somefile
do
    rsync somefile user@host.domain:./somefile
done

nano에서는 잘 작동하지만 vim에서는 실패합니다. 나노를 사용하면 다음과 같이 출력됩니다.

somefile CLOSE_WRITE,CLOSE   

다른 판을 기다리는 다음 루프를 시작합니다.

vim을 사용하면 출력이 없으며 스크립트는 종료 코드 0으로 닫힙니다.

나는 약간의 연구를하고 close_write가 vim과 함께 initofywait를 사용하기위한 올바른 매개 변수라는 것을 알았습니다 (먼저 수정 이벤트를 사용하고 싶었습니다). 그러나 어떤 이유로 든 실패합니다.


그것은 나를 위해 작동합니다. 편집하기 위해 파일을 여는 대신 파일을 저장하기 전에 vim에서 파일을 변경 했 습니까?
roaima

@roaima backupcopy옵션이 꺼져있는 경우에만 작동합니다 .
Gilles 'SO- 악의를 그만두십시오'

답변:


15

편집자는 몇 가지 전략에 따라 파일을 저장할 수 있습니다. 두 가지 주요 변형은 기존 파일을 덮어 쓰거나 새 파일에 쓰고 제자리로 옮기는 것입니다. 새 파일에 쓰고 제자리로 옮기면 파일에서 읽을 때 파일의 전체 버전을 제공하는 좋은 속성이 있습니다 (하나는 이전 파일, 다음은 새로운 파일). 파일을 덮어 쓰면 파일이 불완전한 시간이있어 다른 프로그램이 파일에 액세스하거나 시스템이 충돌하는 경우 문제가됩니다.

Nano는 기존 파일을 덮어 씁니다. 스크립트는 쓰기가 완료된 시점 ( close_write이벤트)을 감지하고 rsync해당 시점에서 실행됩니다 . rsync가 첫 번째 저장에서 작업을 완료하기 전에 rsync가 파일의 불완전한 버전을 빠르게 두 번 저장하는 경우 rsync가 파일의 불완전한 버전을 가져올 수 있습니다.

반면에 Vim은 write-then-move 전략을 사용합니다.

echo 'new content' >somefile.new
mv -f somefile.new somefile

이전 버전의 파일에서 발생하는 일은 새 버전이 제자리로 이동되는 시점에서 파일이 삭제된다는 것입니다. 이 시점에서 inotifywait감시하라는 파일이 더 이상 존재하지 않기 때문에 명령이 반환됩니다. (새 somefile파일은 이름이 같은 다른 파일입니다.) Vim이 백업 파일을 만들도록 구성된 경우 다음과 같은 결과가 발생합니다.

echo 'new content' >somefile.new
ln somefile somefile.old
mv -f somefile.new somefile

그리고 inotifywait지금 백업을 지켜보고있을 것이다.

파일 저장 전략에 대한 자세한 내용 은 프로그램이 실행되는 동안 어떻게 실시간 업데이트를 수행 할 수 있습니까?를 참조하십시오. 파일 권한 및 저장

Vim은 덮어 쓰기 전략을 사용하도록 지시 할 수 있습니다 . backupcopy옵션 을 끄십시오 ( :set nobackupcopy). 위에 표시된대로 이는 위험합니다.

두 가지 저장 전략을 모두 처리하려면 디렉토리를보고 이벤트 close_write와를 모두 필터링하십시오 .moved_tosomefile

inotifywait -m -e close_write,moved_to --format %e/%f . |
while IFS=/ read -r events file; do
  if [ "$file" = "somefile" ]; then
    …
  fi
done

여기에 제안 된 방법의 단점은 여러 파일을 "한 번에"작성할 때 명령이 각 파일마다 한 번씩 실행된다는 것입니다. 코드를 편집 중이므로 헤더와 몇 가지 다른 번역 단위 및을 수정할 수 있습니다 :wa. 그런 다음 작성된 모든 파일에 대해 내 빌드가 한 번 실행됩니다.
제한적 속죄

@LimitedAtonement이 질문의 경우보다 훨씬 더 복잡한 사용 사례입니다. 사용 사례의 경우 하나의 파일을 저장 한 후 약간 기다려야합니다. 파일은 실제로 "한 번에"수정되지 않습니다. 를 사용하여 여러 파일을 저장 :wa하면 연속적인 inotify 이벤트가 발생합니다. 다른 사람이 올지 확인하려면 첫 번째 항목을 기다려야합니다. 그러나 여기에 제시된 코드를 사용할 수 있습니다. 추가 복잡성은 내부에 있습니다.
Gilles 'SO- 악마 그만

@Gilles 나는 while true; do inotifywait ... [no -m]; make; sleep .1; done;그렇게 결정했다 . 몇 가지 문제가 있지만 실제로 실행 가능한 무언가에 도달했습니다.
제한적 속죄
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.