Laissez-moi vous donner un exemple:
$ timeout 1 yes "GNU" > file1
$ wc -l file1
11504640 file1
$ for ((sec0=`date +%S`;sec<=$(($sec0+5));sec=`date +%S`)); do echo "GNU" >> file2; done
$ wc -l file2
1953 file2
Ici vous pouvez voir que la commande yesécrit des 11504640lignes en une seconde alors que je ne peux écrire que des 1953lignes en 5 secondes en utilisant bash foret echo.
Comme suggéré dans les commentaires, il existe différentes astuces pour le rendre plus efficace, mais aucune ne correspond à la vitesse de yes:
$ ( while :; do echo "GNU" >> file3; done) & pid=$! ; sleep 1 ; kill $pid
[1] 3054
$ wc -l file3
19596 file3
$ timeout 1 bash -c 'while true; do echo "GNU" >> file4; done'
$ wc -l file4
18912 file4
Ceux-ci peuvent écrire jusqu'à 20 000 lignes en une seconde. Et ils peuvent être encore améliorés pour:
$ timeout 1 bash -c 'while true; do echo "GNU"; done >> file5'
$ wc -l file5
34517 file5
$ ( while :; do echo "GNU"; done >> file6 ) & pid=$! ; sleep 1 ; kill $pid
[1] 5690
$ wc -l file6
40961 file6
Cela nous amène à 40 000 lignes en une seconde. Mieux, mais loin de là, yeson peut écrire environ 11 millions de lignes en une seconde!
Alors, comment yesécrire dans un fichier si rapidement?
datepoids est assez lourd. En outre, le shell doit rouvrir le flux de sortie echopour chaque itération de la boucle. Dans le premier exemple, il n'y a qu'une seule invocation de commande avec une seule redirection de sortie, et la commande est extrêmement légère. Les deux ne sont nullement comparables.
datepeut être lourd, voir modifier à ma question.
timeout 1 $(while true; do echo "GNU">>file2; done;)est la mauvaise façon d'utiliser timeout car la timeoutcommande ne démarrera qu'une fois la substitution de commande terminée. Utilisez timeout 1 sh -c 'while true; do echo "GNU">>file2; done'.
write(2)appels système, et non aux charges de bateaux d'autres appels système, à la surcharge du shell ou même à la création de processus dans votre tout premier exemple (qui s'exécute et attend datepour chaque ligne imprimée dans le fichier). Une seconde d’écriture suffit à peine à goulot d’étranglement sur les E / S du disque (plutôt que sur le processeur / la mémoire), sur un système moderne disposant de beaucoup de RAM. Si on laisse courir plus longtemps, la différence serait moins grande. (En fonction de la qualité de votre implémentation bash et de la vitesse relative du processeur et du disque, il est possible que vous ne saturiez même pas les E / S du disque avec bash).