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 yes
scrive 11504640
righe in un secondo mentre posso scrivere solo 1953
righe in 5 secondi usando bash for
e 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 yes
quale può scrivere circa 11 milioni di righe in un secondo!
Quindi, come si yes
scrive in un file così rapidamente?
date
è piuttosto pesante, inoltre la shell deve riaprire il flusso di output echo
per 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.
date
potrebbe essere pesante, vedi modifica alla mia domanda.
timeout 1 $(while true; do echo "GNU">>file2; done;)
è il modo sbagliato di utilizzare timeout
poiché il timeout
comando 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 date
ogni 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).