Por que esse loop de shell simples fica parado e começa a consumir grandes quantidades de memória?

2

Um amigo meu conhecido pelo tratamento desumano de máquinas queria enfatizar sua CPU, e assim escreveu um one-liner como este:

for z in {1..100000000};do num1=$(($z * $z)) && echo $num1;done

Quando executado, este loop apenas fica sem saída e uma rápida olhada top mostra a festa consumindo grandes quantidades de memória ( gigabytes depois de alguns minutos).

Conforme escrito, eu esperaria que este processo fosse executado sequencialmente - como em z variável, calcule-o, ecoe o resultado, repita.

Em vez disso, tentar isso com limites superiores menores faz com que pareça que tudo é calculado na frente e, em seguida, despejado na tela em massa . Como em, ele se senta por um momento fazendo os cálculos, então faz o echo tudo de uma vez.

Por que esse loop se comporta dessa maneira?

Mikey T.K.
fonte

Respostas:

4

Como descrito Aqui , o operador de intervalo cria o intervalo (cria uma matriz de inteiros) antes de permitir que você faça coisas como iterar sobre ele. Você pode estar melhor com um loop while:

 z=1 ; while [[ $z -le 100000000 ]] ; do num1=$(($z * $z)) && echo $num1 ; z=$(($z + 1)) ; done

(Embora seja improvável que isso realmente force a CPU, pois o eco causa algum alívio. Meu próprio sistema atinge apenas cerca de 30% de utilização ao executar isso.)

Ouroborus
fonte