O redirecionamento da saída para um arquivo aplica um bloqueio ao arquivo?

O redirecionamento da saída para um arquivo aplica um bloqueio ao arquivo?

Se eu tiver um comando

$ ./script >> file.log

que é chamado duas vezes, com a segunda chamada ocorrendo antes do término da primeira, o que acontece?

A primeira chamada obtém um bloqueio exclusivo no arquivo de saída? Em caso afirmativo, o segundo script falha ao tentar escrever ou o shell aceita a saída (permitindo que o script termine) e gera um erro?

Ou o arquivo de log é gravado duas vezes?

Responder1

Os sistemas Unix em geral evitam bloqueios obrigatórios. Existem alguns casos em que o kernel bloqueará um arquivo contra modificações feitas por programas do usuário, mas não se ele estiver apenas sendo escrito por outro programa. Nenhum sistema Unix bloqueará um arquivo porque um programa está gravando nele.

Se você deseja que instâncias simultâneas do seu script não pisem umas nas outras, você precisa usar um mecanismo de bloqueio explícito, comoflock lockfile.

Quando você abre um arquivo para anexar, o que >>acontece, é garantido que cada programa sempre grave no final do arquivo. Portanto, a saída das múltiplas instâncias nunca se sobrescreverá e, se elas se revezarem na gravação, a saída estará na mesma ordem das gravações.

A coisa ruim que pode acontecer é se uma das instâncias gravar vários pedaços de saída e esperar que eles saiam juntos. Entre gravações consecutivas de uma instância, outras instâncias podem realizar suas próprias gravações. Por exemplo, se a instância 1 escreve foo, então a instância 2 escreve helloe só então a instância 2 escreve bar, então o arquivo conterá foohellobar.

Um processo grava efetivamente no arquivo quando chama a writechamada do sistema. Uma chamada to writeé atômica: cada chamada to writeescreve uma sequência de bytes que não será interrompida por outros programas. Muitas vezes há um limite para a quantidade de dados que uma única chamada writegravará efetivamente: para tamanhos maiores, apenas o início dos dados é gravado e o aplicativo deve chamar writenovamente. Além disso, muitos programas executamcarregando: eles acumulam dados em uma área de memória e, em seguida, gravam esses dados em um bloco. Alguns programas liberam o buffer de saída após uma linha completa ou outra separação significativa. Com esses programas, você pode esperar que linhas inteiras sejam ininterruptas, desde que não sejam muito longas (até alguns kilobytes; isso depende do sistema operacional). Se o programa não liberar em pontos significativos, mas apenas com base no tamanho do buffer, você poderá ver algo como 4kB de uma instância, depois 4kB de outra instância, novamente 4kB da primeira instância e assim por diante.

Responder2

Como você está usando >>, o que significa anexar, cada linha de saída de cada instância será anexada na ordem em que ocorreu.

Se a saída do seu script for impressa 1\ncom 5\num atraso de um segundo entre cada uma e a instância dois for iniciada 2,5 segundos depois, você obterá o seguinte:

1
2
1
3
2
4
3
5
4
5

Então, para responder à sua pergunta: Não.

informação relacionada