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 é executado rsync
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
echo 'new content' >somefile.new
mv -f somefile.new somefile
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 novo somefile
é um arquivo diferente com o mesmo nome.) Se o Vim tivesse sido configurado para criar um arquivo de backup, o que aconteceria seria algo como
echo 'new content' >somefile.new
ln somefile somefile.old
mv -f somefile.new somefile
e 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
inotifywait -m -e close_write,moved_to --format %e/%f . |
while IFS=/ read -r events file; do
if [ "$file" = "somefile" ]; then
…
fi
done