La redirection de la sortie vers un fichier applique-t-elle un verrou sur le fichier?

30

Si j'ai une commande

$ ./script >> file.log

qui est appelé deux fois, le deuxième appel ayant lieu avant la fin du premier, que se passe-t-il?

Le premier appel obtient-il un verrou exclusif sur le fichier de sortie? Si tel est le cas, le deuxième script échoue-t-il lors de la tentative d'écriture ou le shell accepte-t-il la sortie (permettant au script de se terminer) et renvoie-t-il une erreur?

Ou le fichier journal est-il écrit deux fois?


la source
1
Je ne connais aucun système qui verrouillerait le fichier par défaut. Ce qui est plus probable, c'est que les deux programmes finiraient par entrelacer leurs écritures, car les deux seraient en mode ajout. Les résultats seraient plutôt imprévisibles. Au lieu de "bonjour le monde", vous pouvez obtenir "hweolrllod".
jw013

Réponses:

18

Puisque vous utilisez >>, ce qui signifie ajouter, chaque ligne de sortie de chaque instance sera ajoutée dans l'ordre où elle s'est produite.

Si vos impressions de sortie de script 1\npar 5\nun délai d' une seconde entre chaque et deux par exemple est démarré 2,5 secondes plus tard , vous obtiendrez ceci:

1
2
1
3
2
4
3
5
4
5

Donc, pour répondre à votre question: Non.

bahamat
la source
23

Les systèmes Unix évitent généralement les verrous obligatoires. Il y a quelques cas où le noyau verrouille un fichier contre les modifications des programmes utilisateur, mais pas s'il est simplement écrit par un autre programme. Aucun système Unix ne verrouillera un fichier car un programme y écrit.

Si vous voulez que les instances simultanées de votre script ne marchent pas les unes sur les autres, vous devez utiliser un mécanisme de verrouillage explicite tel que .flock lockfile

Lorsque vous ouvrez un fichier à ajouter, ce qui est le >>cas, chaque programme est garanti de toujours écrire à la fin du fichier. Ainsi, la sortie des instances multiples ne se remplacera jamais et si elles écrivent à tour de rôle, leur sortie sera dans le même ordre que les écritures.

La mauvaise chose qui pourrait arriver, c'est si l'une des instances écrit plusieurs morceaux de sortie et s'attend à ce qu'ils sortent ensemble. Entre les écritures consécutives d'une instance, d'autres instances peuvent effectuer leurs propres écritures. Par exemple, si l'instance 1 écrit foo, puis l'instance 2 écrit helloet seulement alors l'instance 2 écrit bar, le fichier contient foohellobar.

Un processus écrit efficacement dans le fichier lorsqu'il appelle l' writeappel système. Un appel à writeest atomique: chaque appel à writeécrit une séquence d'octets qui ne sera pas interrompue par d'autres programmes. Il y a souvent une limite à la quantité de données qu'un seul appel writeva écrire efficacement: pour les tailles plus grandes, seul le début des données est écrit et l'application doit rappeler write. En outre, de nombreux programmes effectuent la mise en mémoire tampon: ils accumulent des données dans une zone mémoire, puis écrivent ces données en un seul morceau. Certains programmes vident le tampon de sortie après une ligne complète ou une autre séparation significative. Avec de tels programmes, vous pouvez vous attendre à ce que des lignes entières soient ininterrompues, tant qu'elles ne sont pas trop longues (jusqu'à quelques kilo-octets; cela dépend du système d'exploitation). Si le programme ne vide pas à des endroits significatifs, mais uniquement en fonction de la taille du tampon, vous pouvez voir quelque chose comme 4 Ko d'une instance, puis 4 Ko d'une autre instance, puis à nouveau 4 Ko de la première instance, etc.

Gilles, arrête de faire le mal
la source