Suponha que eu li (cat) um arquivo enquanto outro processo está reescrevendo seu conteúdo. A saída é previsível? O que aconteceria?
Suponha que eu li (cat) um arquivo enquanto outro processo está reescrevendo seu conteúdo. A saída é previsível? O que aconteceria?
Respostas:
Isso depende do que o escritor faz.
Se o gravador substituir o arquivo existente, o leitor verá o novo conteúdo quando o gravador ultrapassar o leitor, se for o caso. Se o escritor e o leitor prosseguirem em velocidades variáveis, o leitor poderá ver alternativamente o conteúdo antigo e o novo.
Se o gravador truncar o arquivo antes de começar a gravar, o leitor será executado no final do arquivo nesse momento.
Se o gravador criar um novo arquivo e depois mover o novo arquivo para o nome antigo, o leitor continuará lendo o arquivo antigo. Se um arquivo aberto for movido ou removido, os processos que abriram o arquivo continuarão lendo esse mesmo arquivo. Se o arquivo for removido, ele realmente permanecerá no disco (mas não será possível abri-lo novamente) até que o último processo o feche.
Os sistemas Unix tendem a não ter bloqueios obrigatórios . Se um aplicativo deseja garantir que seu componente gravador e seu componente leitor não pisem nos dedos um do outro, cabe ao desenvolvedor usar o bloqueio adequado. Existem algumas exceções em que um arquivo aberto pelo kernel pode ser protegido contra gravação por aplicativos do usuário, por exemplo, uma imagem de sistema de arquivos montada em loop ou um executável que está sendo executado em algumas variantes do unix.
ftp
/ sftp
cenários? Digamos que um processo comece a ler um ftp
arquivo transmitido enquanto outra versão do mesmo arquivo o substitui devido a uma nova transmissão.
É uma condição clássica de corrida, portanto o resultado é imprevisível por definição.
Entre outros, depende de
fopen(3)
ou open(2)
modos de gravação,Se você precisar ler um arquivo enquanto ele estiver sendo reescrito, poderá fazer com que o gravador faça uma cópia temporária do arquivo, modifique-o e copie-o novamente para o arquivo original. É assim que se rsync
faz, por exemplo. Existem várias maneiras de implementar isso, mas não há almoço grátis. Cada método tem suas próprias deficiências e repercussões.
Os respondentes anteriores têm explicações mais abrangentes do que isso, mas aqui está um truque que definitivamente também funciona, praticamente fazendo exatamente o que ele deseja:
$ tail -f <filename>
Irá mostrar o final do arquivo enquanto ele está sendo gravado. Prático, se você deseja canalizar o STDERR para um arquivo, mas ainda o vê em outra janela do terminal, por exemplo.