Déjame dar un ejemplo:
$ 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
Aquí puede ver que el comando yesescribe 11504640líneas en un segundo, mientras que solo puedo escribir 1953líneas en 5 segundos usando bash fory echo.
Como se sugiere en los comentarios, hay varios trucos para hacerlo más eficiente, pero ninguno se acerca a la velocidad 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
Estos pueden escribir hasta 20 mil líneas en un segundo. Y se pueden mejorar aún más para:
$ 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
Estos nos llevan hasta 40 mil líneas en un segundo. Mejor, ¡pero aún está muy lejos de yespoder escribir alrededor de 11 millones de líneas en un segundo!
Entonces, ¿cómo se yesescribe en el archivo tan rápido?
datees algo pesado, además el shell tiene que volver a abrir la secuencia de salida echopara cada iteración del bucle. En el primer ejemplo, solo hay una invocación de comando único con una única redirección de salida, y el comando es extremadamente ligero. Los dos no son de ninguna manera comparables.
datepuede ser pesado, vea la edición de mi pregunta.
timeout 1 $(while true; do echo "GNU">>file2; done;)es la forma incorrecta de usar timeout ya que el timeoutcomando solo comenzará una vez que finalice la sustitución del comando. Utilizar timeout 1 sh -c 'while true; do echo "GNU">>file2; done'.
write(2)llamadas del sistema, no a las cargas de otros syscalls, la sobrecarga de shell o incluso la creación de procesos en su primer ejemplo (que se ejecuta y espera datecada línea impresa en el archivo). Un segundo de escritura es apenas suficiente para que se produzca un cuello de botella en la E / S de disco (en lugar de CPU / memoria), en un sistema moderno con mucha RAM. Si se le permite correr más tiempo, la diferencia sería menor. (Dependiendo de cuán mala sea la implementación de bash que use y la velocidad relativa de la CPU y el disco, es posible que ni siquiera sature la E / S del disco con bash).