Lasciami fare un esempio:
$ 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
Qui puoi vedere che il comando yesscrive 11504640righe in un secondo mentre posso scrivere solo 1953righe in 5 secondi usando bash fore echo.
Come suggerito nei commenti, ci sono vari trucchi per renderlo più efficiente, ma nessuno si avvicina alla corrispondenza della velocità di 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
Questi possono scrivere fino a 20 mila righe in un secondo. E possono essere ulteriormente migliorati per:
$ 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
Questi ci portano fino a 40 mila linee in un secondo. Meglio, ma ancora un grido lontano dal yesquale può scrivere circa 11 milioni di righe in un secondo!
Quindi, come si yesscrive in un file così rapidamente?
dateè piuttosto pesante, inoltre la shell deve riaprire il flusso di output echoper ogni iterazione di loop. Nel primo esempio, esiste solo una singola chiamata di comando con un singolo reindirizzamento dell'output e il comando è estremamente leggero. I due non sono in alcun modo comparabili.
datepotrebbe essere pesante, vedi modifica alla mia domanda.
timeout 1 $(while true; do echo "GNU">>file2; done;)è il modo sbagliato di utilizzare timeout poiché il timeoutcomando verrà avviato solo al termine della sostituzione del comando. Usa timeout 1 sh -c 'while true; do echo "GNU">>file2; done'.
write(2)le chiamate di sistema, non per i carichi di altre scale di sistema, l'overhead della shell o persino la creazione di processi nel primo esempio (che viene eseguito e attende dateogni riga stampata nel file). Un secondo di scrittura è appena sufficiente per il collo di bottiglia sull'I / O del disco (piuttosto che sulla CPU / memoria), su un sistema moderno con molta RAM. Se fosse permesso di correre più a lungo, la differenza sarebbe più piccola. (A seconda della cattiva implementazione di bash utilizzata e della velocità relativa della CPU e del disco, potresti non saturare l'I / O del disco con bash).