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. Escrever em um novo arquivo e movê-lo para o lugar tem a boa propriedade de que, a qualquer momento, a leitura do arquivo fornece uma versão completa do arquivo (em um instante o antigo, no instante seguinte, o novo). Se o arquivo for sobrescrito no lugar, há um tempo durante o qual ele está incompleto, o que é problemático se algum outro programa o acessa naquele momento ou se o sistema travar.
O Nano aparentemente substitui o arquivo existente. Seu script detecta o ponto quando ele termina de gravar (o evento close_write
) e executa rsync
nesse ponto. Observe que é possível que o rsync capture uma versão incompleta do arquivo, se você salvar duas vezes em sucessão rápida, antes que o rsync tenha concluído seu trabalho desde o primeiro salvamento.
Vim, por outro lado, usa a estratégia write-then-move - 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 ele é excluído no ponto em que a nova versão é colocada no lugar. Neste ponto, o comando inotifywait
retorna, porque o arquivo que foi informado para assistir não existe mais. (O novo somefile
é um arquivo diferente com o mesmo nome.) Se o Vim tivesse sido configurado para fazer 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 estariam assistindo ao backup.
Para obter mais informações sobre estratégias de salvamento de arquivos, consulte Como é possível fazer uma atualização ao vivo enquanto um programa está rodando? e Permissões de arquivo e salvamento
O Vim pode ser instruído a usar a estratégia de substituição: desative o backupcopy
opção ( :set nobackupcopy
). Isso é arriscado, conforme indicado acima.
Para lidar com as duas estratégias de salvamento, assista ao diretório e filtre os eventos close_write
e moved_to
para somefile
.
inotifywait -m -e close_write,moved_to --format %e/%f . |
while IFS=/ read -r events file; do
if [ "$file" = "somefile" ]; then
…
fi
done