Y a-t-il une différence entre ces 2 lignes?

for i in $(seq 1 10); do echo $i - `date`; sleep 1; done >> /tmp/output.txt

for i in $(seq 1 10); do echo $i - `date` >> /tmp/output.txt ; sleep 1; done

Parce que Robert m'a dit que le premier ne fait que l'OP d'E / S en dehors de la boucle for.

Mais si je tape tail -f /tmp/output.txt, cela se comporte exactement de la même manière.

4
Bast 28 déc. 2015 à 16:21

2 réponses

Meilleure réponse

Ils font de même s'ils réussissent. Cependant, il peut y avoir des différences notables en cas d'échec pour une raison quelconque.

Le premier:

for ...; do
   # things
done >> file

Cela redirigera vers le fichier soi-disant une fois la boucle terminée. Cependant, cela peut arriver chaque fois que Bash décide de vider le tampon.

Imaginez que quelque chose échoue après l'itération numéro 3: vous ne pouvez pas dire ce qui a été stocké après dans le fichier.

Le deuxième:

for ...; do
   # things >> file
done

Cela redirigera vers le fichier à chaque itération.

Imaginez que quelque chose échoue après l'itération numéro 3: vous êtes sûr que les deux premières boucles ont été correctement stockées dans le fichier.

Depuis Comment rediriger la sortie d'un programme en boucle infinie:

Si votre programme utilise les fonctions de sortie standard (par exemple puts, printf et amis de stdio.h en C, cout << … en C ++, print dans de nombreux langages de haut niveau), alors sa sortie est tamponné: les caractères s'accumulent dans une zone de mémoire appelée tampon; quand il y a trop de données dans le tampon, le contenu du tampon est imprimé (il est «vidé») et le tampon devient vide (prêt à être rempli à nouveau). Si votre programme ne produit pas beaucoup de sortie, il peut ne pas ont encore rempli sa mémoire tampon.

Aussi, à partir de la réponse que vous liez:

Placer l’opérateur de redirection à l’extérieur de la boucle double le performances lors de l'écriture de 500000 lignes (sur mon système).

Cela a du sens: si vous devez vider chaque boucle, cela prend plus de temps que de laisser Bash vider chaque fois qu'il le trouve pratique. Il est plus facile d'écrire cinq lignes à la fois qu'une ligne à chaque fois.

3
Community 13 avril 2017 à 12:36

Il y a une autre différence importante qui n'a pas été mentionnée: >> ouvre le fichier pour l'écriture à chaque fois. Cela peut affecter sensiblement les performances.

De plus, si /tmp/output.txt est supprimé pendant que la boucle est en cours d'exécution, echo ... >> /tmp/output.txt recréera le fichier avec un nouveau contenu, tandis que for ... done >> /tmp/output.txt continuera d'ajouter des données au même fichier.

C'est quelque chose d'important à retenir, surtout si nous avons affaire à des liens physiques ou des fichiers temporaires (en général, nous dissocions les fichiers temporaires peu de temps après leur création, pour éviter d'avoir des fichiers périmés si le script Bash se ferme de manière inattendue).

0
Andrea Corbellini 28 déc. 2015 à 14:48