Eu tenho um script simples que monitora o arquivo para alterações e o sincroniza com cópia remota:
#!/bin/bash
while inotifywait -e close_write somefile
do
rsync somefile [email protected]:./somefile
done
Funciona muito bem com o nano, mas falha com o vim. Quando eu uso o nano, ele gera:
somefile CLOSE_WRITE,CLOSE
e inicia o próximo loop aguardando outra edição.
Quando uso o vim, não há saída, o script é fechado com o código de saída 0.
Eu fiz algumas pesquisas e descobri que close_write é o parâmetro certo para usar o initofywait junto com o vim (primeiro eu queria usar o evento de modificação), mas, por algum motivo, ele falhou para mim.
backupcopy
opção estiver desativada.Respostas:
Os editores podem seguir várias estratégias para salvar um arquivo. As duas principais variantes são substituir o arquivo existente ou gravar em um novo arquivo e movê-lo no lugar. Gravar em um novo arquivo e movê-lo no lugar tem a propriedade legal de que, a qualquer momento, a leitura do arquivo fornece uma versão completa do arquivo (um instante, o antigo, o próximo, o novo). Se o arquivo for sobrescrito no local, haverá um período incompleto, o que é problemático se algum outro programa acessá-lo naquele momento ou se o sistema travar.
Aparentemente, o Nano substitui o arquivo existente. Seu script detecta o ponto quando termina de escrever (o
close_write
evento) e é executadorsync
nesse ponto. Observe que é possível que o rsync pegue uma versão incompleta do arquivo, se você salvar duas vezes em rápida sucessão, antes que o rsync conclua seu trabalho desde o primeiro salvamento.O Vim, por outro lado, usa a estratégia de escrever e mover - algo para o efeito de
O que acontece com a versão antiga do arquivo é que ela é excluída no ponto em que a nova versão é movida para o local. Nesse ponto, o
inotifywait
comando retorna, porque o arquivo que foi instruído a assistir não existe mais. (O novosomefile
é um arquivo diferente com o mesmo nome.) Se o Vim tivesse sido configurado para criar um arquivo de backup, o que aconteceria seria algo comoe
inotifywait
agora estaria assistindo o backup.Para obter mais informações sobre estratégias para salvar arquivos, consulte Como é possível fazer uma atualização ao vivo enquanto um programa está em execução? e Permissões de arquivo e salvamento
Pode-se dizer ao Vim para usar a estratégia de substituição: desative a
backupcopy
opção (:set nobackupcopy
). Isso é arriscado, como indicado acima.Para lidar com as duas estratégias de salvamento, observe o diretório e filtre os eventos
close_write
e .moved_to
somefile
fonte
:wa
. Então minha compilação é executada uma vez para cada arquivo gravado.:wa
, obtém sucessivos eventos de inotificação. Você precisaria esperar depois do primeiro para ver se outros estão chegando. Mas você pode usar o código apresentado aqui: a complexidade adicional entraria no…
.while true; do inotifywait ... [no -m]; make; sleep .1; done;
ou menos. Existem algumas dicas, mas cheguei a algo bastante viável.