¿Redirigir la salida a un archivo aplica un bloqueo en el archivo?

30

Si tengo un comando

$ ./script >> file.log

que se llama dos veces, con la segunda llamada antes de que termine la primera, ¿qué sucede?

¿La primera llamada obtiene un bloqueo exclusivo en el archivo de salida? Si es así, ¿falla el segundo script al intentar escribir, o el shell acepta la salida (permitiendo que finalice el script) y arroja un error?

¿O el archivo de registro se escribe dos veces?


fuente
1
No conozco ningún sistema que bloquee el archivo por defecto. Lo más probable es que los dos programas terminen intercalando sus escrituras, ya que ambos estarían en modo de agregado. Los resultados serían bastante impredecibles. En lugar de "hola mundo" podrías obtener "hweolrllod".
jw013

Respuestas:

18

Como está utilizando >>, lo que significa agregar, cada línea de salida de cada instancia se agregará en el orden en que ocurrió.

Si las impresiones de salida de secuencia de comandos 1\na través 5\nde un retardo de un segundo entre cada dos y la instancia se inicia 2,5 segundos después que obtendrá la siguiente:

1
2
1
3
2
4
3
5
4
5

Así que para responder a su pregunta, no.

bahamat
fuente
23

Los sistemas Unix en general evitan bloqueos obligatorios. Hay algunos casos en los que el kernel bloqueará un archivo contra modificaciones por parte de los programas del usuario, pero no si solo lo está escribiendo otro programa. Ningún sistema Unix bloqueará un archivo porque un programa lo está escribiendo.

Si desea que las instancias simultáneas de su script no pisen los dedos de los demás, debe utilizar un mecanismo de bloqueo explícito como .flock lockfile

Cuando abre un archivo para anexar, lo que >>hace, se garantiza que cada programa siempre escriba al final del archivo. Por lo tanto, la salida de varias instancias nunca se sobrescribirá entre sí, y si se turnan para escribir, su salida estará en el mismo orden que las escrituras.

Lo malo que podría suceder es si una de las instancias escribe varios fragmentos de salida y espera que salgan juntos. Entre escrituras consecutivas por una instancia, otras instancias pueden realizar sus propias escrituras. Por ejemplo, si la instancia 1 escribe foo, la instancia 2 escribe helloy solo entonces la instancia 2 escribe bar, entonces el archivo contendrá foohellobar.

Un proceso escribe efectivamente en el archivo cuando llama a la writellamada del sistema. Una llamada a writees atómica: cada llamada a writeescribe una secuencia de bytes que no serán interrumpidos por otros programas. A menudo hay un límite en la cantidad de datos que una sola llamada writeescribirá efectivamente: para tamaños más grandes, solo se escribe el comienzo de los datos y la aplicación debe writevolver a llamar . Además, muchos programas realizan el almacenamiento en búfer: acumulan datos en un área de memoria, luego los escriben en un fragmento. Algunos programas descargan el búfer de salida después de una línea completa u otra separación significativa. Con estos programas, puede esperar que las líneas enteras no se interrumpan, siempre que no sean demasiado largas (hasta unos pocos kilobytes; esto depende del sistema operativo). Si el programa no se descarga en puntos significativos, sino que solo se basa en el tamaño del búfer, es posible que vea algo como 4kB de una instancia, luego 4kB de otra instancia, luego nuevamente 4kB de la primera instancia y así sucesivamente.

Gilles 'SO- deja de ser malvado'
fuente