O redirecionamento de saída para um arquivo aplica um bloqueio no arquivo?

30

Se eu tiver um comando

$ ./script >> file.log

que é chamado duas vezes, com a segunda chamada antes que a primeira termine, o que acontece?

A primeira chamada recebe um bloqueio exclusivo no arquivo de saída? Nesse caso, o segundo script falha ao tentar gravar ou o shell aceita a saída (permitindo que o script termine) e gera um erro?

Ou o arquivo de log é gravado duas vezes?


fonte
11
Não conheço nenhum sistema que bloqueie o arquivo por padrão. O mais provável é que os dois programas acabem intercalando suas gravações, pois ambos estariam no modo de acréscimo. Os resultados seriam imprevisíveis. Em vez de "olá mundo", você pode obter "hweolrllod".
Jw013 07/07/2012

Respostas:

18

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 sua saída de script impressões 1\natravés 5\ncom um segundo de atraso entre cada e exemplo dois é iniciado 2,5 segundos mais tarde você vai ter isso:

1
2
1
3
2
4
3
5
4
5

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

bahamat
fonte
23

Os sistemas Unix geralmente evitam bloqueios obrigatórios. Existem alguns casos em que o kernel bloqueia um arquivo contra modificações feitas por programas do usuário, mas não se estiver apenas sendo gravado 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 nos dedos um do outro, é necessário usar um mecanismo de bloqueio explícito, como .flock 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 várias instâncias nunca se substituirá e, se elas revezarem na gravação, a saída será na mesma ordem que as gravações.

O ruim que poderia acontecer é se uma das instâncias gravar vários blocos de saída e esperar que eles saiam juntos. Entre gravações consecutivas por uma instância, outras instâncias podem executar suas próprias gravações. Por exemplo, se a instância 1 gravar foo, a instância 2 gravar helloe somente a instância 2 gravar bar, o arquivo conterá foohellobar.

Um processo efetivamente grava no arquivo quando chama a writechamada do sistema. Uma chamada para writeé atômica: cada chamada writegrava uma sequência de bytes que não será interrompida por outros programas. Geralmente, 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 executam buffering: eles acumulam dados em uma área de memória e gravam esses dados em um único 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 descarregar 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 e novamente 4kB da primeira instância e assim por diante.

Gilles 'SO- parar de ser mau'
fonte